diff --git a/Makefile b/Makefile index bd69ed8..ce592e6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-O1 -DDEBUG -g -ggdb -std=c23 -LIBS=`pkg-config sdl3 --cflags --libs` +LIBS=`pkg-config sdl3 --cflags --libs` -lGL -lGLEW OBJ = main.o diff --git a/main.c b/main.c index a18001a..db1038f 100644 --- a/main.c +++ b/main.c @@ -1,13 +1,19 @@ -#include // for fprintf() -#include // for exit() +#include +#include +#include #include +#include #include // only include this one in the source file with main()! + #define INITIAL_FPS 60 SDL_Window* window = NULL; -SDL_Renderer* renderer = NULL; +SDL_GLContext glcontext = NULL; + +GLuint program; +GLuint vbo; static double FPS = INITIAL_FPS; static double FrameTime = 1.0 / INITIAL_FPS; @@ -16,12 +22,12 @@ static double PerformancePeriod; static void panic ( const char *text ) __attribute__((noreturn)); -static double GetTime() +static double GetTime( void ) { return PerformancePeriod * SDL_GetPerformanceCounter(); } -static void SetTitle(SDL_Window * window) +static void SetTitle ( SDL_Window *window ) { char title[48] = {0}; SDL_snprintf(title, sizeof(title), "Crude frame limiter @ %6.3f Hz", FPS); @@ -30,13 +36,121 @@ static void SetTitle(SDL_Window * window) void panic ( const char *text ) { - fprintf(stderr, "ERROR: %s. %s\n", text, SDL_GetError()); - SDL_DestroyRenderer(renderer); + //fprintf(stderr, "ERROR: %s. %s\n", text, SDL_GetError()); + SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "%s. %s\n", text, SDL_GetError()); + SDL_GL_DestroyContext(glcontext); SDL_DestroyWindow(window); SDL_Quit(); exit(1); } +char *readFile ( const char *fileName ) +{ + SDL_IOStream *ioStream = SDL_IOFromFile(fileName, "rb"); + if (!ioStream) panic("SDL_IOFromfile"); + if (!SDL_SeekIO(ioStream, 0, SDL_IO_SEEK_END)) panic("SDL_SeekIO_END"); + long len = SDL_TellIO(ioStream); + if (!len) panic("SDL_TellIO"); + if (!SDL_SeekIO(ioStream, 0, SDL_IO_SEEK_SET)) panic("SDL_SeekIO_SET"); + char *res = SDL_malloc(len + 1); + if (!res) panic("SDL_malloc_RES"); + if (SDL_ReadIO(ioStream, res, len) != (size_t)len) panic("SDL_ReadIO"); + if (!SDL_CloseIO(ioStream)) panic("SDL_CloseIO"); + + + /* char *res = SDL_LoadFile_IO(ioStream, NULL, true); */ + /* if (!res) panic("SDL_LoadFile_IO"); */ + + res[len] = 0; + return res; +} + +GLuint CreateShader ( const char *shaderFile, GLenum shaderType ) +{ + const char *strShaderType; + if (shaderType == GL_VERTEX_SHADER) { + strShaderType = "vertex"; + } else if (shaderType == GL_GEOMETRY_SHADER) { + strShaderType = "geometry"; + } else if (shaderType == GL_FRAGMENT_SHADER) { + strShaderType = "fragment"; + } else { + SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Unrecognized shader type.\n"); + exit(1); + } + GLuint shader = glCreateShader(shaderType); + if (!shader) { + SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Error create shader type %s\n", strShaderType); + exit(1); + } + GLchar *content = readFile(shaderFile); + glShaderSource(shader, 1, (const GLchar **)&content, NULL); + SDL_free(content); + glCompileShader(shader); + GLint status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLint infoLen; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + GLchar *info = SDL_malloc(sizeof(GLchar) * (infoLen + 1)); + glGetShaderInfoLog(shader, infoLen, NULL, info); + SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Filed to compile %s shader:\n%s\n", strShaderType, info); + exit(1); + } + return shader; +} + +void CreateProgram ( GLuint *shaders, int len ) +{ + program = glCreateProgram(); + if (!program) { + SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Can't to create shader program\n"); + exit(1); + } + for (int i = 0; i < len; i++) { + glAttachShader(program, shaders[i]); + } + glLinkProgram(program); + GLint status; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + GLint infoLen; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen); + GLchar *info = SDL_malloc(sizeof(GLchar) * (infoLen + 1)); + glGetProgramInfoLog(program, infoLen, NULL, info); + SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Link failed: %s\n", info); + exit(1); + } +} + + +void CreateBuffer ( void ) +{ + float vertices[] = { + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f + }; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); +} + +void ConfProg ( void ) +{ + CreateBuffer(); + + GLuint shaders[] = { + CreateShader("vertex.glsl", GL_VERTEX_SHADER), + CreateShader("fragmet.glsl", GL_FRAGMENT_SHADER) + }; + int len = sizeof(shaders) / sizeof(shaders[0]); + CreateProgram(shaders, len); + for (int i = 0; i < len; i++) { + glDeleteShader(shaders[i]); + } +} + int main( int argc, char* argv[] ) { const int WIDTH = 640; @@ -48,27 +162,31 @@ int main( int argc, char* argv[] ) SDL_SetHint(SDL_HINT_RENDER_VSYNC, 0); - if (!SDL_Init(SDL_INIT_VIDEO)) - { + if (!SDL_Init(SDL_INIT_VIDEO)) { panic("SDL_Init failed"); } + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + PerformancePeriod = 1.0 / SDL_GetPerformanceFrequency(); time_counter = GetTime(); - window = SDL_CreateWindow("Hello SDL", WIDTH, HEIGHT, SDL_WINDOW_OPENGL); - if (!window) - { + window = SDL_CreateWindow("Hello SDL", WIDTH, HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + if (!window) { panic("SDL_CreateWindow"); } - renderer = SDL_CreateRenderer(window, "opengl"); - if (!renderer) - { - panic("SDL_CreateRenderer"); + glcontext = SDL_GL_CreateContext(window); + if (!glcontext) { + panic("SDL_GL_CreateContext"); } - //SDL_GetWindowSize(window, &width, &height); + ConfProg(); + SetTitle(window); //if (!SDL_SetRenderVSync(renderer, 1)) @@ -80,64 +198,69 @@ int main( int argc, char* argv[] ) int red = 0; int green = 0; - while (!loopShouldStop) - { + + int r, g, b; + while (!loopShouldStop) { SDL_Event e; SDL_zero(e); - while (SDL_PollEvent(&e)) - { + while (SDL_PollEvent(&e)) { if (e.type == SDL_EVENT_QUIT) loopShouldStop = true; - else if (e.type == SDL_EVENT_KEY_DOWN) - { - if (e.key.key == SDLK_X) - { + else if (e.type == SDL_EVENT_KEY_DOWN) { + if (e.key.key == SDLK_X) { FPS -= 0.1; - if (FPS < 1) - { + if (FPS < 1) { FPS = 1; } FrameTime = 1.0 / FPS; SetTitle(window); } - else if (e.key.key == SDLK_C) - { + else if (e.key.key == SDLK_C) { FPS += 0.1; FrameTime = 1.0 / FPS; SetTitle(window); } + if (e.key.key == SDLK_ESCAPE) + loopShouldStop = true; } - else if (e.key.mod == SDL_KMOD_LCTRL && e.key.key == SDLK_Q) - loopShouldStop = true; } - SDL_SetRenderDrawColor(renderer, red, green, 0, 255); - SDL_RenderClear(renderer); + /* SDL_SetRenderDrawColor(renderer, red, green, 0, 255); */ + /* SDL_RenderClear(renderer); */ + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + SDL_GL_SwapWindow(window); sleep_time = time_counter - GetTime(); - if (sleep_time * 1000 > delay_threshold) - { + if (sleep_time * 1000 > delay_threshold) { Uint32 ms = (Uint32)(sleep_time * 1000) - delay_threshold; SDL_Delay(ms); - if (time_counter < GetTime()) - { + if (time_counter < GetTime()) { delay_threshold++; SDL_Log("Slept too long. Increased threshold to %u ms.", delay_threshold); } } while (time_counter > GetTime()) { - /* Waiting for the right moment. */ + /* Waiting for the right moment. */ } - SDL_RenderPresent(renderer); - red = (red + 1) % 256; - green = (green + 1) % 64; + /* red = (red + 1) % 256; */ + /* green = (green + 1) % 64; */ time_counter += FrameTime; } - SDL_DestroyRenderer(renderer); + + SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r); + SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g); + SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b); + + printf("Red size: %d, Green size: %d, Blue size: %d\n", r, g, b); + + SDL_DestroyWindow(window); + SDL_GL_DestroyContext(glcontext); SDL_Quit(); exit(0); }