简体   繁体   English

Android NDK中的OpenGL ES 2.0:没有被绘制

[英]OpenGL ES 2.0 in Android NDK: Nothing being drawn

I have a 2D game project that I'm porting to Android that utilizes OpenGL ES 2.0. 我有一个2D游戏项目,我正在移植到使用OpenGL ES 2.0的Android。 I am having trouble getting anything drawn on the screen (except for a solid color from clearing the screen). 我无法在屏幕上绘制任何内容(除了清除屏幕的纯色)。 Everything renders just fine when running in my Windows environment, but of course the environment is set up differently for the different version of OpenGL. 在我的Windows环境中运行时,一切都呈现得很好,但当然不同版本的OpenGL环境设置也不同。

I followed the native-activity sample and took advice from several other OpenGL ES 2.0 resources to compose what I currently have. 我按照本机活动样本,从其他几个OpenGL ES 2.0资源中获取建议,以构建我目前拥有的内容。

I have checked everything I know how to with no anomalous results. 我已经检查了所有我知道如何没有异常结果。 As mentioned, glClear works, and displays the color set by glClearColor . 如上所述, glClear可以工作,并显示glClearColor设置的颜色。 I also know that every frame is being rendered, as changing glClearColor frame-by-frame displays the different colors. 我也知道每个帧都在渲染,因为逐帧更改glClearColor会显示不同的颜色。 Of course, the application properly compiles. 当然,应用程序正确编译。 My textures are loaded from the proper location in the app's cache. 我的纹理从应用程序缓存中的正确位置加载。 glGetError is returning GL_NO_ERROR at every step in the process, so what I am doing appears to be accepted by OpenGL. glGetError在进程的每一步都返回GL_NO_ERROR ,因此我正在做的事情似乎被OpenGL接受。 My shaders are loaded without error. 我的着色器加载没有错误。 I have also tested this on both a few emulators and my physical android device, so it isn't localized to a specific device configuration. 我还在一些模拟器和我的物理android设备上测试了这个,所以它没有本地化到特定的设备配置。

I speculate that it must be some mistake in how I initialize and set up OpenGL. 我推测在初始化和设置OpenGL时一定是个错误。 I am hoping someone more versed in OpenGL ES than I am will be able to help root out my problem. 我希望有更多精通OpenGL ES的人能够帮助解决我的问题。 I am pasting the different relevant sections of my code below. 我正在粘贴下面代码的不同相关部分。 engine is a global struct I am presently using out of laziness. engine是一个全局结构,我目前正在使用懒惰。

Initializing the display 初始化显示

static int AND_InitDisplay() {

    // Desired display attributes
    const EGLint attribs[] = {
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL_BLUE_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_DEPTH_SIZE, 16,
            EGL_NONE
    };
    EGLint w, h, dummy, format;
    EGLint numConfigs;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(display, 0, 0);
    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);

    ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);

    surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);

    EGLint const attrib_list[3] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
    context = eglCreateContext(display, config, NULL, attrib_list);

    if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
        LOGW("Unable to eglMakeCurrent");
        return -1;
    }

    eglQuerySurface(display, surface, EGL_WIDTH, &w);
    eglQuerySurface(display, surface, EGL_HEIGHT, &h);

    engine->display = display;
    engine->context = context;
    engine->surface = surface;
    engine->width = w;
    engine->height = h;

    // Initialize GL state.
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return 0;
}

Drawing a frame 画一个框架

static void AND_drawFrame() {
    if (engine->display == NULL) {
        LOGW("DB E: DISPLAY IS NULL");
        // No display.
        return;
    }

    // Clearing with red color. This displays properly.
    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // eglSwapBuffers results in no visible change
    eglSwapBuffers(engine->display, engine->surface);
}

Example of preparing VBO data 准备VBO数据的示例

I understand many wouldn't like the idea of using multiple VBOs for the same geometry. 我知道很多人不喜欢将多个VBO用于相同的几何体。 I would love to hear if this code isn't orthodox or is incorrect, but I am not focused on this unless it the root of my problem. 我很想知道这段代码是不是正统的还是不正确的,但除非它是我问题的根源,否则我不会专注于此。

GLfloat charPosVerts[] = {

    p0.x, p0.y, 0.f,
    p1.x, p0.y, 0.f,
    p1.x, p1.y, 0.f,

    p0.x, p0.y, 0.f,
    p1.x, p1.y, 0.f,
    p0.x, p1.y, 0.f
};

GLfloat charTexVerts[] = {
    0.0, 0.0,
    textures[texid].w, 0.0,
    textures[texid].w, textures[texid].h,

    0.0, 0.0,
    textures[texid].w, textures[texid].h,
    0.0, textures[texid].h
};

GLfloat charColorVerts[] = {
    e->color.r, e->color.g, e->color.b, e->color.a,
    e->color.r, e->color.g, e->color.b, e->color.a,
    e->color.r, e->color.g, e->color.b, e->color.a,

    e->color.r, e->color.g, e->color.b, e->color.a,
    e->color.r, e->color.g, e->color.b, e->color.a,
    e->color.r, e->color.g, e->color.b, e->color.a
};

glGenBuffers(1, &(e->vboPos));
glGenBuffers(1, &(e->vboTex));
glGenBuffers(1, &(e->vboColor));

glBindBuffer(GL_ARRAY_BUFFER, e->vboPos);
glBufferData(GL_ARRAY_BUFFER, sizeof(charPosVerts), charPosVerts, GL_DYNAMIC_DRAW);
glVertexAttribPointer(shaderIDs.attribPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(shaderIDs.attribPosition);

glBindBuffer(GL_ARRAY_BUFFER, e->vboTex);
glBufferData(GL_ARRAY_BUFFER, sizeof(charTexVerts), charTexVerts, GL_DYNAMIC_DRAW);
glVertexAttribPointer(shaderIDs.attribTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(shaderIDs.attribTexCoord);

glBindBuffer(GL_ARRAY_BUFFER, e->vboColor);
glBufferData(GL_ARRAY_BUFFER, sizeof(charColorVerts), charColorVerts, GL_DYNAMIC_DRAW);
glVertexAttribPointer(shaderIDs.attribColors, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(shaderIDs.attribColors);

Example of drawing VBO 绘制VBO的示例

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, CORE_GetBmpOpenGLTex(texix));
glUniform1i(shaderIDs.uniTexture, 0);

// Draw the sprite
glBindBuffer(GL_ARRAY_BUFFER, e->vboPos);
glVertexAttribPointer(shaderIDs.attribPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(shaderIDs.attribPosition);

glBindBuffer(GL_ARRAY_BUFFER, e->vboTex);
glVertexAttribPointer(shaderIDs.attribTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(shaderIDs.attribTexCoord);

glBindBuffer(GL_ARRAY_BUFFER, e->vboColor);
glVertexAttribPointer(shaderIDs.attribColors, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(shaderIDs.attribColors);

glDrawArrays(GL_TRIANGLES, 0, 18);

Vertex Shader 顶点着色器

The shaders are very simple. 着色器非常简单。

attribute vec3 position;
attribute vec2 texCoord;
attribute vec4 colors;

varying vec2 texCoordVar;
varying vec4 colorsVar;

void main() {
    gl_Position = vec4(position, 1.0);
    texCoordVar = texCoord;
    colorsVar = colors;
}

Fragment Shader 片段着色器

uniform sampler2D texture;

varying vec2 texCoordVar;
varying vec4 colorsVar;

void main()
{
    gl_FragColor = texture2D(texture, texCoordVar) * colorsVar;
}

Thanks for looking at this long post. 感谢您查看这篇长篇文章。 Help is very much appreciated. 非常感谢帮助。

The posted code is not drawing anything. 发布的代码没有绘制任何内容。 From the AND_drawFrame() function: AND_drawFrame()函数:

// Clearing with red color. This displays properly.
glClearColor(1.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// eglSwapBuffers results in no visible change
eglSwapBuffers(engine->display, engine->surface);

Based on this, the draw code is either never invoked, or the window is cleared after drawing, which would wipe out everything that was drawn before. 基于此,绘图代码要么永远不会被调用,要么绘制清除窗口,这将消除之前绘制的所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM