我尝试在 SDL2 应用程序中使用 openGL 程序和着色器。
我可以使用以下示例更改整个窗口颜色:
static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glClearBufferfv(GL_COLOR, 0, 红色);
但是我无法使用着色器和程序绘制任何东西。 这是一个小例子,据我所知,没有渲染任何内容,但它应该绘制一个三角形。
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <cstdio>
static const GLchar* vertexShaderSrc[] =
{
"#version 430 core \n"
" \n"
"const vec4 vertices[3] = vec4[3]("
"vec4(0.25, -0.25,0.5,1.0),"
"vec4(-0.25, -0.25,0.5,1.0),"
"vec4(0.25, 0.25,0.5,1.0)"
"); \n"
" \n"
"void main(void) \n"
"{ \n"
" gl_Position = vertices[gl_VertexID]; \n"
"} \n"
};
static const GLchar* fragmentShaderSrc[] =
{
"#version 430 core \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = vec4(0.0, 0.8, 1.0, 1.0); \n"
"} \n"
};
int main(int argc, char* argv[])
{
int init = SDL_Init(SDL_INIT_EVERYTHING);
if (init < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
return 1;
}
// Use OpenGL 4.3 core profile
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// Turn on double buffering with a 24bit Z buffer
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
auto window = SDL_CreateWindow(
"Hello",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
700,300,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
);
// Create a OpenGL Context
auto glContext = SDL_GL_CreateContext(window);
glewExperimental = GL_TRUE;
auto err = glewInit();
printf("glewInit: %i \n", err);
if (GLEW_OK != err)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
printf("Vendor: %s\n", glGetString(GL_VENDOR)); // null !
printf("OpenGL Version: %s\n", glGetString(GL_VERSION)); // null !
printf("Shader Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); // null !
err = SDL_GL_MakeCurrent(window, glContext);
// Enable VSync
SDL_GL_SetSwapInterval(-1);
printf("gl context: %i \n", err);
// program specific
// Set up initial GL attributes
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
// create program
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, vertexShaderSrc, nullptr);
glCompileShader(vertexShader);
//Check vertex shader for errors
GLint vShaderCompiled = GL_FALSE;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vShaderCompiled);
if (vShaderCompiled != GL_TRUE)
{
printf("Unable to compile vertex shader %d!\n", vertexShader);
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, fragmentShaderSrc, nullptr);
glCompileShader(fragmentShader);
//Check vertex shader for errors
vShaderCompiled = GL_FALSE;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &vShaderCompiled);
if (vShaderCompiled != GL_TRUE)
{
printf("Unable to compile fragment shader %d!\n", fragmentShader);
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
GLint programSuccess = GL_TRUE;
glGetProgramiv(program, GL_LINK_STATUS, &programSuccess);
if (programSuccess != GL_TRUE)
{
printf("Error linking program %d!\n", program);
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// VAO
GLuint VAO;
glCreateVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glUseProgram(program);
printf("a %i \n", glGetError()); // still 0
GLint x = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &x);
printf("b %i %i\n", program, x); // used program is 0 however !!!
int i = 200;
while (i>0) {
i--;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(0);
//
SDL_GL_SwapWindow(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteProgram(program);
SDL_GL_DeleteContext(glContext);
//end
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
我只看到黑屏。
glGetIntegerv(GL_CURRENT_PROGRAM, &x) 总是给出 0 的事实也让我感到不安。
glGetString(GL_VENDOR) 或 GL_VERSION 也给出 0。
我已经测试了其他应该可以工作但没有成功的代码,所以我应该准确地说我正在使用 Visual Studio 和 vcpk 作为编译系统。
问题与 Visual Studio 构建相关。与 Cmake + Msbuild 和命令行配合使用效果良好