193 lines
6.4 KiB
C
193 lines
6.4 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include <GL/glew.h>
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3/SDL_opengl.h>
|
|
#include <SDL3/SDL_main.h> // only include this one in the source file with main()!
|
|
#include "opengl.h"
|
|
|
|
#define INITIAL_FPS 60
|
|
|
|
static double FPS = INITIAL_FPS;
|
|
static double FrameTime = 1.0 / INITIAL_FPS;
|
|
|
|
static double PerformancePeriod;
|
|
|
|
static double GetTime( void )
|
|
{
|
|
return PerformancePeriod * SDL_GetPerformanceCounter();
|
|
}
|
|
|
|
static void SetTitle ( SDL_Window *window )
|
|
{
|
|
char title[48] = {0};
|
|
SDL_snprintf(title, sizeof(title), "Hello Triangles! Framelimit: %6.3f Hz", FPS);
|
|
SDL_SetWindowTitle(window, title);
|
|
}
|
|
|
|
float toRad ( float deg )
|
|
{
|
|
/* 180 deg = pi */
|
|
/* "deg" deg = x */
|
|
return deg * 3.141593f / 180.0f;
|
|
}
|
|
|
|
void resizeWindow ( int width, int height )
|
|
{
|
|
shaderProgram_t sp;
|
|
float n = 1.0f; // near
|
|
float f = 3.0f; // far
|
|
float fov = toRad(90); // 90 or 65 for console
|
|
float aspect = width / (float) height;
|
|
float t = n * tanf (fov / 2.0f);
|
|
float r = t * aspect;
|
|
|
|
float projMatr[] = {
|
|
n/r, 0, 0, 0,
|
|
0, n/t, 0, 0,
|
|
0, 0, (f+n)/(n-f), -1,
|
|
0, 0, 2.0f*n*f/(n-f), 0
|
|
}; // it's not rows, it's columns, 'GL_FALSE'
|
|
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "n=%.1f f=%.1f fov=%.2f aspect=%.2f t=%.2f r=%.2f\n", n, f, fov, aspect, t, r);
|
|
glUseProgram(sp.program);
|
|
glUniformMatrix4fv(sp.projMatrLoc, 1, GL_FALSE, projMatr);
|
|
glUseProgram(0);
|
|
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
|
}
|
|
|
|
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
_glWindows_t glW;
|
|
const int WIDTH = 640;
|
|
const int HEIGHT = 480;
|
|
int delayThreshold = 2;
|
|
int r, g, b, alpha_s, depth_s, stencil_s, dbuffer, glVersionMa, glVersionMi, glAccel, glProfile = 0;
|
|
double sleepTime = 0;
|
|
double timeCounter = 0;
|
|
bool loopShouldStop = false;
|
|
|
|
SDL_SetHint(SDL_HINT_RENDER_VSYNC, 0);
|
|
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_Init failed: %s", SDL_GetError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Set atrribute SDL_GL_CONTEXT_PROFILE_MASK: %s", SDL_GetError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
|
|
PerformancePeriod = 1.0 / SDL_GetPerformanceFrequency();
|
|
timeCounter = GetTime();
|
|
|
|
glW.window = SDL_CreateWindow("Hello SDL", WIDTH, HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
|
if (!glW.window) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_CreateWindow: %s", SDL_GetError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
glW.glcontext = SDL_GL_CreateContext(glW.window);
|
|
if (!glW.glcontext) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_GL_CreateContext: %s", SDL_GetError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
SetTitle(glW.window);
|
|
|
|
SDL_HideCursor();
|
|
|
|
glewExperimental = GL_TRUE;
|
|
GLenum err = glewInit();
|
|
if (err != GLEW_OK) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "glewInit: %s", glewGetErrorString(err));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
|
|
SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &glProfile);
|
|
SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &glAccel);
|
|
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &glVersionMa);
|
|
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &glVersionMi);
|
|
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
|
|
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
|
|
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
|
|
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha_s);
|
|
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth_s);
|
|
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_s);
|
|
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &dbuffer);
|
|
|
|
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "OpenGL Version: %d.%d, OpenGL Accelerated: %d, OpenGL Profile Mask: %d",
|
|
glVersionMa, glVersionMi, glAccel, glProfile);
|
|
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Red size: %d, Green size: %d, Blue size: %d, Alpha size: %d, Depth size: %d, Stencil size: %d, DoubleBuffer: %d",
|
|
r, g, b, alpha_s, depth_s, stencil_s, dbuffer);
|
|
|
|
SDL_GL_SetSwapInterval(0);
|
|
startShaderProg();
|
|
|
|
while (!loopShouldStop) {
|
|
SDL_Event e;
|
|
SDL_zero(e);
|
|
while (SDL_PollEvent(&e)) {
|
|
if (e.type == SDL_EVENT_QUIT)
|
|
loopShouldStop = true;
|
|
else if (e.type == SDL_EVENT_WINDOW_RESIZED) {
|
|
resizeWindow(e.window.data1, e.window.data2);
|
|
}
|
|
else if (e.type == SDL_EVENT_KEY_DOWN) {
|
|
if (e.key.key == SDLK_X) {
|
|
FPS -= 0.1;
|
|
if (FPS < 1) {
|
|
FPS = 1;
|
|
}
|
|
FrameTime = 1.0 / FPS;
|
|
SetTitle(glW.window);
|
|
} else if (e.key.key == SDLK_C) {
|
|
FPS += 0.1;
|
|
FrameTime = 1.0 / FPS;
|
|
SetTitle(glW.window);
|
|
}
|
|
if (e.key.key == SDLK_ESCAPE)
|
|
loopShouldStop = true;
|
|
}
|
|
}
|
|
|
|
_GLBuffer();
|
|
if (!SDL_GL_SwapWindow(glW.window)) {
|
|
SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_GL_SwapWwindow: %s", SDL_GetError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
sleepTime = timeCounter - GetTime();
|
|
if (sleepTime * 1000 > delayThreshold) {
|
|
Uint32 ms = (Uint32)(sleepTime * 1000) - delayThreshold;
|
|
SDL_Delay(ms);
|
|
if (timeCounter < GetTime()) {
|
|
delayThreshold++;
|
|
SDL_Log("Slept too long. Increased threshold to %u ms", delayThreshold);
|
|
}
|
|
}
|
|
|
|
while (timeCounter > GetTime()) {
|
|
/* Waiting for the right moment. */
|
|
}
|
|
timeCounter += FrameTime;
|
|
}
|
|
|
|
SDL_DestroyWindow(glW.window);
|
|
SDL_GL_DestroyContext(glW.glcontext);
|
|
SDL_Quit();
|
|
exit(EXIT_SUCCESS);
|
|
}
|