OpenGL + SDL + glew在初始化成功后没有绘制任何东西

问题描述:

所以我一直在寻找一个解决方案,但我能找到的所有东西都很过时。我的问题是,在初始化SDL和glew没有错误后,窗口将打开,而其他Z上的任何内容(比1,0或-1)都不会呈现。而且将Z设置为这三个值中的任何一个都不会做任何事情。这是我的代码。我在头文件中包含glew和sdl,循环方法是主程序循环。OpenGL + SDL + glew在初始化成功后没有绘制任何东西

#include "Controller.h" 

int Controller::loop() { 
    // Initialize 
    if(!init()) 
     return -1; 

    SDL_Event _event; 

    // Main loop 
    while(_running) { 
     // Loop through all input 
     while(SDL_PollEvent(&_event)) 
      event(_event); 
     // Game logic 
     step(); 
     // Game drawing 
     draw(); 
    } 

    // End game 
    end(); 
    return 0; 
} 

bool Controller::init() { 
    // Initialize SDL 
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) 
     return false; 

    // Create window 
    if ((_mainWindow = SDL_CreateWindow("GAME", 200, 200, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL)) == NULL) 
     return false; 

    // Create context 
    _mainContext = SDL_GL_CreateContext(_mainWindow); 

    // Make it active 
    SDL_GL_MakeCurrent(_mainWindow, _mainContext); 

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 

    // Initialize glew 
    glewExperimental = GL_TRUE; 
    if (glewInit() != 0) 
     return false; 

    return true; 
} 

void Controller::event(SDL_Event& _event) { 
    switch(_event.type) { 
    case SDL_KEYDOWN: 
     switch (_event.key.keysym.sym) { 
     case SDLK_ESCAPE: 
      _running = false; 
      break; 
     default: 
      std::cout << "Key has been pressed." << std::endl; 
     } 
    default: 
     break; 
    } 
    _world[_currentWorld].event(_event); 
} 

void Controller::step() { 
    _world[_currentWorld].step(); 
} 

void Controller::draw() { 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glColor3f(1.0f, 0.0f, 0.0f); 

    glBegin(GL_TRIANGLES); 

    glVertex3f(-1.0f, -0.5f, -4.0f); // A 
    glVertex3f(1.0f, -0.5f, -4.0f); // B 
    glVertex3f(0.0f, 0.5f, -4.0f); // C 

    glEnd(); 

    //_world[_currentWorld].draw(); 
    SDL_GL_SwapWindow(_mainWindow); 
} 

void Controller::end() { 
    SDL_GL_DeleteContext(_mainContext); 
    SDL_DestroyWindow(_mainWindow); 
    SDL_Quit(); 
} 

在另一个Z什么比1,0或-1将无法呈现。

在OpenGL中的归一化设备坐标系统中,观看体积仅仅是归一化的立方体沿着所有三个维度打算从-1到1。

由于您没有应用任何转换,您基本上直接在NDC空间中绘制(实际上,它将是剪辑空间,但是如果您的输入w坐标为1,那么它将与NDC相同,并且它是默认)。因此,将z设置为< -1.0或> 1.0将导致顶点位于观察体积之外。虽然任何值之间(不只是0.0)应该工作。

而且将Z设置为这三个值中的任何一个都不会做任何事情。

我敢肯定不是100%,我理解这个问题的权利。我认为你期望物体在沿z移动时越远越小。但GL总是总是做一个正交(非透视)投影,通过在xy平面简单的光栅化。如果需要透视效果,并且通常需要通过4x4均匀投影矩阵完成,则必须进行一些透视变换

我会建议你学习线性代数和同质空间/射影变换第一的基础知识,试图潜入渲染,比如OpenGL或者D3D API的面前。

另外,还有一些与您的代码的几个问题:

你您创建的背景下,这不会有任何影响(它只会告诉SDL做什么,下一次之后请求GL上下文版本它创建一个GL上下文)。 YOu也似乎要求一个“现代”的OpenGL版本3.3。但是,用于绘制的代码在现代GL中已弃用,并且这些功能在核心配置文件中完全删除。如果你现在开始学习GL,我强烈推荐学习现代OpenGL,而不是20年前的这种过时的粗体。看看this tutorial,它也涉及数学的一些方面。

+0

感谢您的回答。我已经将这些代码放在了多个教程中,没有一个是我需要知道的。我完全忘记了Z属性的范围从0到1.在绘制一个简单的三角形之前,我不想进行变换。我发现的所有教程都是这种旧式的绘图。 –

您没有任何转换矩阵。因此,可见z的范围是[-1,1]。如果你指定了这个值,相应的部分将被剪掉(并且不可见)。