Advertisement
microwerx

SDL Template #2

Apr 29th, 2023
989
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.37 KB | Source Code | 0 0
  1. /**
  2.  * Copyright (c) 2023 Jonathan Metzgar
  3.  *
  4.  * This software is released under the MIT License.
  5.  * https://opensource.org/licenses/MIT
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <memory.h>
  11. #include <string.h>
  12. #include <stdint.h>
  13. #include <stdbool.h>
  14.  
  15. #include "object.h"
  16. #include "goldfish.h"
  17.  
  18. #define SDL_MAIN_HANDLED
  19. #include <SDL2/SDL.h>
  20. #include <SDL2/SDL_opengl.h>
  21.  
  22. const char *vertSource = "#version 300 es\n"
  23. "uniform mat4 WorldMatrix;\n"
  24. "uniform mat4 CameraMatrix;\n"
  25. "uniform mat4 ProjectionMatrix;\n"
  26. "\n"
  27. "attribute vec4 aPosition;\n"
  28. "attribute vec3 aNormal;\n"
  29. "attribute vec4 aColor;\n"
  30. "attribute vec4 aTexCoord;\n"
  31. "\n"
  32. "varying vec4 VS_Position;\n"
  33. "varying vec3 VS_Normal;\n"
  34. "varying vec4 VS_Color;\n"
  35. "varying vec4 VS_TexCoord;\n"
  36. "varying vec3 VS_CameraDir;\n"
  37. "\n"
  38. "void main(void)\n"
  39. "{\n"
  40. "    VS_Position = WorldMatrix * aPosition;\n"
  41. "    VS_CameraDir = CameraMatrix[3].xyz - VS_Position.xyz;\n"
  42. "    VS_Normal = aNormal;\n"
  43. "    VS_Color = aColor;\n"
  44. "    VS_TexCoord = aTexCoord;\n"
  45. "    gl_Position = ProjectionMatrix * CameraMatrix * WorldMatrix * aPosition;\n"
  46. "}\n";
  47.  
  48. const char *fragSource = "\n"
  49. "void main(void)\n"
  50. "{\n"
  51. "    gl_FragColor = vec4(1, 1, 0, 1);\n"
  52. "}\n";
  53.  
  54. void LogSDLError()
  55. {
  56.     fprintf(stderr, "Error: %s\n", SDL_GetError());
  57. }
  58.  
  59. /////// Game Engine //////
  60.  
  61. typedef struct GameEngine
  62. {
  63.     Object_t self;
  64.     SDL_Window *window;
  65.     int frameCount;
  66.     double previousTime;
  67.     double currentTime;
  68.     double deltaTime;
  69.     int width;
  70.     int height;
  71.     bool finished;
  72.  
  73.     GfPipelineState pso;
  74. } GameEngine;
  75.  
  76. typedef GameEngine *GameEnginePtr;
  77.  
  78. GameEnginePtr CreateGameEngine()
  79. {
  80.     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
  81.     {
  82.         LogSDLError();
  83.         return NULL;
  84.     }
  85.  
  86.     const int windowWidth = 1280;
  87.     const int windowHeight = 720;
  88.  
  89.     // Tell SDL2 to make a window with an OpenGL context.
  90.     SDL_WindowFlags windowFlags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
  91.     SDL_Window *window = SDL_CreateWindow("Game Engine",
  92.                                           SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
  93.                                           windowWidth, windowHeight, windowFlags);
  94.     if (window == NULL)
  95.     {
  96.         LogSDLError();
  97.         return NULL;
  98.     }
  99.  
  100.     // Tell SDL2 what to have in the OpenGL context.
  101.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
  102.     // SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  103.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
  104.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
  105.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
  106.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  107.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
  108.     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
  109.  
  110.     SDL_GLContext glContext = SDL_GL_CreateContext(window);
  111.     if (glContext == NULL)
  112.     {
  113.         LogSDLError();
  114.         return NULL;
  115.     }
  116.  
  117.     // Enable vsync on the display.
  118.     SDL_GL_SetSwapInterval(1);
  119.     SDL_GL_MakeCurrent(window, glContext);
  120.  
  121.     GameEnginePtr engine = (GameEnginePtr)allocObject(sizeof(GameEngine));
  122.  
  123.     engine->window = window;
  124.     engine->width = windowWidth;
  125.     engine->height = windowHeight;
  126.     engine->currentTime = SDL_GetTicks64() / 1000.0;
  127.  
  128.     // engine->pso = GfNewPipeline(vertSource, fragSource);
  129.     engine->pso = GfNewPipeline(NULL, fragSource);
  130.  
  131.     return engine;
  132. }
  133.  
  134. void EngineStartFrame(GameEnginePtr engine)
  135. {
  136.     engine->previousTime = engine->currentTime;
  137.     engine->currentTime = SDL_GetTicks64() / 1000.0;
  138.     engine->deltaTime = engine->currentTime - engine->previousTime;
  139.     engine->frameCount++;
  140. }
  141.  
  142. void EnginePollEvents(GameEnginePtr engine)
  143. {
  144.     // Process all events for the current frame.
  145.     SDL_Event e;
  146.     while (SDL_PollEvent(&e))
  147.     {
  148.         if (e.type == SDL_KEYDOWN)
  149.         {
  150.             if (e.key.keysym.sym == SDLK_ESCAPE)
  151.                 engine->finished = true;
  152.         }
  153.  
  154.         else if (e.type == SDL_WINDOWEVENT)
  155.         {
  156.             if (e.window.event == SDL_WINDOWEVENT_RESIZED)
  157.             {
  158.                 engine->width = e.window.data1;
  159.                 engine->height = e.window.data2;
  160.             }
  161.         }
  162.  
  163.         else if (e.type == SDL_QUIT)
  164.         {
  165.             engine->finished = true;
  166.         }
  167.  
  168.         else
  169.         {
  170.             // This is an unhandled event.
  171.         }
  172.     }
  173. }
  174.  
  175. void EngineTick(GameEnginePtr engine)
  176. {
  177. }
  178.  
  179. void EngineDraw(GameEnginePtr engine)
  180. {
  181.     // Set up OpenGL drawing commands.
  182.     glViewport(0, 0, engine->width, engine->height);
  183.  
  184.     double s = sin(engine->currentTime) * 0.5 + 0.5;
  185.     glClearColor(0.1, s, 0.3, 1.0);
  186.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  187.  
  188.     // TODO: Put in a buffer for the shaders.
  189.     glMatrixMode(GL_PROJECTION);
  190.     glLoadIdentity();
  191.     glMatrixMode(GL_MODELVIEW);
  192.     glLoadIdentity();
  193.  
  194.     // TODO: Put in a buffer for our draw calls.
  195.     // GfCommandBuffer cmdBuffer = GfCommandQueueCommandBuffer(cmdQueue);
  196.     // GfRenderEncoder renderEncoder = GfCommandBufferRenderEncoder(cmdBuffer);
  197.     // GfRenderEncoderSetPipeline(renderEncoder, pso);
  198.     // GfRenderEncoderVertexBuffer(renderEncoder, triangleBuffer, 0);
  199.     // GfRenderEncoderDrawPrimitives(renderEncoder, GfTriangles, 0, 3);
  200.     // GfRenderEncoderEndEncoding(renderEncoder);
  201.     // GfCommandBufferCommit();
  202.  
  203.     GfUsePipeline(engine->pso);
  204.     // GfSetVertexBuffer(triangleBuffer, 0);
  205.     // GfDrawPrimitives(GfTriangles, 0, 3);
  206.  
  207.  
  208.     glBegin(GL_TRIANGLES);
  209.     glVertex2f(-0.5f, -0.5f);
  210.     glVertex2f(0.5f, -0.5f);
  211.     glVertex2f(0.0f, 0.5f);
  212.     glEnd();
  213. }
  214.  
  215. void EngineEndFrame(GameEnginePtr engine)
  216. {
  217.     SDL_GL_SwapWindow(engine->window);
  218. }
  219.  
  220. int main(int argc, char **argv)
  221. {
  222.     GameEnginePtr engine = CreateGameEngine();
  223.     if (engine == NULL)
  224.     {
  225.         return -1;
  226.     }
  227.  
  228.     // Start the game loop.
  229.     while (!engine->finished)
  230.     {
  231.         EngineStartFrame(engine);
  232.         EnginePollEvents(engine);
  233.  
  234.         // Leave the loop if we're done.
  235.         if (engine->finished)
  236.             break;
  237.  
  238.         EngineTick(engine);
  239.         EngineDraw(engine);
  240.         EngineEndFrame(engine);
  241.     }
  242.  
  243.     releaseObject((ObjectPtr)engine);
  244.     return 0;
  245. }
  246.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement