4

I'm writing a simple texture stream rendering program using OpenGL ES 2.0. The program works on desktop but fail on embedded platform with Mali400 GPU. The LCD goes black with the top few lines blinking. I don't know what's wrong with my code. I tried some other OpenGL ES 2.0 programs which are OK, so the problem must lay in my code. Any help will be appreciated. Thanks.

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);
}
user1777342
  • 433
  • 1
  • 5
  • 11

1 Answers1

0

Did you try to render the frame without the texture ?

Do like gl_FragColor = vec4(1.0,0.0,0.0,1.0); then check it is still black or red.

If red check your texture function.

I think it can be a problem not to call these functions each a frame

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,c_Texture[TEXTURES_FIRST].texture_id);
glUniform1i(h_Texture[TEXTURES_FIRST],1);
Sung
  • 1,036
  • 1
  • 8
  • 22