Android OpenGL ES...为什么教程总是正确渲染,而我的版本却随机不正确?

发布于 2024-10-25 05:19:28 字数 4460 浏览 8 评论 0原文

我正在遵循 insanitydesign.com 上找到的教程集,这是一个NeHe OpenGL 教程的 Android 端口。我在理解为什么教程版本似乎始终正确渲染而我的修改版本随机渲染完全错误时遇到了很多问题。有时,当程序加载时,问题会立即显现出来,但有时我必须在它出现之前旋转屏幕。您可以下载一个包含屏幕截图的 zip 文件,其中我从 filedropper 将屏幕旋转了 12 次。正如您所看到的,三角形通常会渲染,但有时会显得完全扭曲和弄脏。 如果您好奇的话,这里是我的整个 Eclipse 项目的链接

我怀疑问题出在我的 Shape.draw() 方法中,但我不能确定。

我相信,这是相关代码:

GLRenderer.java

    private Shape shape;

public GLRenderer(){
    Log.i(this.toString(),"ctor");
    shape = Shape.makeTriangle();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    speedPerSecond = SystemClock.uptimeMillis();
    Log.d(this.toString(), ".onSurfaceCreated");

    gl.glShadeModel(GL10.GL_SMOOTH);            



    gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f);


    gl.glClearDepthf(1.0f);                     //Depth Buffer Setup



    gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
    gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

    //Really Nice Perspective Calculations
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 

}

@Override
public void onDrawFrame(GL10 gl) {

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();

    shape.setX(0.0f);
    shape.setY(0.0f);
    shape.setZ(-6.0f);
    shape.draw(gl);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0){
        height = 1;
    }
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();


    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 50.0f);


    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();


}

Shape.java 包 com.smashing.test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.util.Log;

public class Shape implements IGLShape {

    public float getX(){
        return x;
    }

    public float getY(){
        return y;
    }

    public float getZ(){
        return z;
    }

    public void setX(float pX){
        x = pX;
    }

    public void setY(float pY){
        y = pY;
    }

    public void setZ(float pZ){
        z = pZ;
    }



    public static Shape makeTriangle(){
        Shape s = new Shape();
                /*
                 *  Is this correct?  I want to create a right triangle on screen like this
                 *  |\
                 *  | \
                 *  |  \
                 *  |   \
                 *  |____\  though with a 90/45/45 degree spread rather than this poor representation.
                 */
        float v[] = {
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f
        };
        s.setVertices(v);
        return s;
    }

    public static Shape makeShapeFromVertices(float pVerts[]){
        Shape s = new Shape();
        s.setVertices(pVerts);
        return s;   
    }


    private float x = 0.0f;
    private float y = 0.0f;
    private float z = 0.0f;
    private float[] mVertices;
    private FloatBuffer mVertexBuffer;






    public void setVertices(float pVerts[]){
        mVertices = pVerts;
        ByteBuffer bb = ByteBuffer.allocateDirect(mVertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        mVertexBuffer = bb.asFloatBuffer();
        mVertexBuffer.put(mVertices);
        mVertexBuffer.position(0);
    }

    public float[] getVertices(){
        return mVertices;
    }

    private Shape(){

    }


    @Override
    public void draw(GL10 gl) {


        /*
         * I believe the problem is here... but I don't understand how or why?
         */
        gl.glTranslatef(x, y, z);
        gl.glFrontFace(GL10.GL_CW);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVertices.length);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glTranslatef(-x, -y, -z);

    }



}

编辑:我知道该教程与我的版本略有不同。我正在尝试从中推断和实验......我只是对这些差异感到非常惊讶和震惊,并且想知道它们为什么存在,以及如何避免我在渲染中发现的这种令人不快的结果方案。

I'm following the tutorial set found at insanitydesign.com, which is an Android port of the NeHe tutorials on OpenGL. I'm having a lot of problems understanding why the tutorial version appears to render correctly at all times while my modified version randomly renders completely incorrectly. Occasionally, the problem is evident immediately when the program loads, but sometimes I have to rotate the screen before it appears. You can download a zip file containing screengrabs where I've rotated the screen 12 times from filedropper. As you can see, the triangle usually renders but on occasion appears completely distorted and smudged. Here is a link to my entire Eclipse project if you're curious.

I suspect the problem is in my Shape.draw() method, but I can't know for sure.

This is, I believe, the relevant code:

GLRenderer.java

    private Shape shape;

public GLRenderer(){
    Log.i(this.toString(),"ctor");
    shape = Shape.makeTriangle();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    speedPerSecond = SystemClock.uptimeMillis();
    Log.d(this.toString(), ".onSurfaceCreated");

    gl.glShadeModel(GL10.GL_SMOOTH);            



    gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f);


    gl.glClearDepthf(1.0f);                     //Depth Buffer Setup



    gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
    gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

    //Really Nice Perspective Calculations
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 

}

@Override
public void onDrawFrame(GL10 gl) {

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();

    shape.setX(0.0f);
    shape.setY(0.0f);
    shape.setZ(-6.0f);
    shape.draw(gl);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0){
        height = 1;
    }
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();


    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 50.0f);


    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();


}

Shape.java
package com.smashing.test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.util.Log;

public class Shape implements IGLShape {

    public float getX(){
        return x;
    }

    public float getY(){
        return y;
    }

    public float getZ(){
        return z;
    }

    public void setX(float pX){
        x = pX;
    }

    public void setY(float pY){
        y = pY;
    }

    public void setZ(float pZ){
        z = pZ;
    }



    public static Shape makeTriangle(){
        Shape s = new Shape();
                /*
                 *  Is this correct?  I want to create a right triangle on screen like this
                 *  |\
                 *  | \
                 *  |  \
                 *  |   \
                 *  |____\  though with a 90/45/45 degree spread rather than this poor representation.
                 */
        float v[] = {
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f
        };
        s.setVertices(v);
        return s;
    }

    public static Shape makeShapeFromVertices(float pVerts[]){
        Shape s = new Shape();
        s.setVertices(pVerts);
        return s;   
    }


    private float x = 0.0f;
    private float y = 0.0f;
    private float z = 0.0f;
    private float[] mVertices;
    private FloatBuffer mVertexBuffer;






    public void setVertices(float pVerts[]){
        mVertices = pVerts;
        ByteBuffer bb = ByteBuffer.allocateDirect(mVertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        mVertexBuffer = bb.asFloatBuffer();
        mVertexBuffer.put(mVertices);
        mVertexBuffer.position(0);
    }

    public float[] getVertices(){
        return mVertices;
    }

    private Shape(){

    }


    @Override
    public void draw(GL10 gl) {


        /*
         * I believe the problem is here... but I don't understand how or why?
         */
        gl.glTranslatef(x, y, z);
        gl.glFrontFace(GL10.GL_CW);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVertices.length);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glTranslatef(-x, -y, -z);

    }



}

EDIT: I am aware that the tutorial is a little different than my version. I'm attempting to extrapolate from it and experiment... I'm just completely surprised and astounded at the differences and would like to know why they exist, and how I can avoid such an unpleasant outcome as I've found with my rendering scheme.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

第七度阳光i 2024-11-01 05:19:28

你应该替换

glDrawArrays(GL10.GL_TRIANGLE_STRIP, ...)

glDrawArrays(GL10.GL_TRIANGLES, ...)

我认为当你绘制一个简单的三角形而不是四边形时,这就是问题的原因。

问候

you should replace

glDrawArrays(GL10.GL_TRIANGLE_STRIP, ...)

with

glDrawArrays(GL10.GL_TRIANGLES, ...)

I think that as you're drawing a simple triangle and not a quad, that is the cause of the trouble.

Regards

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文