您好我最近在Android ndk上玩过OpenGL ES 1.1,我有点遇到问题。发生的事情是,我在屏幕上渲染一个简单的红色方块,当我启动应用程序时,方块显示完美,但当我点击主页按钮并返回应用程序时,方块不再显示。我在调用getError
后尝试调用glDrawArrays
来查看是否发生了错误,并且始终返回GL_NO_ERROR
。我在android网站上读到了以下内容:
在某些情况下,EGL渲染上下文将会丢失。 这通常发生在设备进入睡眠状态后唤醒时。什么时候 EGL上下文丢失,所有OpenGL资源(如纹理)都是如此 与该上下文相关联将被自动删除。在 为了保持正确渲染,渲染器必须重新创建任何丢失 它仍然需要的资源。 onSurfaceCreated(GL10,EGLConfig) 方法是一个方便的地方。
我所做的是在活动的每个阶段打印日志cat,当点击主页按钮并返回应用程序时,系统没有调用onSurfaceCreated
。我也尝试在log cat中打印我的顶点,只是为了检查它们是否会被破坏而我只是向glVertexPointer
发送了错误的值,但它看起来还不错。这是代码:
static jint initialize(JNIEnv* env, jobject obj, jint width, jint height){
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glOrthof(0, width, height, 0, -1, 1);
glClearColor(100.0f/255.0, 149.0f/255.0f, 237.0/255.0f, 1.0f);
}
struct Vertex {
float Position[2];
float Texture[4];
};
static void gameRun(JNIEnv* evn, jobject obj) {
glClear(GL_COLOR_BUFFER_BIT);
const Vertex Vertices[] = {
{{ 0.0f, 100.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }},
{{ 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }},
{{ 100.0f, 100.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }},
{{ 100.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }},
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &Vertices[0].Position[0]);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), &Vertices[0].Texture[0]);
GLsizei vertexCount = sizeof(Vertices) / sizeof(Vertex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
注意:函数initialize
来自onSurfaceCreated
,gameRun
来自onDrawFrame
。
有一件事让我感到奇怪的是,在主页按钮后再次在我的手机上运行应用程序时,系统会调用函数onSurfaceChanged
两次。不确定它是否与任何事情有关,只是奇怪。
如果有人能帮助我,我会非常感激:D
答案 0 :(得分:1)
好的,所以在做了一些测试并与一些示例项目进行比较之后,我注意到了一些东西。在调用glOrthof的一个项目中,我将传递左右宽度和高度之间的比率,并且我将传递-1和1作为顶部和底部:
float ratio = width / height;
glOrthof(-ratio, ratio, -1, 1, -1, 1);
当我点击主页按钮然后再次运行应用程序时,我注意到该正方形会缩放。
在另一个项目中我只想创建一个投影矩阵,然后我会在我的gameRun函数上用glLoadMatrix设置它:
mat4 projection = mat4::Frustum(-2, 2, -h / 2, h / 2, 5, 10);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(projection.Pointer());
当我点击主页按钮然后再次运行应用程序时,我看到这次正方形会出现没问题。然后我开始阅读OpenGL ES 1.1的文档,发现了以下内容:
glOrtho描述了一个产生并行的转换 投影。 将当前矩阵(请参阅glMatrixMode)乘以 这个矩阵和结果取代了当前的矩阵......
它突然袭击了我......因为从home中断回来后,我的应用程序正在使用之前创建的上下文。所以它实际上发生的是当我这次调用glOrthof
时,这些值乘以我的应用程序被中断之前设置的值。这会导致我的Ortho以平方因子放大。使我的100 x 100平方渲染真的非常小。为了解决此问题,我只需在调用glLoadIndentity
之前添加glOrthof
:
static jint initialize(JNIEnv* env, jobject obj, jint width, jint height){
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, width, height, 0, -1, 1);
glClearColor(100.0f/255.0, 149.0f/255.0f, 237.0/255.0f, 1.0f);
}
这是有效的,因为glLoadIdentity
使用单位矩阵替换之前的值:
glLoadIdentity 用身份矩阵替换当前矩阵。 它在语义上等同于调用glLoadMatrix 单位矩阵
(1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1)
从而解决问题!! :d