Weird behavior : Rendering is done in the top right screen corner
Posted: 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 :
Render code :
Texture creation code :
VBO code :
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);