Discussion:
[SDL] GL coordinates since 2.0.4 - what changed?
A_SN
2016-11-22 14:52:36 UTC
Permalink
It seems a few things changed in SDL 2.0.4. Compiling my program with 2.0.5, I get many different behaviours when the program uses the SDL 2.0.4 or 2.0.5 DLL, but everything returns to normal when I use the 2.0.3 DLL.

One of them has to do with the coordinates of a GL texture I use. With the 2.0.3 DLL my texture displays in the whole window with the following code, whereas with >=2.0.4 it only fills the top right quarter of the window, the rest remains black:

Code:

// w and h and the window dimensions
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex2f(w, 0.f);
glTexCoord2f(1.f, 1.f); glVertex2f(w, h);
glTexCoord2f(0.f, 1.f); glVertex2f(0.f, h);
glEnd();



What changed? Did I forget to do something? I don't know much about OpenGL and I only use this texture which fills the screen. Here's the full source of a short program that demonstrates the problem (simply swapping DLLs produces the different behaviours):


Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include <SDL.h>
#include <gl/glew.h>
#include <SDL_opengl.h>
#include <gl/glut.h>

int get_sdl_renderer_index(const char *name)
{
int i, n;
SDL_RendererInfo info;

n = SDL_GetNumRenderDrivers();

for (i=0; i<n; i++)
{
SDL_GetRenderDriverInfo(i, &info);

if (strcmp(name, info.name)==0)
return i;
}

return -1;
}

int get_sdl_opengl_renderer_index()
{
int index;

index = get_sdl_renderer_index("opengl");

if (index==-1)
{
index = get_sdl_renderer_index("opengles2");

if (index==-1)
fprintf(stderr, "OpenGL renderer not found, fell back to default (in get_sdl_opengl_renderer_index())\n");
else
fprintf(stderr, "OpenGL renderer not found, fell back to OpenGLES2 (in get_sdl_opengl_renderer_index())\n");
}

return index;
}

int main(int argc, char *argv[])
{
int w = 800, h = 600, exit_flag = 0;
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Event event;
uint32_t gltex; // ID of the GL texture for cltex

//**** Init SDL, OpenGL/glew ****
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO);

window = SDL_CreateWindow ("Title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL);
SDL_GetWindowSize(window, &w, &h);

SDL_GL_CreateContext(window);
glewExperimental = 1;
glewInit();

renderer = SDL_CreateRenderer(window, get_sdl_opengl_renderer_index(), SDL_RENDERER_PRESENTVSYNC);
//-------------------------------

// create an OpenGL 2D texture normally
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &gltex); // generate the texture ID
glBindTexture(GL_TEXTURE_2D, gltex); // binding the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // specify texture dimensions, format etc

while (exit_flag==0)
{
while (SDL_PollEvent(&event))
{
if (event.type==SDL_QUIT)
{
exit_flag = 1;
break;
}
}

uint32_t z = 0x77AAFF33;
glClearTexImage(gltex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &z);

glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex2f(w, 0.f);
glTexCoord2f(1.f, 1.f); glVertex2f(w, h);
glTexCoord2f(0.f, 1.f); glVertex2f(0.f, h);
glEnd();

SDL_GL_SwapWindow(window);
}

SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();

return 0;
}
A_SN
2016-11-23 13:19:46 UTC
Permalink
After more research it seems like 2.0.4 must have changed to the default GL matrix mode. I now get the same results on all versions of the DLL if I call glLoadIdentity() to reset it. If I do then with both versions I can call this instead:


Code:

glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex2f(-1., 1.);
glTexCoord2f(1.f, 0.f); glVertex2f(1., 1.);
glTexCoord2f(1.f, 1.f); glVertex2f(1., -1.);
glTexCoord2f(0.f, 1.f); glVertex2f(-1., -1.);
glEnd();
capehill
2016-11-24 19:39:42 UTC
Permalink
I don't know the exact reason but there may be some issues with the code.

Do you intend to use OpenGL directly or Renderer? You seem to be mixing them. If you create an OpenGL-based renderer, it might be that you get matrices set by it.

If you continue with OpenGL, you should probably do OpenGL initializations yourself so that you are not relying on defaults or undocumented features.

Also, remember to destroy OpenGL context at the end if you created it.
Ryan C. Gordon
2016-11-27 05:25:42 UTC
Permalink
Post by A_SN
What changed? Did I forget to do something? I don't know much about
OpenGL and I only use this texture which fills the screen. Here's the
full source of a short program that demonstrates the problem (simply
You probably shouldn't use the SDL render API at all; that adds a simple
renderer on top of OpenGL, but since you're doing your own GL rendering
anyhow, it's just going to trample some GL state without your permission.

Just delete the call to SDL_CreateRenderer() and keep using everything
else in here (including the SDL_WINDOW_OPENGL flag and the
SDL_GL_CreateContext() and SDL_GL_SwapWindow() calls) as it is.

--ryan.

Loading...