2012-03-02 48 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