成功初始化后,OpenGL + SDL + glew不会绘制任何内容

时间:2016-11-27 13:44:52

标签: c++ opengl sdl glew

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

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

2 个答案:

答案 0 :(得分:2)

  

除了1,0之外的其他Z上的任何内容都不会呈现。

在OpenGL的规范化设备坐标系中,查看体积就是规范化的立方体,沿着所有三个维度从-1到1。

由于你没有应用任何变换,你基本上直接在NDC空间中绘制(实际上,它将是剪辑空间,但如果你的输入w坐标是1,那么它将与NDC相同,默认情况下是) 。结果,将z设置为&lt; -1.0或&gt; 1.0将导致顶点位于观察体积之外。但是,介于两者之间的任何值(不仅仅是0.0)都应该有用。

  

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

我不是百分百肯定我理解这个问题。我认为你希望物体沿着z移动得越远就越小。但是GL将通过简单地在xy平面中进行光栅化来总是进行正交(非透视)投影。如果你想要透视效果,你必须做一些透视变换,通常,这是通过4x4同质投影矩阵完成的。

在尝试深入研究OpenGL或D3D等渲染API之前,我建议您先学习线性代数和均匀空间/投影变换的基础知识。

此外,您的代码存在一些问题:

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

答案 1 :(得分:1)

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