在阅读了NDK文档和我在OpenGLES上的所有书籍后,我碰壁了。我正试图将我的iOS OpenGLES设置复制到Android NDK R7及以上版本,主要是为了获得我之前在编码时忽略的深度缓冲区。
问题是,当我启用如下所示的颜色缓冲区时,我会丢失一些对象上的纹理,而当我将对象发送到背景中时,深度缓冲区不起作用。
我使用OGLES 1.1 FFP和NDK R7或以上
这是我的初始化代码:-
int32_t ES1Renderer::initRenderer() {
EGLint lFormat, lNumConfigs, lErrorResult;
EGLConfig lConfig;
const EGLint lAttributes[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL_BLUE_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_RED_SIZE, 5,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (mDisplay == EGL_NO_DISPLAY) goto ERROR;
if (!eglInitialize(mDisplay, NULL, NULL)) goto ERROR;
if(!eglChooseConfig(mDisplay, lAttributes, &lConfig, 1,
&lNumConfigs) || (lNumConfigs <= 0)) goto ERROR;
if (!eglGetConfigAttrib(mDisplay, lConfig,
EGL_NATIVE_VISUAL_ID, &lFormat)) goto ERROR;
ANativeWindow_setBuffersGeometry(mApplication->window, 0, 0,
lFormat);
mSurface = eglCreateWindowSurface(mDisplay, lConfig,
mApplication->window, NULL);
if (mSurface == EGL_NO_SURFACE) goto ERROR;
mContext = eglCreateContext(mDisplay, lConfig, EGL_NO_CONTEXT,
NULL);
if (mContext == EGL_NO_CONTEXT) goto ERROR;
if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)
|| !eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth)
|| !eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight)
|| (mWidth <= 0) || (mHeight <= 0)) goto ERROR;
//Get the default FrameBuffer and bind it
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mHeight);
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, mWidth, mHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
{
const GLfloat matAmbient[] = {1.0, 1.0, 1.0, 1.0};
const GLfloat matDiffuse[] = {1.0, 1.0, 1.0, 1.0};
const GLfloat lightShininess = 20.0;
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, lightShininess);
}
glViewport( 0, 0, mWidth, mHeight );
glEnable ( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glDepthMask( GL_TRUE );
glEnable ( GL_CULL_FACE );
glShadeModel( GL_SMOOTH );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_GENERATE_MIPMAP_HINT , GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT , GL_NICEST );
glHint( GL_POINT_SMOOTH_HINT , GL_NICEST );
glHint( GL_FOG_HINT , GL_NICEST );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glMatrixMode(GL_PROJECTION);
glOrthof(-1.0, //LEFT
1.0, //RIGHT
-1.0 * mHeight / mWidth, //BOTTOM
1.0 * mHeight / mWidth, //TOP
-2.0, //NEAR
100.0); //FAR
glMatrixMode(GL_MODELVIEW);
}
这是我的渲染代码:
int32_t ES1Renderer::render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
RENDERING GOES HERE THE REMOVED FOR EXAMPLE
*/
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
if (eglSwapBuffers(mDisplay, mSurface) != EGL_TRUE) {
return 0;
}
return 1;
}
在安卓NDK 7上的OGLES设置中,Sylvain Ratabouil(如果你想在NDK7上跟上进度,请查看他的书和页面)的指针后确定。我不需要生成和绑定缓冲区,因为它们是在设置EGL曲面时自动处理的。他建议添加以下内容:-
EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
至
const EGLint lAttributes[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL_BLUE_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_RED_SIZE, 5,
EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE };
这修复了我的深度缓冲区,请注意检查EGL状态,确保它得到支持。以下是我使用的完整设置实现:-
int32_t ES1Renderer::initialiseRenderer() {
EGLint lFormat, lNumConfigs, lErrorResult;
EGLConfig lConfig;
const EGLint lAttributes[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL_BLUE_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_RED_SIZE, 5,
EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE };
mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (mDisplay == EGL_NO_DISPLAY)
goto ERROR;
if (!eglInitialize(mDisplay, NULL, NULL))
goto ERROR;
if (!eglChooseConfig(mDisplay, lAttributes, &lConfig, 1, &lNumConfigs)
|| (lNumConfigs <= 0))
goto ERROR;
if (!eglGetConfigAttrib(mDisplay, lConfig, EGL_NATIVE_VISUAL_ID, &lFormat))
goto ERROR;
ANativeWindow_setBuffersGeometry(mApplication->window, 0, 0, lFormat);
mSurface = eglCreateWindowSurface(mDisplay, lConfig, mApplication->window,
NULL);
if (mSurface == EGL_NO_SURFACE)
goto ERROR;
mContext = eglCreateContext(mDisplay, lConfig, EGL_NO_CONTEXT, NULL);
if (mContext == EGL_NO_CONTEXT)
goto ERROR;
if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)
|| !eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth)
|| !eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight)
|| (mWidth <= 0) || (mHeight <= 0))
goto ERROR;
{
const GLfloat matAmbient[] = { 1.0, 1.0, 1.0, 1.0 };
const GLfloat matDiffuse[] = { 1.0, 1.0, 1.0, 1.0 };
const GLfloat lightShininess = 20.0;
glEnable( GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, lightShininess);
}
glLoadIdentity();
#ifdef ORTHOGANAL_PROJECTION
glViewport( 0, 0, mWidth, mHeight );
#endif
glEnable ( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glDepthMask( GL_TRUE );
glEnable ( GL_CULL_FACE );
//glShadeModel( GL_SMOOTH );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_GENERATE_MIPMAP_HINT , GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT , GL_NICEST );
glHint( GL_POINT_SMOOTH_HINT , GL_NICEST );
glHint( GL_FOG_HINT , GL_NICEST );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glMatrixMode(GL_PROJECTION);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
//glShadeModel(GL_FLAT);
#ifdef ORTHOGANAL_PROJECTION
glOrthof(-1.0, //LEFT
1.0, //RIGHT
-1.0 * mHeight / mWidth, //BOTTOM
1.0 * mHeight / mWidth, //TOP
-2.0, //NEAR
100.0); //FAR
#else
{
GLfloat mWidthf = mWidth;
GLfloat mHeightf = mHeight;
const GLfloat zNear = 0.1;
const GLfloat zFar = 1000.0;
const GLfloat fieldOfView = 60.0;
GLfloat size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
glFrustumf(-size, size, -size / (mWidthf / mHeightf),
size / (mWidthf / mHeightf), zNear, zFar);
glViewport(0, 0, mWidthf, mHeightf);
}
#endif
glMatrixMode(GL_MODELVIEW);
}
渲染代码与上面相同。