embedded - OpenGL ES 2.0 程序在 Mali400 平台上失败

标签 embedded opengl-es-2.0 mali

我正在使用 OpenGL ES 2.0 编写一个简单的纹理流渲染程序。该程序在桌面上运行,但在具有 Mali400 GPU 的嵌入式平台上失败。 LCD 变黑,顶部几行闪烁。我不知道我的代码有什么问题。我尝试了其他一些 OpenGL ES 2.0 程序,都没有问题,所以问题肯定出在我的代码中。任何帮助将不胜感激。谢谢。

main.c

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <sys/stat.h>

static EGLDisplay display;
static EGLSurface surface;

static void render_target_init(EGLNativeWindowType nativeWindow)
{
    assert((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) != EGL_NO_DISPLAY);

    EGLint majorVersion;
    EGLint minorVersion;
    assert(eglInitialize(display, &majorVersion, &minorVersion) == EGL_TRUE);

    EGLConfig config;
    EGLint numConfigs;
    const EGLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_DEPTH_SIZE, 24,
        EGL_NONE
    };
    assert(eglChooseConfig(display, configAttribs, &config, 1, &numConfigs) == EGL_TRUE);

    const EGLint attribList[] = {
            EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
            EGL_NONE
    };
    assert((surface = eglCreateWindowSurface(display, config, nativeWindow, attribList)) != EGL_NO_SURFACE);

    EGLContext context;
    const EGLint contextAttribs[] = {
            EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL_NONE
    };
    assert((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);

    assert(eglMakeCurrent(display, surface, surface, context) == EGL_TRUE);
}

static GLuint LoadShader(const char *name, GLenum type)
{
    FILE *f;
    int size;
    char *buff;
    GLuint shader;
    GLint compiled;
    const char *source[1];

    assert((f = fopen(name, "r")) != NULL);

    // get file size
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, 0, SEEK_SET);

    assert((buff = malloc(size)) != NULL);
    assert(fread(buff, 1, size, f) == size);
    source[0] = buff;
    fclose(f);
    shader = glCreateShader(type);
    glShaderSource(shader, 1, source, &size);
    glCompileShader(shader);
    free(buff);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    if (!compiled) {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen > 1) {
                    char *infoLog = malloc(infoLen);
                    glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
                    fprintf(stderr, "Error compiling shader %s:\n%s\n", name, infoLog);
                    free(infoLog);
            }
            glDeleteShader(shader);
            return 0;
    }

    return shader;
}

static void init_GLES(int width, int height)
{
    GLint linked;
    GLuint program;
    GLuint vertexShader;
    GLuint fragmentShader;
    assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0);
    assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0);
    assert((program = glCreateProgram()) != 0);
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked) {
            GLint infoLen = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen > 1) {
                    char *infoLog = malloc(infoLen);
                    glGetProgramInfoLog(program, infoLen, NULL, infoLog);
                    fprintf(stderr, "Error linking program:\n%s\n", infoLog);
                    free(infoLog);
            }
            glDeleteProgram(program);
            exit(1);
    }

    glClearColor(0.15f, 0.15f, 0.15f, 0.15f);
    glViewport(0, 0, width, height);
    glEnable(GL_DEPTH_TEST);

    glUseProgram(program);

    GLfloat vertex[] = {
        1, 0, 0,
        0, 1, 0,
        -1, 0, 0,
        0, -1, 0,
    };

    GLfloat texcoord[] = {
        1, 1,
        0, 1,
        0, 0,
        1, 0,
    };

    GLushort index[] = {
        0, 1, 2,
        0, 3, 2,
    };

    GLuint VBO[3];
    glGenBuffers(3, VBO);

    GLint pos = glGetAttribLocation(program, "positionIn");
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat) * 3, vertex, GL_STATIC_DRAW);
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, 0, 0, 0);

    GLint tex = glGetAttribLocation(program, "texcoordIn");
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat) * 2, texcoord, GL_STATIC_DRAW);
    glEnableVertexAttribArray(tex);
    glVertexAttribPointer(tex, 2, GL_FLOAT, 0, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[2]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLushort), index, GL_STATIC_DRAW);

    GLuint texid;
    GLint texMap = glGetUniformLocation(program, "texMap");
    glUniform1i(texMap, 0); // GL_TEXTURE0
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &texid);
    glBindTexture(GL_TEXTURE_2D, texid);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    assert(glGetError() == 0);
}

#ifdef _X_WINDOW_SYSTEM_

#include <X11/Xlib.h>

static EGLNativeWindowType CreateNativeWindow(void)
{
    assert((display = XOpenDisplay(NULL)) != NULL);

    int screen = DefaultScreen(display);
    Window root = DefaultRootWindow(display);
    Window window =  XCreateWindow(display, root, 0, 0, 600, 480, 0,
         DefaultDepth(display, screen), InputOutput,
         DefaultVisual(display, screen), 
         0, NULL);
    XMapWindow(display, window);
    XFlush(display);
    return window;
}

#endif

int display_init(int width, int height)
{
#ifdef _X_WINDOW_SYSTEM_
    render_target_init(CreateNativeWindow());
#else
    struct mali_native_window window;
    window.width = width;
    window.height = height;
    render_target_init(&window);
#endif

    init_GLES(width, height);
}

void render_frame(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
    //glDrawArrays(GL_TRIANGLES, 0, 3);

    eglSwapBuffers(display, surface);
}

void update_texture(void *data, int width, int height)
{
    static int first_time = 1;

    if (first_time) {
        printf("create texture %d %d\n", width, height);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        first_time = 0;
    }
    else {
        printf("update texture %d %d\n", width, height);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
    }

    assert(glGetError() == 0);
}

int main(void)
{
    int i;
    void *texture[2] = {0};

    int fd = open("0.rgb", O_RDONLY);
    struct stat st;
    fstat(fd, &st);
    texture[0] = malloc(st.st_size);
    read(fd, texture[0], st.st_size);
    close(fd);

    fd = open("1.rgb", O_RDONLY);
    fstat(fd, &st);
    texture[1] = malloc(st.st_size);
    read(fd, texture[1], st.st_size);
    close(fd);

    display_init(600, 480);

    for (i = 0; i < 200; i++) {
        update_texture(texture[i%2], 720, 576);
        render_frame();
        usleep(20000);
    }

    return 0;
}

vert.glsl

attribute vec3 positionIn;
attribute vec2 texcoordIn;

varying vec2 texcoord;

void main()
{
    gl_Position = vec4(positionIn, 1);
    texcoord = texcoordIn;
}

碎片.glsl

precision mediump float;

uniform sampler2D texMap;

varying vec2 texcoord;

void main() {
    vec3 color = texture2D(texMap, texcoord).rgb;
    gl_FragColor = vec4(color, 1);
}

最佳答案

您是否尝试渲染没有纹理的框架?

像 gl_FragColor = vec4(1.0,0.0,0.0,1.0);然后检查它仍然是黑色或红色。

如果是红色,请检查您的纹理函数。

我认为不一帧调用这些函数可能会出现问题

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,c_Texture[TEXTURES_FIRST].texture_id);
glUniform1i(h_Texture[TEXTURES_FIRST],1);

关于embedded - OpenGL ES 2.0 程序在 Mali400 平台上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16869335/

相关文章:

c - bss段结束地址小于起始地址

android - 如何以编程方式在 Android 中使用 OpenGL ES 2.0 动态绘制虚线?

linux - 硬件启动 - 在新板上安装 uboot

embedded - PIC 中的计算方程

opengl-es - 是否可以在片段着色器中绘制线条粗细?

java - Triangle_Strip 应该包裹吗?

c - OpenCL : Querying max clock frequency of a mobile GPU always returns a lesser value

c++ - ComputeLibrary CLTensor 数据传输

arm - 是否可以使用 Mali OpenCL SDK 在 ARM CPU (Cortex-a7) 上执行 OpenCL 代码?

c - 如何与LCD通信(嵌入式C)