2012-03-02 47 views
2

上週我買了一本舊的OpenGL書(爲Windows 95設計的OpenGL superbible),只需一美元就能獲得3D和OpenGL繪圖的一些想法。所有代碼都使用這個奇怪的Windows庫,所以我一直在將示例移植到SDL OpenGL。我被困在一個可調整大小的窗口示例中,無論窗口大小如何,都在中心繪製一個正方形。出於某種原因,廣場僅出現在第一次調整大小後,無論如何調整窗口大小,我都不會再看到它。SDL可調整大小的程序沒有正確繪製OpenGL

有誰知道問題是什麼?

#include <stdio.h> 
#include <stdlib.h> 
#include "SDL.h" 
#include "SDL_opengl.h" 

#define TRUE 1 
#define FALSE 0 

#define WIN_WIDTH 500 
#define WIN_HEIGHT 400 
#define BPP 32 

//go through and get the values to see if everything was set 
int check_gl_init(int r_size, int g_size, int b_size, int dbuff) { 
    int red, green, blue, doublebuf; 

    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red); 
    if(red != r_size) { return FALSE; } 
    SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green); 
    if(green != g_size) { return FALSE; } 
    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &blue); 
    if(blue != b_size) { return FALSE; } 
    SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuf); 
    if(dbuff != doublebuf) { return FALSE; } 

    return TRUE; 
} 

int main(int argc, char** argv) { 
    SDL_Init(SDL_INIT_EVERYTHING); 
    atexit(SDL_Quit); 

    SDL_Surface* screen; 
    SDL_Event e; 
    int w = WIN_WIDTH; int h = WIN_HEIGHT; 
    Uint32 vid_flags = SDL_OPENGL | SDL_RESIZABLE; 

    if(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) < 0) { 
     printf("couldn't set double buffering: %s\n", SDL_GetError()); 
    } else { vid_flags |= SDL_DOUBLEBUF; } 

    const SDL_VideoInfo* info = SDL_GetVideoInfo(); 
    if(info->hw_available == TRUE) { vid_flags |= SDL_HWSURFACE; } else { vid_flags |= SDL_SWSURFACE; } 
    printf("hardware surfaces available?: %s\n", (info->hw_available == TRUE ? "yes" : "no")); 
    if(info->blit_hw == TRUE) { vid_flags |= SDL_HWACCEL; } 
    printf("hardware blits available?: %s\n", (info->blit_hw == TRUE ? "yes" : "no")); 

    if(SDL_VideoModeOK(WIN_WIDTH, WIN_HEIGHT, BPP, vid_flags) == 0) { 
     printf("error: video mode not supported: `%s'\n", SDL_GetError()); 
     return 0; 
    } 
    else { 
     screen = SDL_SetVideoMode(WIN_WIDTH, WIN_HEIGHT, BPP, vid_flags); 
     if(screen == NULL) { 
      printf("no video: `%s'\n", SDL_GetError()); 
      return 0; 
     } 
    } 

    if(check_gl_init(BPP/4, BPP/4, BPP/4, TRUE) == FALSE) { 
     printf("problem setting up opengl: %s\n", glGetString(glGetError())); 
     return 0; 
    } 

    int running = TRUE; 
    for(;running;) { 
     //process events 
     while(SDL_PollEvent(&e)) { 
      if(e.type == SDL_VIDEORESIZE) { 
       w = e.resize.w; h = e.resize.h; 
       if(h == 0) { h = 1; } //prevent division by zero 
       screen = SDL_SetVideoMode(w, h, BPP, vid_flags); 
       if(screen == NULL) { 
        printf("sdl error, screen died: `%s'\n", SDL_GetError()); 
       } 

       glViewport(0, 0, w, h); //x, y, w, h 
       glLoadIdentity(); //reset coordinate system 
       glMatrixMode(GL_PROJECTION); 

       if(w <= h) { 
        glOrtho(0.0f, 250.0f, 0.0f, 250.0f * (h/w), 1.0, -1.0); 
       } 
       else { 
        glOrtho(0.0f, 250.0f * (w/h), 0.0f, 250.0f, 1.0, -1.0); 
       } 

       glMatrixMode(GL_MODELVIEW); 
       glLoadIdentity(); 

       if(glGetError() != GL_NO_ERROR) { 
        printf("opengl error: %s\n", glGetString(glGetError())); 
       } 
      } 
      if(e.type == SDL_QUIT) { running = FALSE; } 
      if(e.type == SDL_KEYDOWN) { if(e.key.keysym.sym == SDLK_q) { running = FALSE; } } 
     } 

     glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //clear with blue 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     glColor3f(1.0f, 0.0f, 0.0f); //red 
     glRectf(100.0f, 150.0f, 150.0f, 100.0f); 

     glFlush(); 
     SDL_GL_SwapBuffers(); 
     SDL_Delay(100); 
    } 

    SDL_Quit(); 
    return 0; 
} 

回答

2

你有這樣的:

glLoadIdentity(); //reset coordinate system 
glMatrixMode(GL_PROJECTION); 

該序列將加載到GL_MODELVIEW堆棧單位矩陣,因爲這是最近的堆棧中的最後調整大小期間通過glMatrixMode()設置。

glOrtho()然後繼續將新的正投影矩陣乘以最後一個。正如你所看到的,這並不是很好。

設置你的矩陣模式,然後負載單位矩陣:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); //reset coordinate system 
+0

完美,謝謝! – David 2012-03-02 20:39:20