纹理的使用与绘制三角形冲突,只显示一个
Useage of Textures collides with drawing Triangles, Only one is displayed
我目前正在学习 OpenGL(使用 Java / Android),到目前为止,所有问题都可以使用名为 Whosebug 或 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 保存顶点,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);
的纹理不知何故发生冲突。
有没有办法将两者用于同一个“框架”?
也许我需要在 Render 中的 openGL 中配置一些东西 class?
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);
}
}
我认为这是所有相关代码。我不知道它是否适用于 post 一个 link 到这里的 (Github) 项目但是如果需要我可以创建一个分支并且 link 也可以。
问题已解决:简而言之,我需要在绘制纹理之前启用 2DTexture gl10.glEnable(GL10.GL_TEXTURE_2D)
,然后禁用它 gl10.glDisable(GL10.GL_TEXTURE_2D)
。 (我刚刚启用它。)有关详细答案,请参阅已接受的答案。
将应用程序移到后台并返回前台后,纹理消失的问题与此无关。通过调用下面的部分 // 一次解决了这个问题:位图到纹理的转换(参见第二个代码示例)。我猜纹理 behnd textures[0] 指针通过将应用程序移动到后台被删除。
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
我目前正在学习 OpenGL(使用 Java / Android),到目前为止,所有问题都可以使用名为 Whosebug 或 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 保存顶点,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);
的纹理不知何故发生冲突。
有没有办法将两者用于同一个“框架”?
也许我需要在 Render 中的 openGL 中配置一些东西 class?
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);
}
}
我认为这是所有相关代码。我不知道它是否适用于 post 一个 link 到这里的 (Github) 项目但是如果需要我可以创建一个分支并且 link 也可以。
问题已解决:简而言之,我需要在绘制纹理之前启用 2DTexture gl10.glEnable(GL10.GL_TEXTURE_2D)
,然后禁用它 gl10.glDisable(GL10.GL_TEXTURE_2D)
。 (我刚刚启用它。)有关详细答案,请参阅已接受的答案。
将应用程序移到后台并返回前台后,纹理消失的问题与此无关。通过调用下面的部分 // 一次解决了这个问题:位图到纹理的转换(参见第二个代码示例)。我猜纹理 behnd textures[0] 指针通过将应用程序移动到后台被删除。
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