【问题标题】:Useage of Textures collides with drawing Triangles, Only one is displayed纹理的使用与绘制三角形冲突,只显示一个
【发布时间】:2020-11-21 04:53:12
【问题描述】:

我目前正在学习 OpenGL(使用 Java / Android),到目前为止,所有问题都可以使用名为 stackoverflow 或 google 的网站来解决(你可能都知道)。

到目前为止,我只使用类似的东西绘制三角形(带索引的顶点)。

    // some math here to calculate vertices and indices
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    gl.glVertexPointer(COORDS_PER_VERTEX, GL10.GL_FLOAT, vertex_stride, vertex_buffer);
    gl.glColor4f(color.r, color.g, color.b, color.a);
    gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, index_buffer_size, GL10.GL_UNSIGNED_SHORT, index_buffer);

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

vertex_buffer 保存 verices,index_buffer 保存索引。 这行得通,我可以画矩形、圆形、箭头和其他简单的形状

现在我想添加一个纹理。我确实遵循了这个:https://examples.javacodegeeks.com/android/games/opengl-es/opengl-es-texture-mapping/

它本身也有效:

    // once: bitmap to texture conversion
    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
    // do some math for the verices and the mapping

    // always: drawing
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    gl.glVertexPointer(COORDS_PER_VERTEX, GL10.GL_FLOAT, vertex_stride, vertex_buffer);
    gl.glTexCoordPointer(COORDS_PER_TEXTURE_COORD, GL10.GL_FLOAT, 0, texture_buffer);
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, NUM_VERTICES);

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

textures[0] 保存指向纹理的指针,vertex_buffer 又是顶点,texture_buffer 是纹理到顶点的映射, 位图持有位图。

现在,如果我同时使用两者,我发现 openGL 只绘制纹理。不显示所有简单形状。如果我将应用程序放在后台而不是再次放在前台,突然所有 简单形状 都会显示,但纹理会变成填充随机颜色的矩形(可能是我最后绘制的颜色 简单的形状与)。 如果我先绘制简单形状然后再绘制纹理,结果不会改变,反之亦然。

我猜只能打电话 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 对于简单的形状,而不是gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 的纹理以某种方式发生冲突。

有没有办法将两者用于同一个“框架”?

也许我需要在渲染类中的 openGL 中配置一些东西?

class OpenGLRenderer implements GLSurfaceView.Renderer {

    public OpenGLRenderer(Context c, int screen_width_px, int screen_height_px){
        context = c;
        this.screen_width_px = screen_width_px;
        this.screen_height_px = screen_height_px;
    }


    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig egl_config){
        gl10.glEnable(GL10.GL_TEXTURE_2D);
        gl10.glShadeModel(GL10.GL_SMOOTH);

        gl10.glClearColor(0.5f, 0.5f, 0.0f, 0.5f);
        gl10.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
        gl10.glEnable(GL10.GL_DEPTH_TEST);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height){
        screen_height_px = height;
        screen_width_px = width;

        GLES20.glViewport(0,0,width,height);
        float ratio  = (float) width / (float) height;
        gl10.glMatrixMode(GL10.GL_PROJECTION);
        gl10.glLoadIdentity();

        float near = 1.0f;
        float far = -zoom+1;
        float bottom = -1.0f;
        float top = 1.0f;
        float left = -ratio;
        float right = ratio;
        gl10.glFrustumf(left , right , bottom, top, near, far);
    }

    @Override
    public void onDrawFrame(GL10 gl10){

        prepareFrame(gl10);

        // HERE I would call all simple_shapes and Textures in two for loops
    }

    void prepareFrame(GL10 gl10){
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        gl10.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl10.glMatrixMode(GL10.GL_MODELVIEW);
        gl10.glLoadIdentity();
        gl10.glTranslatef(0.0f, 0.0f, zoom);
        gl10.glEnable(GL10.GL_BLEND);
        gl10.glEnable(GL10.GL_TEXTURE_2D);
        gl10.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
    }  
}

我认为这就是所有相关代码。我不知道是否适合在此处发布(Github)项目的链接,但如果需要,我也可以创建一个分支并链接它。


问题已解决:简而言之,我需要在绘制纹理之前启用 2DTexture gl10.glEnable(GL10.GL_TEXTURE_2D),然后在之后禁用它 gl10.glDisable(GL10.GL_TEXTURE_2D)。 (我刚刚启用它。)有关详细答案,请参阅接受的答案。

将应用程序移入后台并返回前台后,纹理消失的问题无关紧要。通过调用下面的部分//一次:位图到纹理转换(参见第二个代码示例)再次解决了它。我猜纹理 behnd textures[0] 指针通过将应用移到后台被删除。

【问题讨论】:

    标签: java android opengl-es textures


    【解决方案1】:

    OpenGL 是一个状态引擎。一旦设置了一个状态,它就会一直保持下去,直到它再次被改变。在Legacy OpenGL,二维纹理必须由gl10.glEnable(GL10.GL_TEXTURE_2D); 启用。一旦设置了这个状态,它就会被保留。如果启用了 2 维纹理且未提供纹理坐标,则网格的所有纹理坐标属性必须为默认值 (0, 0),并且当前绑定纹理在此坐标处的纹素被包裹在整个网格上。

    在使用纹理绘制几何之前,您必须启用二维纹理:

    gl10.glEnable(GL10.GL_TEXTURE_2D);
    // draw mesh with texture
    

    在绘制没有纹理的几何图形之前,您必须禁用二维纹理:

    gl10.glDisable(GL10.GL_TEXTURE_2D);
    // draw mesh with color
    

    【讨论】:

    • 非常感谢,这就是问题所在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多