I try to use openGL programs and shaders in a SDL2 application.
I can change full window color using for example:
static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, red);
But I’m not able to draw anything using shaders and program.
Here a small example, nothing is rendered but it should draw a triangle, as far I know.
#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: %sn", 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: %sn", glewGetErrorString(err));
}
printf("Vendor: %sn", glGetString(GL_VENDOR)); // null !
printf("OpenGL Version: %sn", glGetString(GL_VERSION)); // null !
printf("Shader Version: %sn", 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);
//glCullFace(GL_BACK);
glEnable(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 %in", 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;
}
I only get a black screen.
The fact that glGetIntegerv(GL_CURRENT_PROGRAM, &x) is always giving 0 is also disturbing to me.