Fragment
Posts: 7
Joined: Sun Feb 05, 2017 9:30 pm

Weird behavior : Rendering is done in the top right screen corner

Tue Mar 26, 2019 12:49 am

Hello,

i have a rendering issue with OpenGL ES 2, i am rendering a fullscreen textured quad with the texture updated each frames and it work however the quad is rendered half width / half height in the top right corner of the screen...

This fullscreen quad without the dispman part was actually tested with GLFW on desktop and gles2 fbdev on NanoPI Fire and it display fine so i guess it must be something wrong in the dispman code or some buggy / unsupported stuff on VC4 side ?

The triangle2 example in raspbian work fine and some dispman setup code were used from it but i don't see anything wrong...

The full code is available here :

https://github.com/grz0zrg/fbg/blob/mas ... engl_es2.c

Here is the display setup code :

Code: Select all

const GLfloat fbg_gles2Quad[] = { -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, // vertices
                        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; // UVs

const char *fbg_gles2SimpleVs = "attribute vec3 vp; \
    attribute vec2 vu; \
    varying vec2 uv; \
    void main() { \
        uv = vu; \
        gl_Position = vec4(vp, 1.0); \
    }";

const char *fbg_gles2SimpleFs = "varying vec2 uv; \
    uniform sampler2D t0; \
    void main() { \
        gl_FragColor = texture2D(t0, uv); \
    }";
    
    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    EGLDisplay egl_display;
    EGLContext egl_context;
    EGLSurface egl_surface;

    egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (egl_display == EGL_NO_DISPLAY) {
        printf("fbg_gles2Setup: eglGetDisplay failed with EGL_NO_DISPLAY\n");

        return NULL;
    }
 
    if (!eglInitialize(egl_display, NULL, NULL)) {
        printf("fbg_gles2Setup: eglInitialize failed\n");

        return NULL;
    }
 
    static const EGLint attr[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_DEPTH_SIZE, 16,
        EGL_SAMPLES, 0,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };
 
    EGLConfig eglconf;
    EGLint num_config;

    if (!eglSaneChooseConfigBRCM(egl_display, attr, &eglconf, 1, &num_config)) {
        printf("fbg_gles2Setup: eglSaneChooseConfigBRCM failed\n");
        eglTerminate(egl_display);
        return NULL;
    }


    EGLBoolean result = eglBindAPI(EGL_OPENGL_ES_API);
    if (result == EGL_FALSE || result == EGL_BAD_PARAMETER) {
        printf("fbg_gles2Setup: eglCreateContext failed with EGL_NO_CONTEXT\n");
        eglTerminate(egl_display);
        return NULL;
    }

    static const EGLint ctxattr[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    egl_context = eglCreateContext(egl_display, eglconf, EGL_NO_CONTEXT, ctxattr);
    if (egl_context == EGL_NO_CONTEXT) {
        printf("fbg_gles2Setup: eglCreateContext failed with EGL_NO_CONTEXT\n");
        eglTerminate(egl_display);
        return NULL;
    }

    uint32_t screen_width, screen_height;
    uint32_t render_width, render_height;

    int32_t success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = screen_width;
    dst_rect.height = screen_height;

    // change this for custom render size
    render_width = screen_width;
    render_height = screen_height;
    
    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = render_width << 16;
    src_rect.height = render_height << 16;        

    dispman_display = vc_dispmanx_display_open(0 /* LCD */);
    dispman_update = vc_dispmanx_update_start(0);
        
    dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
    
    nativewindow.element = dispman_element;
    nativewindow.width = render_width;
    nativewindow.height = render_height;
    vc_dispmanx_update_submit_sync(dispman_update);

    egl_surface = eglCreateWindowSurface(egl_display, eglconf, &nativewindow, NULL);

    if (egl_surface == EGL_NO_SURFACE) {
        printf("fbg_gles2Setup: eglCreateWindowSurface failed with EGL_NO_SURFACE\n");
        eglDestroyContext(egl_display, egl_context);
        eglTerminate(egl_display);

        return NULL;
    }
 
    eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);

    gles2_context->egl_display = egl_display;
    gles2_context->egl_context = egl_context;
    gles2_context->egl_surface = egl_surface;

    gles2_context->simple_program = fbg_gles2CreateProgramFromString(fbg_gles2SimpleVs, fbg_gles2SimpleFs);
    gles2_context->fbg_vbo = fbg_gles2CreateVBOvu(12, &fbg_gles2Quad[0]);
    gles2_context->fbg_texture = fbg_gles2CreateTexture(render_width, render_height);

    //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    //glPixelStorei(GL_PACK_ALIGNMENT, 1); 

    glViewport(0, 0, screen_width, screen_height);
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

Render code :

Code: Select all

    glUseProgram(gles2_context->simple_program);

    glBindBuffer(GL_ARRAY_BUFFER, gles2_context->fbg_vbo);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) (12 * sizeof(GLfloat)));

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gles2_context->fbg_texture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fbg->width, fbg->height, GL_RGB, GL_UNSIGNED_BYTE, fbg->disp_buffer);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glUseProgram(0);

Texture creation code :

Code: Select all

    GLuint texture;
    glGenTextures(1, &texture);

    glBindTexture(GL_TEXTURE_2D, texture);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

VBO code :

Code: Select all

    GLuint vbo = 0;

    glGenBuffers(1, &vbo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // Vertices + UV
    glBufferData(GL_ARRAY_BUFFER, (data_count + (data_count / 3) * 2) * sizeof(GLfloat), data, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) (data_count * sizeof(GLfloat)));

    glBindBuffer(GL_ARRAY_BUFFER, 0);

User avatar
PeterO
Posts: 4739
Joined: Sun Jul 22, 2012 4:14 pm

Re: Weird behavior : Rendering is done in the top right screen corner

Tue Mar 26, 2019 9:25 am

Fragment wrote:
Tue Mar 26, 2019 12:49 am
The full code is available here :
https://github.com/grz0zrg/fbg/blob/mas ... engl_es2.c
A compile command or a make file would be helpful.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

Fragment
Posts: 7
Joined: Sun Feb 05, 2017 9:30 pm

Re: Weird behavior : Rendering is done in the top right screen corner

Tue Mar 26, 2019 7:49 pm

Here is an example which replicate the behavior, it draw a red 1920x1080 texture (the drawing is done on CPU) :

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#include <sys/ioctl.h>
#include <linux/fb.h>
#include <unistd.h>
#include <fcntl.h>

#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include "bcm_host.h"

void fbg_gles2PrintShaderLog(GLuint obj, int type);
GLenum fbg_gles2CreateProgramFromString(const char *vs, const char *fs);
GLenum fbg_gles2CreateProgramFromFiles(const char *vs, const char *fs);
GLuint fbg_gles2CreateProgram(GLuint vertex_shader, GLuint fragment_shader);
GLuint fbg_gles2CreateShaderFromFile(GLenum type, const char *filename);
GLuint fbg_gles2CreateShader(GLenum type, const GLchar *source);
GLuint fbg_gles2CreateVBOvu(GLsizeiptr data_count, const GLvoid *data);
GLuint fbg_gles2CreateTexture(GLuint width, GLuint height);

struct _fbg_gles2_context {
    //! EGL display
    EGLDisplay egl_display;
    //! EGL context
    EGLContext egl_context;
    //! EGL surface
    EGLContext egl_surface;
    //! EGL image
    void *egl_image;
    //! Simple GLSL program (screen-aligned textured quad)
    GLenum simple_program;
    //! FBG VBO
    GLuint fbg_vbo;
    //! FBG texture (updated at each frames)
    GLuint fbg_texture;
    //! tell wether fbg_gles2 should update fbg disp_buffer after rendering
    int update_buffer;
    char *data;
};

const GLfloat fbg_gles2Quad[] = { -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, // vertices
                        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; // UV

const char *fbg_gles2SimpleVs = "attribute vec3 vp; \
    attribute vec2 vu; \
    varying vec2 uv; \
    void main() { \
        uv = vu; \
        gl_Position = vec4(vp, 1.0); \
    }";

const char *fbg_gles2SimpleFs = "varying vec2 uv; \
    uniform sampler2D t0; \
    void main() { \
        gl_FragColor = texture2D(t0, uv); \
    }";

void fbg_gles2Draw(struct _fbg_gles2_context *fbg);
void fbg_gles2Flip(struct _fbg_gles2_context *fbg);

struct _fbg_gles2_context *fbg_gles2Setup() {
    bcm_host_init();

    struct _fbg_gles2_context *gles2_context = (struct _fbg_gles2_context *)calloc(1, sizeof(struct _fbg_gles2_context));
    if (!gles2_context) {
        fprintf(stderr, "fbg_gles2Setup: gles2 context calloc failed!\n");
        return NULL;
    }

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    //setenv("EGL_PLATFORM", "fbdev", 0);
    //setenv("FRAMEBUFFER", fb_device, 0);

    EGLDisplay egl_display;
    EGLContext egl_context;
    EGLSurface egl_surface;

    egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (egl_display == EGL_NO_DISPLAY) {
        printf("fbg_gles2Setup: eglGetDisplay failed with EGL_NO_DISPLAY\n");

        return NULL;
    }
 
    if (!eglInitialize(egl_display, NULL, NULL)) {
        printf("fbg_gles2Setup: eglInitialize failed\n");

        return NULL;
    }
 
    static const EGLint attr[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_DEPTH_SIZE, 16,
        EGL_SAMPLES, 0,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    EGLConfig eglconf;
    EGLint num_config;

/*
    if (!eglChooseConfig(egl_display, attr, &eglconf, 1, &num_config)) {
        printf("fbg_gles2Setup: eglChooseConfig failed\n");
        eglTerminate(egl_display);
        close(fd);
        return NULL;
    }*/

    if (!eglSaneChooseConfigBRCM(egl_display, attr, &eglconf, 1, &num_config)) {
        printf("fbg_gles2Setup: eglSaneChooseConfigBRCM failed\n");
        eglTerminate(egl_display);
        return NULL;
    }


    EGLBoolean result = eglBindAPI(EGL_OPENGL_ES_API);
    if (result == EGL_FALSE || result == EGL_BAD_PARAMETER) {
        printf("fbg_gles2Setup: eglCreateContext failed with EGL_NO_CONTEXT\n");
        eglTerminate(egl_display);
        return NULL;
    }

    static const EGLint ctxattr[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    egl_context = eglCreateContext(egl_display, eglconf, EGL_NO_CONTEXT, ctxattr);
    if (egl_context == EGL_NO_CONTEXT) {
        printf("fbg_gles2Setup: eglCreateContext failed with EGL_NO_CONTEXT\n");
        eglTerminate(egl_display);

        return NULL;
    }

    uint32_t screen_width, screen_height;
    uint32_t render_width, render_height;

    int32_t success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = screen_width;
    dst_rect.height = screen_height;

    // change this for custom render size
    render_width = screen_width;
    render_height = screen_height;
    
    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = render_width << 16;
    src_rect.height = render_height << 16;        

    dispman_display = vc_dispmanx_display_open(0 /* LCD */);
    dispman_update = vc_dispmanx_update_start(0);
        
    dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
    
    nativewindow.element = dispman_element;
    nativewindow.width = render_width;
    nativewindow.height = render_height;
    vc_dispmanx_update_submit_sync(dispman_update);

    egl_surface = eglCreateWindowSurface(egl_display, eglconf, &nativewindow, NULL);

    if (egl_surface == EGL_NO_SURFACE) {
        printf("fbg_gles2Setup: eglCreateWindowSurface failed with EGL_NO_SURFACE\n");
        eglDestroyContext(egl_display, egl_context);
        eglTerminate(egl_display);
        return NULL;
    }
 
    eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);

    gles2_context->egl_display = egl_display;
    gles2_context->egl_context = egl_context;
    gles2_context->egl_surface = egl_surface;

    gles2_context->simple_program = fbg_gles2CreateProgramFromString(fbg_gles2SimpleVs, fbg_gles2SimpleFs);
    gles2_context->fbg_vbo = fbg_gles2CreateVBOvu(12, &fbg_gles2Quad[0]);
    gles2_context->fbg_texture = fbg_gles2CreateTexture(render_width, render_height);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1); 

    glViewport(0, 0, screen_width, screen_height);
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    //struct _fbg *fbg = fbg_customSetup(render_width, render_height, (void *)gles2_context, fbg_gles2Draw, fbg_gles2Flip, NULL, fbg_gles2Free);

    return gles2_context;
}

void fbg_gles2Clear() {
    glClear(GL_COLOR_BUFFER_BIT);
}

void fbg_gles2Draw(struct _fbg_gles2_context *fbg) {
    struct _fbg_gles2_context *gles2_context = fbg;

    glUseProgram(gles2_context->simple_program);

    glBindBuffer(GL_ARRAY_BUFFER, gles2_context->fbg_vbo);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) (12 * sizeof(GLfloat)));

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gles2_context->fbg_texture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1920, 1080, GL_RGB, GL_UNSIGNED_BYTE, fbg->data);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glUseProgram(0);

    //glFlush();
    //glFinish();
}

void fbg_gles2Flip(struct _fbg_gles2_context *fbg) {
    struct _fbg_gles2_context *gles2_context = fbg;

    eglSwapBuffers(gles2_context->egl_display, gles2_context->egl_surface);
}

GLuint fbg_gles2CreateTexture(GLuint width, GLuint height) {
    GLuint texture;
    glGenTextures(1, &texture);

    glBindTexture(GL_TEXTURE_2D, texture);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    return texture;
}

GLuint fbg_gles2CreateVBOvu(GLsizeiptr data_count, const GLvoid *data) {
    GLuint vbo = 0;

    glGenBuffers(1, &vbo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // Vertices + UV
    glBufferData(GL_ARRAY_BUFFER, (data_count + (data_count / 3) * 2) * sizeof(GLfloat), data, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) (data_count * sizeof(GLfloat)));

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    return vbo;
}

void fbg_gles2PrintShaderLog(GLuint obj, int type) {
    static char log[16384];

    if (type == 0) {
        glGetProgramInfoLog(obj, 16384, 0, log);
    } else if (type == 1) {
        glGetShaderInfoLog(obj, 16384, 0, log);
    }
    log[16383] = 0;

    fprintf(stderr, "fbg_gles2PrintShaderLog : BEGIN:\n%s\nEND.\n", log);
}

GLuint fbg_gles2CreateShader(GLenum type, const GLchar *source) {
    GLuint shader;
    GLint status;

    shader = glCreateShader(type);

    glShaderSource(shader, 1, (const GLchar**)&source, NULL);
    glCompileShader(shader);

    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);

    if (status != GL_TRUE) {
        fprintf(stderr, "fbg_gles2CreateShader : Failed to compile shader '%s'!\n", source);

        fbg_gles2PrintShaderLog(shader, 1);

        glDeleteShader(shader);
        
        return 0;
    }

    return shader;
}

GLuint fbg_gles2CreateShaderFromFile(GLenum type, const char *filename) {
    FILE *file = fopen(filename, "rt");
    if (!file) {
        fprintf(stderr, "fbg_gles2CreateShaderFromFile : Failed to open shader file '%s'!\n", filename);
        return 0;
    }

    fseek(file, 0, SEEK_END);
    long size = ftell(file);

    GLchar *source = (GLchar*)malloc(size + 1);

    if (!source) {
        fprintf(stderr, "fbg_gles2CreateShaderFromFile : Malloc failed for '%s'!\n", filename);

        fclose(file);

        return 0;
    }

    fseek(file, 0, SEEK_SET);
    source[fread(source, 1, size, file)] = 0;
    fclose(file);

    GLuint shader = fbg_gles2CreateShader(type, source);
    free(source);

    return shader;
}

GLuint fbg_gles2CreateProgram(GLuint vertex_shader, GLuint fragment_shader) {
    GLuint program = 0;
    GLint status;

    program = glCreateProgram();

    if (vertex_shader) {
        glAttachShader(program, vertex_shader);
    }

    if (fragment_shader) {
        glAttachShader(program, fragment_shader);
    }

    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status != GL_TRUE) {
        fprintf(stderr, "fbg_gles2CreateProgram : Failed to link program!\n");

        fbg_gles2PrintShaderLog(program, 0);

        glDeleteProgram(program);

        return 0;
    }

    if (vertex_shader) {
        glDetachShader(program, vertex_shader);
    }

    if (fragment_shader) {
        glDetachShader(program, fragment_shader);
    }

    return program;
}

GLenum fbg_gles2CreateProgramFromFiles(const char *vs, const char *fs) {
    GLuint id_vs = 0;
    GLuint id_fs = 0;

    if (vs) {
        id_vs = fbg_gles2CreateShaderFromFile(GL_VERTEX_SHADER, vs);
    }

    if (fs) {
        id_fs = fbg_gles2CreateShaderFromFile(GL_FRAGMENT_SHADER, fs);
    }

    GLuint program = fbg_gles2CreateProgram(id_vs, id_fs);

    if (vs) {
        glDeleteShader(id_vs);
    }

    if (fs) {
        glDeleteShader(id_fs);
    }

    return program;
}

GLenum fbg_gles2CreateProgramFromString(const char *vs, const char *fs) {
    GLuint id_vs = 0;
    GLuint id_fs = 0;

    if (vs) {
        id_vs = fbg_gles2CreateShader(GL_VERTEX_SHADER, vs);
    }

    if (fs) {
        id_fs = fbg_gles2CreateShader(GL_FRAGMENT_SHADER, fs);
    }

    GLuint program = fbg_gles2CreateProgram(id_vs, id_fs);

    if (vs) {
        glDeleteShader(id_vs);
    }

    if (fs) {
        glDeleteShader(id_fs);
    }

    return program;
}

int main(int argc, char **argv) {
    struct _fbg_gles2_context *context = fbg_gles2Setup();

    context->data = calloc(1, sizeof(char) * 1920 * 1080 * 3);

    for (int y = 0; y < 1080; y += 1) {
        for (int x = 0; x < 1920; x += 1) {
            context->data[(x + y * 1920) * 3] = 255;
            //context->data[(x + y * 1920) * 3+1] = 0;
            //context->data[(x + y * 1920) * 3+1] = 0;
        }
    }

    while (1) {
        fbg_gles2Clear();

        fbg_gles2Draw(context);

        fbg_gles2Flip(context);
    }

    return 0;
}
compiled with

Code: Select all

gcc gles2rpi.c -std=c11 -pedantic -D_GNU_SOURCE -D_POSIX_SOURCE -Wno-unused-value -Wno-unknown-pragmas -I/opt/vc/include/ -L/opt/vc/lib/ -lbrcmGLESv2 -lbrcmEGL -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt -lm -o gles2rpi
on latest Raspbian

User avatar
PeterO
Posts: 4739
Joined: Sun Jul 22, 2012 4:14 pm

Re: Weird behavior : Rendering is done in the top right screen corner

Wed Mar 27, 2019 7:02 am

Maybe if your code didn't require a hard power off to stop it I would me more inclined to figure out the problem, but as it is......

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

Fragment
Posts: 7
Joined: Sun Feb 05, 2017 9:30 pm

Re: Weird behavior : Rendering is done in the top right screen corner

Wed Mar 27, 2019 7:02 pm

What do you mean it require a hard power off ??

Return to “OpenGLES”