根据这里的教程:http://lazyfoo.net/tutorials/SDL/51_SDL_and_modern_opengl/index.php
但没有太多运气。有任何想法吗?下面是代码:
#include <stdio.h>
#include <SDL2/SDL.h>
#include "glew.h"
//#include <GL/glut.h>
#include <SDL2/SDL_opengl.h>
#include <stdbool.h>
void close(GLuint gProgramID, SDL_Window *window);
bool initGL(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO);
void printProgramLog(GLuint program);
void printShaderLog(GLuint shader);
void render(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO);
void close(GLuint gProgramID, SDL_Window *window) {
//Deallocate program
glDeleteProgram( gProgramID );
//Destroy window
SDL_DestroyWindow( window );
window = NULL;
//Quit SDL subsystems
SDL_Quit();
}
bool initGL(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO) {
*gProgramID = glCreateProgram();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const GLchar *vertexShaderSource[] =
{
"#version 140\nin vec2 LVertexPos2D; void main() { gl_Position = vec4( LVertexPos2D.x, LVertexPos2D.y, 0, 1 ); }"
};
glShaderSource(vertexShader, 1, vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLint vShaderCompiled = GL_FALSE;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vShaderCompiled);
if (vShaderCompiled != GL_TRUE) {
printf("Unable to compile shader %d", &vShaderCompiled);
printShaderLog(vertexShader);
return false;
}
else {
glAttachShader(*gProgramID, vertexShader);
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
const GLchar *fragmentShaderSource[] =
{
"#version 140\nout vec4 LFragment; void main() { LFragment = vec4( 1.0, 1.0, 1.0, 1.0 );}"
};
glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
GLint fShaderCompiled = GL_FALSE;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fShaderCompiled);
if(fShaderCompiled != GL_TRUE) {
printf("Unable to compile fragment shader %d!\n", fragmentShader);
printShaderLog(fragmentShader);
return false;
}
else {
glAttachShader(*gProgramID, fragmentShader);
glLinkProgram(*gProgramID);
GLint programSuccess = GL_TRUE;
glGetProgramiv(*gProgramID, GL_LINK_STATUS, &programSuccess);
if (programSuccess != GL_TRUE) {
printf("Error linking program %d!\n", *gProgramID);
printProgramLog(*gProgramID);
return false;
}
else {
*gVertexPos2DLocation = glGetAttribLocation(*gProgramID, "LVertexPos2D");
if (*gVertexPos2DLocation == -1) {
printf("LVertexPos2D is not a valid glsl program variable!\n");
return false;
}
else {
glClearColor(0.f, 0.f, 0.f, 1.f);
GLfloat vertexData[] = {
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f
};
GLuint indexData[] = { 0, 1, 2, 3 };
glGenBuffers(1, gVBO);
glBindBuffer(GL_ARRAY_BUFFER, *gVBO);
glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW);
glGenBuffers(1, gIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *gIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW);
return true;
}
}
}
}
}
void printProgramLog(GLuint program) {
if (glIsProgram(program)) {
int infoLogLength = 0;
int maxLength = infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
char* infoLog = malloc(sizeof(char) * maxLength);
glGetProgramInfoLog(program, maxLength, &infoLogLength, infoLog);
if (infoLogLength > 0) {
printf("%s\n", infoLog);
}
free(infoLog);
}
else {
printf( "Name %d is not a program\n", program );
}
}
void printShaderLog(GLuint shader) {
//Make sure name is shader
if(glIsShader( shader )) {
//Shader log length
int infoLogLength = 0;
int maxLength = infoLogLength;
//Get info string length
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
//Allocate string
char* infoLog = malloc(sizeof(char) * maxLength);
//Get info log
glGetShaderInfoLog(shader, maxLength, &infoLogLength, infoLog);
if(infoLogLength > 0) {
printf( "%s\n", infoLog );
}
//Deallocate string
free(infoLog);
}
else {
printf("Name %d is not a shader\n", shader);
}
}
void render(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO) {
//Clear color buffer
glClear(GL_COLOR_BUFFER_BIT);
//Bind program
glUseProgram(*gProgramID);
//Enable vertex position
glEnableVertexAttribArray(*gVertexPos2DLocation);
//Set vertex data
glBindBuffer(GL_ARRAY_BUFFER, *gVBO);
glVertexAttribPointer(*gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL);
//Set index data and render
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *gIBO);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL);
//Disable vertex position
glDisableVertexAttribArray(*gVertexPos2DLocation);
//Unbind program
glUseProgram(NULL);
}
int main(int argc, char *argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("SDL_Init error: %s\n", SDL_GetError());
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Window *window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
GLuint gProgramID = 0;
GLint gVertexPos2DLocation = -1;
GLuint gVBO = 0;
GLuint gIBO = 0;
SDL_GLContext *context = SDL_GL_CreateContext(window);
if (context == NULL) {
printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
return 1;
}
glewExperimental = GL_TRUE;
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
printf("Error initializing glew! %s\n", glewGetErrorString(glewError));
return 1;
}
if( SDL_GL_SetSwapInterval( 1 ) < 0 ) {
printf( "Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError() );
}
//Initialize OpenGL
if (!initGL(&gProgramID, &gVertexPos2DLocation, &gVBO, &gIBO)) {
printf( "Unable to initialize OpenGL!\n" );
return 1;
}
bool quit = false;
SDL_Event e;
while (!quit) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
quit = true;
}
if (e.type == SDL_KEYDOWN) {
SDL_Keycode keyPressed = e.key.keysym.sym;
switch (keyPressed) {
case SDLK_ESCAPE:
quit = true;
break;
}
}
}
render(&gProgramID, &gVertexPos2DLocation, &gVBO, &gIBO);
SDL_GL_SwapWindow(window);
}
SDL_StopTextInput();
close(gProgramID, window);
return 0;
}
答案 0 :(得分:3)
您正在使用的教程有一些奇怪的缺陷:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
这要求OpenGL 3.1核心配置文件上下文,因为配置文件是在GL 3.2中引入的,所以根本没有意义。 没有3.1核心配置文件。根据{{3}},现在可能发生以下情况:
如果请求版本3.1,则返回的上下文可以实现任何一个 以下版本:
- 版本3.1。 GL_ARB_compatibility扩展可能会也可能不会实现,具体取决于实现。
- 版本3.2或更高版本的核心配置文件。
所以你很有可能获得一些没有兼容性功能的现代环境,这带来了第二个缺陷:你没有使用WGL_ARB_create_context_specification。这些是现代OpenGL中的强制。您使用的教程可能会在GL实现返回带有兼容性扩展的GL 3.1上下文的几台机器上偶然使用,但绝不保证可以正常工作。
我建议您使用更准确的教程,例如Vertex Array Objects (VAOs)或Learning Modern 3D Graphics Programming。后者也有一个 open.gl,尽管使用的窗口和上下文创建库对于学习OpenGL并不是很重要。