SDL2 OpenGL Window 为黑色

SDL2 OpenGL Window is black

该程序旨在通过倒置控件移动立方体,因此您感觉就像在围绕立方体移动相机。

我无法让立方体出现。

/*
 * SDL OpenGL Tutorial.
 * (c) Michael Vance, 2000
 * briareos@lokigames.com
 *
 * Distributed under terms of the LGPL.
 */

#include <GL/glew.h>
#include <GL/gl.h>
#include <SDL2/SDL.h>

#include <stdio.h>
#include <stdlib.h>

#include <iostream>

static GLboolean should_rotate = GL_TRUE;

static void quit_tutorial(int code)
{
    /*
     * Quit SDL so we can release the fullscreen
     * mode and restore the previous video settings,
     * etc.
     */
    SDL_Quit();

    /* Exit program. */
    exit(code);
}

static void handle_keys(const Uint8 *keys, GLfloat pos[3])
{

    /*
     * We're only interested if 'Esc' has
     * been presssed.
     *
     * EXERCISE:
     * Handle the arrow keys and have that change the
     * viewing position/angle.
     */

    if (keys[SDL_SCANCODE_ESCAPE])
        quit_tutorial(0);
    if (keys[SDL_SCANCODE_W])
    {
        pos[2] -= 0.3f;
    }
    if (keys[SDL_SCANCODE_A])
    {
        pos[0] -= 0.3f;
    }
    if (keys[SDL_SCANCODE_S])
    {
        pos[2] += 0.3f;
    }
    if (keys[SDL_SCANCODE_D])
    {
        pos[0] += 0.3f;
    }
    if (keys[SDL_SCANCODE_SPACE])
    {
        pos[1] += 0.3f;
    }
    if (keys[SDL_SCANCODE_LSHIFT])
    {
        pos[1] -= 0.3f;
    }
}

static void process_events(GLfloat pos[3])
{
    /* Our SDL event placeholder. */
    SDL_Event event;

    /* Grab all the events off the queue. */
    while (SDL_PollEvent(&event))
    {

        switch (event.type)
        {
        case SDL_QUIT:
            /* Handle quit requests (like Ctrl-c). */
            quit_tutorial(0);
            break;
        }
        //std::cout << "event" << std::endl;
    }
    handle_keys(SDL_GetKeyboardState(__null), pos);
}

static void draw_screen(SDL_Window *win, GLfloat pos[3])
{
    /* Our angle of rotation. */
    static float angle = 0.0f;

    /*
     * EXERCISE:
     * Replace this awful mess with vertex
     * arrays and a call to glDrawElements.
     *
     * EXERCISE:
     * After completing the above, change
     * it to use compiled vertex arrays.
     *
     * EXERCISE:
     * Verify my windings are correct here ;).
     */
    static GLfloat v0[] = {-1.0f, -1.0f, 1.0f};
    static GLfloat v1[] = {1.0f, -1.0f, 1.0f};
    static GLfloat v2[] = {1.0f, 1.0f, 1.0f};
    static GLfloat v3[] = {-1.0f, 1.0f, 1.0f};
    static GLfloat v4[] = {-1.0f, -1.0f, -1.0f};
    static GLfloat v5[] = {1.0f, -1.0f, -1.0f};
    static GLfloat v6[] = {1.0f, 1.0f, -1.0f};
    static GLfloat v7[] = {-1.0f, 1.0f, -1.0f};
    static GLubyte red[] = {255, 0, 0, 255};
    static GLubyte green[] = {0, 255, 0, 255};
    static GLubyte blue[] = {0, 0, 255, 255};
    static GLubyte white[] = {255, 255, 255, 255};
    static GLubyte yellow[] = {255, 255, 0, 255};
    static GLubyte black[] = {0, 0, 0, 255};
    static GLubyte cyan[] = {0, 255, 255, 255};
    static GLubyte purple[] = {255, 0, 255, 0};

    /* Clear the color and depth buffers. */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    /* We don't want to modify the projection matrix. */
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /* Move down the z-axis. */
    glTranslatef(-pos[0], -pos[1], -pos[2]);

    /* Rotate. */
    glRotatef(angle, 0.0, 1.0, 0.0);

    if (should_rotate)
    {

        if (++angle > 360.0f)
        {
            angle = 0.0f;
        }
    }

    /* Send our triangle data to the pipeline. */
    glBegin(GL_TRIANGLES);

    glColor4ubv(red);
    glVertex3fv(v0);
    glColor4ubv(purple);
    glVertex3fv(v1);
    glColor4ubv(blue);
    glVertex3fv(v2);

    glColor4ubv(red);
    glVertex3fv(v0);
    glColor4ubv(blue);
    glVertex3fv(v2);
    glColor4ubv(white);
    glVertex3fv(v3);

    glColor4ubv(purple);
    glVertex3fv(v1);
    glColor4ubv(black);
    glVertex3fv(v5);
    glColor4ubv(cyan);
    glVertex3fv(v6);

    glColor4ubv(purple);
    glVertex3fv(v1);
    glColor4ubv(cyan);
    glVertex3fv(v6);
    glColor4ubv(blue);
    glVertex3fv(v2);

    glColor4ubv(black);
    glVertex3fv(v5);
    glColor4ubv(yellow);
    glVertex3fv(v4);
    glColor4ubv(green);
    glVertex3fv(v7);

    glColor4ubv(black);
    glVertex3fv(v5);
    glColor4ubv(green);
    glVertex3fv(v7);
    glColor4ubv(cyan);
    glVertex3fv(v6);

    glColor4ubv(yellow);
    glVertex3fv(v4);
    glColor4ubv(red);
    glVertex3fv(v0);
    glColor4ubv(white);
    glVertex3fv(v3);

    glColor4ubv(yellow);
    glVertex3fv(v4);
    glColor4ubv(white);
    glVertex3fv(v3);
    glColor4ubv(green);
    glVertex3fv(v7);

    glColor4ubv(white);
    glVertex3fv(v3);
    glColor4ubv(blue);
    glVertex3fv(v2);
    glColor4ubv(cyan);
    glVertex3fv(v6);

    glColor4ubv(white);
    glVertex3fv(v3);
    glColor4ubv(cyan);

        SDL_PumpEvents();
    glVertex3fv(v6);
    glColor4ubv(green);
    glVertex3fv(v7);

    glColor4ubv(purple);
    glVertex3fv(v1);
    glColor4ubv(red);
    glVertex3fv(v0);
    glColor4ubv(yellow);
    glVertex3fv(v4);

    glColor4ubv(purple);
    glVertex3fv(v1);
    glColor4ubv(yellow);
    glVertex3fv(v4);
    glColor4ubv(black);
    glVertex3fv(v5);

    glEnd();

    SDL_GL_SwapWindow(win);

    //std::cout << pos[0] << std::endl;
}

static void setup_opengl(int width, int height)
{
    float ratio = (float)width / (float)height;

    /* Our shading model--Gouraud (smooth). */
    glShadeModel(GL_SMOOTH);

    /* Culling. */
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);
    glEnable(GL_CULL_FACE);

    /* Set the clear color. */
    glClearColor(1, 0, 0, 1);

    /* Setup our viewport. */
    glViewport(0, 0, width, height);

    /*
     * Change to the projection matrix and set
     * our viewing volume.
     */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    /*
     * EXERCISE:
     * Replace this with a call to glFrustum.
     */
    gluPerspective(100.0, ratio, 1.0, 1024.0);
}

int main(int argc, char *argv[])
{
    int width = 640;
    int height = 480;

    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
    {
        printf("error initializing SDL: %s\n", SDL_GetError());
    }

    //glewExperimental = true;

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    setup_opengl(width, height);

    std::cout << (glGetError() == GL_NO_ERROR);

    SDL_GL_SetSwapInterval( 1 );

    SDL_Window *win = SDL_CreateWindow("Worlds", // creates a window
                                       SDL_WINDOWPOS_CENTERED,
                                       SDL_WINDOWPOS_CENTERED,
                                       width, height, SDL_WINDOW_OPENGL);


    SDL_GLContext context = SDL_GL_CreateContext(win);

    GLfloat pos[] = {0, 0, 5};

    while (1)
    {
        /* Process incoming events. */
        process_events(pos);
        /* Draw the screen. */
        //printf("frame");
        draw_screen(win, pos);
        if (glGetError() != GL_NO_ERROR)
        {
        std::cout << glewGetErrorString(glGetError()) << std::endl;
        }
        SDL_Delay(1000/30);
    }

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(win);

    return 0;
}

我 运行 在 Linux Mint 20 上使用 NVIDIA 1650Ti。

OpenGL 上下文必须有效才能使用任何 OpenGL API 函数:

//setup_opengl(width, height);
//std::cout << (glGetError() == GL_NO_ERROR);

SDL_GL_SetSwapInterval( 1 );
SDL_Window *win = SDL_CreateWindow(...);
SDL_GLContext context = SDL_GL_CreateContext(win);

setup_opengl(width, height);
std::cout << (glGetError() == GL_NO_ERROR);