OpenGL到GL ES 2.0端口:渲染时出现问题

时间:2014-11-27 11:35:47

标签: ios opengl opengl-es 3d

我是OpenGL的新手,并且正在移植现有的应用程序以使其在iOS中运行。现有的OpenGL代码如下:

glGenTextures(1, (GLuint*)&_colorTexID);
glGenTextures(1, (GLuint*)&_depthTexID);
glBindTexture(GL_TEXTURE_2D, _colorTexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, colorFormat, colorType, getColorBuffer(_HRenderTarget));
glBindTexture(GL_TEXTURE_2D, _depthTexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, depthFormat, depthType, getDepthBuffer(_HRenderTarget));
GLint mode[2];
GLboolean stencilMode;
GLboolean depthTestEnabled;
glGetIntegerv(GL_POLYGON_MODE, mode);
glGetBooleanv(GL_STENCIL_TEST, &stencilMode);
glGetBooleanv(GL_DEPTH_TEST, &depthTestEnabled);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glCullFace(GL_BACK);
glDisable(GL_STENCIL_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _colorTexID);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _depthTexID);
glActiveTexture(GL_TEXTURE0);
glUseProgram(getGLProgramObject());
if (_depthTest)
{
   glEnable(GL_DEPTH_TEST);
   glDepthFunc(GL_LEQUAL);
}
else
{
    glDisable(GL_DEPTH_TEST);
}
glEnable(GL_ALPHA_TEST);
glVertexAttrib4f(glGetAttribLocation(getGLProgramObject(), "color"), 1.f, 1.f, 1.f, _alpha);        
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-1, -1);
glTexCoord2f(1, 0); glVertex2f(1, -1);
glTexCoord2f(1, 1); glVertex2f(1, 1);
glTexCoord2f(0, 1); glVertex2f(-1, 1);
glEnd(); 
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glUseProgram(0);
// Restore states
glPolygonMode(GL_FRONT, mode[0]);
glPolygonMode(GL_BACK, mode[1]);
if (stencilMode) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
if (depthTestEnabled) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);

我的GL ES更改只是替换立即模式四重渲染

glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-1, -1);
glTexCoord2f(1, 0); glVertex2f(1, -1);
glTexCoord2f(1, 1); glVertex2f(1, 1);
glTexCoord2f(0, 1); glVertex2f(-1, 1);
glEnd();

使用:

GLshort vtx1[] = {-1,-1,    1,-1,   1,1,    -1,1    };
GLshort tex1[] = {  0,0,    1,0,    1,1,    0,1,    };
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_SHORT, 0, &vtx1[0]);
glTexCoordPointer(2, GL_SHORT, 0, &tex1[0]);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

GL_RGBA8 GL_RGBA8_OESGL_R32F GL_R32F_EXT,而不使用glPolygonMode,因为它不受支持。但似乎我错过了一些东西。它不会渲染和崩溃,从而导致错误GPU对硬件重启感到内疚。

我的着色器代码:

        const GLcharARB* _udFragmentShader =
        "                                                                          \n" \
        "   uniform sampler2D udTexture;                                           \n" \
        "   uniform sampler2D udDepth;                                             \n" \
        "   void main (void)                                                       \n" \
        "   {                                                                      \n" \
        "     vec4 frag = texture2D(udTexture,gl_TexCoord[0].st);                  \n" \
        "     if(frag.a < 0.5) discard;                                            \n" \
        "     gl_FragColor = frag * gl_Color;                                      \n" \
        "     gl_FragDepth = (texture2D(udDepth,gl_TexCoord[0].st).r * 0.5) + 0.5; \n" \
        "   }                                                                      \n" \
        "                                                                          \n" \
        "";


    const GLcharARB* _udVertexShader =
        "                                                                          \n" \
        "   attribute vec4 color;                                                  \n" \
        "   void main(void)                                                        \n" \
        "   {                                                                      \n" \
        "     gl_Position = gl_Vertex;                                             \n" \
        "     gl_FrontColor = color;                                               \n" \
        "     gl_TexCoord[0]  = gl_MultiTexCoord0;                                 \n" \
        "   }                                                                      \n" \
        "                                                                          \n" \
        "";

1 个答案:

答案 0 :(得分:1)

您正在尝试使用OpenGL ES 1.x和ES 2.0的混合体。 ES 2.0 不是ES 1.x的扩展。 ES 2.0是一个全新的API定义,与ES 1.x几乎没有共同之处。如果您查看官方规范文件(https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/gl.xml):

,也会确认这一点
<feature api="gles1" name="GL_VERSION_ES_CM_1_0" number="1.0">
...
<feature api="gles2" name="GL_ES_VERSION_2_0" number="2.0">
...
<feature api="gles2" name="GL_ES_VERSION_3_0" number="3.0">
...
<feature api="gles2" name="GL_ES_VERSION_3_1" number="3.1">
...

您可以看到ES 3.0和3.1被指定为gles2 API的扩展名,而ES 2.0被指定为具有gles1的新API。因此,它根本不与ES 1.x向后兼容。

这意味着您必须使用ES 1.1或ES 2.0:

  • ES 1.1非常有限。最重要的是,它不支持使用GLSL着色器的可编程管道。我现在也认为它已经过时了。
  • ES 2.0消除了所有固定功能,并且只有可编程管道。

如果你坚持使用ES 2.0(你应该使用恕我直言),你将不得不摆脱所有不再可用的电话。通过快速查看代码,其中包括:

  • GL_ALPHA_TEST:如果您真的需要,请在片段着色器中替换为discard
  • GL_QUADS原始类型:替换为GL_TRIANGLESGL_TRIANGLE_STRIP等。
  • 立即模式渲染(glBegin()等):替换为顶点数组/缓冲区和glDrawArrays()glDrawElements()
  • glEnableClientState():替换为glEnableVertexAttribArray()
  • glVertexPointer()glTexCoordPointer():替换为glVertexAttribPointer()

理想情况下,在使用ES 2.0时,应避免包含任何ES 1.x标头。这将允许您在编译时看到大多数不兼容性,因为ES 2.0中不可用的函数/枚举将不再定义,从而导致构建错误。