2017-08-15 123 views
-3

我想知道爲什麼glGenTextures給出的數字是巨大的。 OpenGL解釋說如果有錯誤,它必須返回0而不是巨大的GLuint。glGenTextures生成一個巨大的數字

該錯誤發生在新線程中,稱爲registerRedThread。

這是我的源代碼。我使用C++,SDL2,OpenGL和多線程。

#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; 
} 

編輯:我想有這使得每一秒的畫面和第二加載某些圖片的第一線......而且兩者必須有相同的GlContext(同樣是第一個線程可以使用加載圖片從第二個線程)。

+2

嘗試在你的問題上內嵌你的源代碼,而不是作爲一個zip文件。 – PhotometricStereo

+3

一個.exe?你真的期望有人來運行它嗎? – kazemakase

+2

請以[mcve]的形式在問題中內嵌代碼。 –

回答

-4

每個gl調用都必須在創建當前上下文的同一個線程中執行。

+0

是的,我知道,但爲什麼它是一個龐大的數字? –

+1

@BenjaminLOISON:因爲未初始化的值是*未初始化*。 'glGenTextures' *失敗*,因此不向數組寫入任何內容。所以它包含了過去的所有內容。這是一個未初始化的整數。 –

+0

@NicolBolas謝謝你的信息!以及如何使用這兩個線程只有一個GlContext? (我想在第二個線程中加載一張圖片,以確保第一個線程將繼續呈現屏幕一次又一次) –