Пробую разные туториалы по SDL2 + OpenGL. Компиляцией из 2-х туториалов получилось это:
#include <string>
#include <iostream>
// OpenGL / glew Headers
#define GL3_PROTOTYPES 1
#include <GL/glew.h>
// SDL2 Headers
#include <SDL2/SDL.h>
std::string programName = "Headerphile SDL2 - OpenGL thing";
// Our SDL_Window ( just like with SDL2 wihout OpenGL)
SDL_Window *mainWindow;
SDL_Renderer* renderer;
// Our opengl context handle
SDL_GLContext mainContext;
bool SetOpenGLAttributes();
void PrintSDL_GL_Attributes();
void CheckSDLError(int line);
void RunGame();
void Cleanup();
float points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
const char* vertex_shader =
"#version 400\n"
"in vec3 vp;"
"void main() {"
" gl_Position = vec4(vp, 1.0);"
"}";
const char* fragment_shader =
"#version 400\n"
"out vec4 frag_colour;"
"void main() {"
" frag_colour = vec4(0.5, 0.0, 0.5, 1.0);"
"}";
GLuint shader_programme;
GLuint vbo = 0;
GLuint vao = 0;
GLuint vs;
GLuint fs;
void init_shaders()
{
shader_programme = glCreateProgram();
vs = glCreateShader(GL_VERTEX_SHADER);
fs = glCreateShader(GL_FRAGMENT_SHADER);
}
void shader_func()
{
init_shaders();
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
glUseProgram(shader_programme);
glBindVertexArray(vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
}
bool Init()
{
// Initialize SDL's Video subsystem
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Failed to init SDL\n";
return false;
}
// Create our window centered at 512x512 resolution
mainWindow = SDL_CreateWindow(programName.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
1024, 1024, SDL_WINDOW_OPENGL);
// Check that everything worked out okay
if (!mainWindow)
{
std::cout << "Unable to create window\n";
CheckSDLError(__LINE__);
return false;
}
// Create our opengl context and attach it to our window
mainContext = SDL_GL_CreateContext(mainWindow);
SetOpenGLAttributes();
// This makes our buffer swap syncronized with the monitor's vertical refresh
SDL_GL_SetSwapInterval(1);
// Init GLEW
// Apparently, this is needed for Apple. Thanks to Ross Vander for letting me know
#ifndef __APPLE__
glewExperimental = GL_TRUE;
glewInit();
#endif
shader_func();
renderer = SDL_CreateRenderer(mainWindow, -1, 0);
/* Select the color for drawing. It is set to red here. */
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
/* Clear the entire screen to our selected color. */
SDL_RenderClear(renderer);
return true;
}
bool SetOpenGLAttributes()
{
// Set our OpenGL version.
// SDL_GL_CONTEXT_CORE gives us only the newer version, deprecated functions are disabled
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// 3.2 is part of the modern versions of OpenGL, but most video cards whould be able to run it
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
// Turn on double buffering with a 24bit Z buffer.
// You may need to change this to 16 or 32 for your system
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
return true;
}
int main(int argc, char *argv[])
{
if (!Init())
return -1;
// Clear our buffer with a black background
// This is the same as :
// SDL_SetRenderDrawColor(&renderer, 255, 0, 0, 255);
// SDL_RenderClear(&renderer);
//
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(mainWindow);
RunGame();
Cleanup();
return 0;
}
void RunGame()
{
bool loop = true;
while (loop)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
// draw points 0-3 from the currently bound VAO with current in-use shader
if (event.type == SDL_QUIT)
loop = false;
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
loop = false;
break;
case SDLK_r://shader_func();
// Cover with red and update
glClearColor(1.0, 0.0, 0.0, 1.0);
//glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_programme);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
//SDL_RenderCopy();
SDL_RenderPresent(renderer);
SDL_GL_SwapWindow(mainWindow);
break;
case SDLK_g:
// Cover with green and update
glClearColor(0.0, 1.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(mainWindow);
break;
case SDLK_b:
// Cover with blue and update
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(mainWindow);
break;
default:
break;
}
}
// glfwPollEvents();
// put the stuff we've been drawing onto the display
//glfwSwapBuffers(window);
}
// Swap our back buffer to the front
// This is the same as :
// SDL_RenderPresent(&renderer);
}
}
void Cleanup()
{
// Delete our OpengL context
SDL_GL_DeleteContext(mainContext);
// Destroy our window
SDL_DestroyWindow(mainWindow);
// Shutdown SDL 2
SDL_Quit();
}
void CheckSDLError(int line = -1)
{
std::string error = SDL_GetError();
if (error != "")
{
std::cout << "SLD Error : " << error << std::endl;
if (line != -1)
std::cout << "\nLine : " << line << std::endl;
SDL_ClearError();
}
}
void PrintSDL_GL_Attributes()
{
int value = 0;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &value);
std::cout << "SDL_GL_CONTEXT_MAJOR_VERSION : " << value << std::endl;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &value);
std::cout << "SDL_GL_CONTEXT_MINOR_VERSION: " << value << std::endl;
}
В первом туториале рассказывалось, как прикрутить в SDL OpenGL и он работает: окошко окрашивается в красный цвет по нажатию кнопки.
Во втором - как работать с шейдерами. И хотя код выглядит валидным, он не работает, как минимум, внутри SDL. Никакой визуальной реакции на нажатие кнопки. В чём может быть проблема?
//Все претензии по качеству и объёму приведённого кода вы можете высказать авторам туториалов.