// https://dataswamp.org/~incal/bad-el/src/glsl/bad-glsl.c #include #include #include #include #include "bad-glsl.h" #define nas __attribute__((unused)) static SDL_Window* win = NULL; static SDL_GLContext ctx; static GLuint VAO = 0; static GLuint VBO = 0; static GLuint prog = 0; const char* vert_shader_src = "#version 460 core \n" "layout (location = 0) in vec3 aPos; \n" "layout (location = 1) in vec3 aCol; \n" "out vec3 vCol; \n" "uniform vec3 uScale; \n" "uniform float uAngle; \n" "void main () { \n" " mat3 R = mat3 ( \n" " uScale.x * cos (uAngle), uScale.y * -sin (uAngle), 0.0, \n" " uScale.x * sin (uAngle), uScale.y * cos (uAngle), 0.0, \n" " 0.0, 0.0, uScale.z \n" " ); \n" " gl_Position = vec4 (aPos * R, 1.0); \n" " vCol.r = aCol.r * 2.0 * cos (uAngle) + 0.4; \n" " vCol.g = aCol.g * 1.0 * sin (uAngle) + 0.3; \n" " vCol.b = aCol.b * 4.0 * cos (uAngle) + 0.5; \n" "} \n"; const char* frag_shader_src = "#version 460 core \n" "in vec3 vCol; \n" "out vec4 FragColor; \n" "void main () { \n" " FragColor = vec4 (vCol, 1.0); \n" "} \n"; GLuint compile_shader (GLenum type, const char* src) { GLuint shader = glCreateShader (type); glShaderSource (shader, 1, &src, NULL); glCompileShader (shader); GLint ok; glGetShaderiv (shader, GL_COMPILE_STATUS, &ok); if (ok) { SDL_Log ("shader compile .... ok"); } else { char log [512]; glGetShaderInfoLog(shader, 512, NULL, log); SDL_Log ("compile error ..... %s", log); sdl_opengl_quit (); } return shader; } void sdl_opengl_init () { SDL_Init (SDL_INIT_VIDEO); // window int w = 1280; int h = 720; win = SDL_CreateWindow ("bad-el SDL3 OpenGL GLSL", w, h, SDL_WINDOW_OPENGL); ctx = SDL_GL_CreateContext (win); glewInit (); // version int major, minor; glGetIntegerv (GL_MAJOR_VERSION, &major); glGetIntegerv (GL_MINOR_VERSION, &minor); SDL_Log ("OpenGL version .... %d.%d", major, minor); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, major); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, minor); SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // shaders GLuint vs = compile_shader (GL_VERTEX_SHADER, vert_shader_src); GLuint fs = compile_shader (GL_FRAGMENT_SHADER, frag_shader_src); prog = glCreateProgram(); glAttachShader (prog, vs); glAttachShader (prog, fs); // link glLinkProgram (prog); GLint linked; glGetProgramiv (prog, GL_LINK_STATUS, &linked); if (linked) { SDL_Log ("linking ........... ok"); } else { char log [512]; glGetProgramInfoLog (prog, 512, NULL, log); SDL_Log ("linking failure ... %s", log); sdl_opengl_quit (); } // done glDetachShader (prog, vs); glDetachShader (prog, fs); glDeleteShader (vs); glDeleteShader (fs); } void sdl_opengl_init_triangle () { float verts [] = { -0.4f, -0.4f, 0.0f, 0.9f, 0.0f, 0.0f, 0.4f, -0.4f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, 0.4f, 0.0f, 0.0f, 0.0f, 1.0f }; // VAO and VBO glGenVertexArrays (1, &VAO); glGenBuffers (1, &VBO); glBindVertexArray (VAO); glBindBuffer (GL_ARRAY_BUFFER, VBO); glBufferData (GL_ARRAY_BUFFER, sizeof (verts), verts, GL_STATIC_DRAW); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof (float), (void*) 0); glEnableVertexAttribArray (0); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof (float), (void*) (3 * sizeof (float))); glEnableVertexAttribArray (1); glUseProgram (prog); glBindVertexArray (VAO); GLenum init_err = glGetError (); if (init_err == GL_NO_ERROR) { SDL_Log ("init .............. ok"); } else { SDL_Log ("init error ........ %d", init_err); } } void sdl_opengl_quit () { glDeleteVertexArrays (1, &VAO); glDeleteBuffers (1, &VBO); glDeleteProgram (prog); SDL_GL_DestroyContext (ctx); SDL_DestroyWindow (win); SDL_Quit (); } void sdl_opengl_clear () { glClearColor (0.01f, 0.02f, 0.04f, 1.0f); glClear (GL_COLOR_BUFFER_BIT); } void sdl_opengl_draw () { // locations GLuint scale_loc = glGetUniformLocation (prog, "uScale"); GLuint angle_loc = glGetUniformLocation (prog, "uAngle"); // scale float scale_x = 1.0f; float scale_y = 1.0f; float scale_z = 1.0f; float scale [3] = { scale_x, scale_y, scale_z }; // angle float angle = SDL_GetTicks () * 0.001f; // set glUniform3fv (scale_loc, 1, scale); glUniform1f (angle_loc, angle); // draw glDrawArrays (GL_TRIANGLES, 0, 3); } int main (int argc nas, char** argv nas) { sdl_opengl_init (); sdl_opengl_init_triangle (); int frames = 0; int run = 1; SDL_Event e; while (run && (frames < 2048)) { sdl_opengl_clear (); while (SDL_PollEvent (&e)) { if (e.type == SDL_EVENT_KEY_DOWN) { if (e.key.key == SDLK_Q) { run = 0; } } } sdl_opengl_draw (); SDL_GL_SwapWindow (win); frames++; SDL_Delay (16); } GLenum err = glGetError (); SDL_Log ("version used ...... %s", glGetString (GL_VERSION)); SDL_Log ("frames drawn ...... %d", frames); if (err == GL_NO_ERROR) { SDL_Log ("errors ............ none"); } else { SDL_Log ("error ............. %d", err); } sdl_opengl_quit (); return 0; }