使用SDL的OpenGL,我做错了什么?

时间:2013-09-18 17:58:17

标签: c opengl sdl glew

我正在尝试使用SDL在OpenGL中显示简单的白色立方体。我已经设置了我的VBO和IBO:

GLfloat vertexData[] =
                {
                    -0.5f, -0.5f, -0.5f, // bot, left, back
                    -0.5f, 0.5f, -0.5f, // top, left, back
                    -0.5f, -0.5f, 0.5f, // bot, left, front
                    -0.5f, 0.5f, 0.5f, // top, left, front
                    0.5f, -0.5f, -0.5f, // bot, right, back
                    0.5f, -0.5f, 0.5f, // bot, right, front
                    0.5f, 0.5f, -0.5f, // top, right, back
                    0.5f, 0.5f, 0.5f // top, right, front
                };

GLint indexData[] = 
                {
                    //back
                    0, 1, 6,
                    0, 5, 6,
                    //left
                    0, 2, 3,
                    0, 1, 3,
                    //right
                    4, 5, 7,
                    4, 6, 7,
                    //bot
                    0, 4, 5,
                    0, 2, 5,
                    //top
                    1, 3, 7,
                    1, 6, 7,
                    //front
                    2, 3, 7,
                    2, 5, 7
                };

然而,它看起来像这样: ehm

我做错了什么?

编辑: 我的初始化函数

bool App::OpenGLInit()
{   
programID = glCreateProgram();

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);

std::string vertexString = getShaderFromFile("src/shader.vert");
const GLchar * vertexShaderSource = vertexString.c_str();
glShaderSource(vertexShader, 1, (const GLchar **)&vertexShaderSource, NULL);

glCompileShader(vertexShader);

glAttachShader(programID, vertexShader);

GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );

//Get fragment source
std::string fragmentString = getShaderFromFile("src/shader.frag");
const GLchar* fragmentShaderSource = fragmentString.c_str();

//Set fragment source
glShaderSource( fragmentShader, 1, (const GLchar **)&fragmentShaderSource, NULL );

//Compile fragment source
glCompileShader( fragmentShader );

glAttachShader(programID, fragmentShader );

glLinkProgram(programID);


return true;
}


bool App::OnInit()
{
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
    return false;
}   

if((screen = SDL_CreateWindow("Color Wars", 100, 100, 1024, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN)) == NULL) {      
    return false;
}

if ((gl_context = SDL_GL_CreateContext(screen)) == NULL)
{
    return false;
}

if((renderer = SDL_CreateRenderer(screen, -1, 0)) == NULL)
{
    return false;
} 
if (SDL_GL_SetSwapInterval(1) < 0)
    return false;
glewExperimental = GL_TRUE;

if (glewInit() != GLEW_OK)
{
    return false;
}
if (!OpenGLInit())
    return false;

game_screen = new GameScreen();
game_screen->Init(programID);

return true;
}

我的渲染功能:

void App::OnRender()
{   
glClear( GL_COLOR_BUFFER_BIT );

glUseProgram( programID );
game_screen->Render(renderer);
glUseProgram( NULL );

SDL_GL_SwapWindow(screen);
}
void GameScreen::Render(SDL_Renderer *renderer)
{
//Enable vertex position
glEnableVertexAttribArray(vertex2DPosition);
//Set vertex data
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glVertexAttribPointer(vertex2DPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL );

//Set index data and render
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IBO );


glDrawElements(GL_TRIANGLE_FAN, 12, GL_UNSIGNED_INT, NULL );

//Disable vertex position
glDisableVertexAttribArray( vertex2DPosition );

}

虚拟文字:asdasdasdasdasdasd

1 个答案:

答案 0 :(得分:1)

在此示例中,您有三件事情对您不利:

  1. 您正在 规范化设备坐标 中绘制一个多维数据集,其范围为XYZ:[ - 1,1]。

  2. 您正在绘制一个不是方形的窗口,因此您的坐标空间与窗口大小无关,因此会延伸立方体面。

  3. 它似乎是一个矩形,因为您没有定义任何查看转换,并且正面朝上而没有透视。

  4. 如果您在调整窗口大小时执行此操作,则可以更正所有这些:

    GLfloat aspect = (GLfloat)width / (GLfloat)height;
    
    glMatrixMode   (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho        ((-1.0f * aspect), (1.0f * aspect), -1.0f, 1.0f, -1.0f, 1.0f);
    glViewport     (0, 0, width, height);
    
    glMatrixMode   (GL_MODELVIEW);
    glLoadIdentity ();
    glRotatef      (45.0f, 0.25f, 0.5f, 0.75f); // Let's rotate this sucker!
    

    宽度和高度分别是SDL窗口的宽度和高度。

    更新

    看,现在很清楚为什么这不起作用。您在问题中从未提及您使用着色器。感谢您发布更新的代码。为了使其与着色器一起使用,您需要传递投影和模型视图矩阵。您可以使用相同的设置来构建矩阵,就像我使用旧的OpenGL矩阵操作函数所描述的那样,而glm可能会使这个最简单。