Skip to content

Instantly share code, notes, and snippets.

@rdeioris
Created January 23, 2020 17:22
Show Gist options
  • Save rdeioris/f05e9a83278cbe93e93c58b61eb56085 to your computer and use it in GitHub Desktop.
Save rdeioris/f05e9a83278cbe93e93c58b61eb56085 to your computer and use it in GitHub Desktop.
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include "glad.h"
#include <string>
#include <vector>
#include <cmath>
/*typedef void glClearColorSignature(float red,
float green,
float blue,
float alpha);
typedef void glClearSignature(unsigned int mask);*/
static std::string vertex_shader_source = R"(
#version 460 core
layout(location=0) in vec2 single_vertex;
layout(location=1) in vec3 single_color;
out vec3 output_color;
void main()
{
output_color = single_color;
// swizzle
gl_Position = vec4(single_vertex.xy, 0, 1);
}
)";
static std::string fragment_shader_source = R"(
#version 460 core
//uniform vec3 triangle_color;
in vec3 output_color;
out vec4 color;
void main()
{
color = vec4(output_color.rgb, 1);
}
)";
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_VIDEO);
// setup major/minor OpenGL version
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
// core means no support for older versions
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
auto window = SDL_CreateWindow("OpenGL Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_OPENGL);
auto context = SDL_GL_CreateContext(window);
// find the address of OpenGL symbols from the .dll/.so
//glClearColorSignature *glClearColor = (glClearColorSignature*)SDL_GL_GetProcAddress("glClearColor");
//glClearSignature* glClear = (glClearSignature*)SDL_GL_GetProcAddress("glClear");
// automatically load ALL OpenGL symbols for the specific version
gladLoadGL();
// setup clear color
glClearColor(1, 0, 0, 0);
// create a program and related shaders
auto program = glCreateProgram();
auto vertex_shader = glCreateShader(GL_VERTEX_SHADER);
auto fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
// convert from std::string to c string (aka ANSI string)
auto vertex_shader_c_source = vertex_shader_source.c_str();
GLint vertex_shader_c_source_len = vertex_shader_source.length();
auto fragment_shader_c_source = fragment_shader_source.c_str();
GLint fragment_shader_c_source_len = fragment_shader_source.length();
// associate sources to related shaders (note: pointers of pointers as you can map multiple sources)
glShaderSource(vertex_shader, 1, &vertex_shader_c_source, &vertex_shader_c_source_len);
glShaderSource(fragment_shader, 1, &fragment_shader_c_source, &fragment_shader_c_source_len);
// compile the shaders (TODO: check for errors)
glCompileShader(vertex_shader);
glCompileShader(fragment_shader);
// associate shaders to the program
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
// finalize the program/pipeline
glLinkProgram(program);
// we can free shader resources as the program is now built
glDetachShader(program, vertex_shader);
glDetachShader(program, fragment_shader);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
// set the current program/pipeline
glUseProgram(program);
// redundant as we are using layout qualifier
//glBindAttribLocation(program, 0, "single_vertex");
// a VAO is an array of VBO
GLuint vao;
glGenVertexArrays(1, &vao);
// this is supported only from 4.5
//glCreateVertexArrays(1, &vao);
glBindVertexArray(vao);
// prepare the vertex data vbo (vertex buffer object)
std::vector<float> triangle =
{
0, 0.8f,
-1, -1,
0.5f, 0,
0.8f, 1,
0.6f, 0.8f,
0.9, 0.8f
};
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// upload data
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * triangle.size(), triangle.data(), GL_STATIC_DRAW);
// enable the vao attribute 0 (attributes are channels allowing communication between shaders and vao's)
glEnableVertexAttribArray(0);
// layout of the data passed to the attribute
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
// another vbo for colors
std::vector<float> colors =
{
1, 1, 0,
0, 1, 0,
0, 1, 1,
1, 1, 1,
1, 0, 1,
0, 0, 0
};
GLuint vbo_colors;
glGenBuffers(1, &vbo_colors);
glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
// upload data
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colors.size(), colors.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
// note: 3 floats as it is a color value
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
//GLint triangle_color = glGetUniformLocation(program, "triangle_color");
float accumulator = 0;
for (;;)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
}
glClear(GL_COLOR_BUFFER_BIT);
accumulator += 0.1f;
//glUniform3f(triangle_color, 0, std::sinf(accumulator), 0);
// draw call (async)
glDrawArrays(GL_TRIANGLES, 0, triangle.size() / 2);
// wait for completion, wait for vsync, swap back and front
SDL_GL_SwapWindow(window);
}
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment