2013-06-01 57 views
3

我正在使用OpenGL ES 2.0編寫一個簡單的紋理流渲染程序。該程序在桌面上運行,但在Mali400 GPU的嵌入式平臺上失敗。液晶顯示屏變黑,頂部幾行閃爍。我不知道我的代碼有什麼問題。我嘗試了一些其他的OpenGL ES 2.0程序,因此問題必須出現在我的代碼中。任何幫助將不勝感激。謝謝。Mali400平臺上的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; 
} 

frag.glsl

precision mediump float; 

uniform sampler2D texMap; 

varying vec2 texcoord; 

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

回答

0

你嘗試呈現無紋理的框架?

像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);