Benjamin LOISON Benjamin LOISON -3 years ago 95
C++ Question

glGenTextures generates an enormous number

I would like to know why the number given by glGenTextures is enormous.
The OpenGL explains that if there is a bug it must returns 0 and not an enormous GLuint.

The bug occured in the new thread called registerRedThread.

Here is my source code. I use C++, SDL2, OpenGL and multithreading.

#include <SDL.h>
#include <SDL_image.h>
#include <gl.h>
#include <glu.h>
#include <cstring>
#include <thread>
#include <iostream>
#define WINDOW_WIDTH 1365
#define WINDOW_HEIGHT 704
using namespace std;

SDL_Window *screen;
SDL_GLContext ctx;
GLuint red = 0;

SDL_Surface *flipSurface(SDL_Surface *surface)
{
int current_line, pitch;
SDL_Surface *fliped_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w,surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
SDL_LockSurface(surface);
SDL_LockSurface(fliped_surface);
pitch = surface->pitch;
for(current_line = 0; current_line < surface->h; current_line++)
memcpy(&((unsigned char*)fliped_surface->pixels)[current_line*pitch], &((unsigned char*)surface->pixels)[(surface->h - 1 - current_line)*pitch], pitch);
SDL_UnlockSurface(fliped_surface);
SDL_UnlockSurface(surface);
return fliped_surface;
}

GLuint loadTexture(const char *filename)
{
GLuint glID;
SDL_Surface *picture_surface, *gl_surface, *gl_fliped_surface;
Uint32 rmask, gmask, bmask, amask;
picture_surface = IMG_Load(filename);
if(picture_surface == NULL)
return 0;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_PixelFormat format = *(picture_surface->format);
format.BitsPerPixel = 32;
format.BytesPerPixel = 4;
format.Rmask = rmask;
format.Gmask = gmask;
format.Bmask = bmask;
format.Amask = amask;
gl_surface = SDL_ConvertSurface(picture_surface, &format, SDL_SWSURFACE);
gl_fliped_surface = flipSurface(gl_surface);
glGenTextures(1, &glID);
glBindTexture(GL_TEXTURE_2D, glID);
glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_fliped_surface->w, gl_fliped_surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, gl_fliped_surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
SDL_FreeSurface(gl_fliped_surface);
SDL_FreeSurface(gl_surface);
SDL_FreeSurface(picture_surface);
return glID;
}

void render(GLuint picture)
{
glBindTexture(GL_TEXTURE_2D, picture);
glBegin(GL_QUADS);
glTexCoord2d(0, 0); glVertex2f(-WINDOW_WIDTH, -WINDOW_HEIGHT);
glTexCoord2d(0, 1); glVertex2f(-WINDOW_WIDTH, WINDOW_HEIGHT);
glTexCoord2d(1, 1); glVertex2f(WINDOW_WIDTH, WINDOW_HEIGHT);
glTexCoord2d(1, 0); glVertex2f(WINDOW_WIDTH, -WINDOW_HEIGHT);
glEnd();
}

void registerRed()
{
SDL_GL_MakeCurrent(screen, ctx);
red = loadTexture("red.jpg");
cout << endl << "Registered: " << red << endl << endl;
}

int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_CreateWindow("My App", 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL);
SDL_Event event;
ctx = SDL_GL_CreateContext(screen);
bool running = true;
glEnable(GL_TEXTURE_2D);
GLuint blue = loadTexture("blue.jpg");
thread registerRedThread = thread(&registerRed);
while(running)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
{
running = false;
break;
}
}

cout << SDL_GetTicks() << endl;
glClear(GL_COLOR_BUFFER_BIT);

render(blue);
if(red != 0)
{
cout << "Rendering the red picture..." << endl;
render(red);
}

glFlush();
SDL_GL_SwapWindow(screen);

SDL_Delay(1000);
}
registerRedThread.detach();
SDL_Quit();
return 0;
}


EDIT: I would like to have the first thread which renders every second the screen and the second load some pictures... And both must have the same GlContext (likewise the first thread can use pictures loaded from the second thread).

Answer Source

Each gl call must be executed in the same thread where the current context was created.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download