Last active
February 27, 2025 04:41
-
-
Save Lightnet/802f51fe762ecb2f99be2980a70dec56 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CMake configuration for SDL 3.2.4 project with SDL_ttf, SDL_image, SDL_mixer, and GLAD | |
cmake_minimum_required(VERSION 3.11) | |
project(MySDLProject VERSION 1.0 DESCRIPTION "SDL 3.2.4 C/C++ test with callbacks" LANGUAGES C CXX) | |
set(CMAKE_C_STANDARD 11) | |
set(CMAKE_C_STANDARD_REQUIRED ON) | |
set(CMAKE_CXX_STANDARD 11) | |
set(CMAKE_CXX_STANDARD_REQUIRED ON) | |
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Suppress deprecated warnings" FORCE) | |
set(BUILD_SHARED_LIBS ON CACHE BOOL "Default to shared libs" FORCE) | |
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>") | |
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>") | |
include(FetchContent) | |
option(BUILD_EXAMPLES "Build example executables from examples/ folder" ON) | |
# Fetch SDL 3.2.4 | |
FetchContent_Declare( | |
SDL3 | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git | |
GIT_TAG release-3.2.4 | |
) | |
message(STATUS "Fetching and building SDL 3.2.4...") | |
set(SDL_SHARED ON CACHE BOOL "Build SDL shared library" FORCE) | |
set(SDL_STATIC OFF CACHE BOOL "Build SDL static library" FORCE) | |
set(SDL_TEST_LIBRARY OFF CACHE BOOL "Build SDL test library" FORCE) | |
FetchContent_MakeAvailable(SDL3) | |
# Fetch SDL_ttf prerelease-3.1.2 | |
FetchContent_Declare( | |
SDL3_ttf | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git | |
GIT_TAG prerelease-3.1.2 | |
) | |
message(STATUS "Fetching and building SDL_ttf prerelease-3.1.2...") | |
set(SDL3TTF_BUILD_SHARED_LIBS ON CACHE BOOL "Build SDL_ttf shared library" FORCE) | |
set(CMAKE_DISABLE_FIND_PACKAGE_PkgConfig ON CACHE BOOL "Disable PkgConfig" FORCE) | |
set(CMAKE_DISABLE_FIND_PACKAGE_Python ON CACHE BOOL "Disable Python" FORCE) | |
set(SDL3TTF_INSTALL OFF CACHE BOOL "Disable SDL_ttf installation" FORCE) | |
FetchContent_MakeAvailable(SDL3_ttf) | |
# Fetch SDL_image release-3.2.0 | |
set(SDL3IMAGE_BUILD_SHARED_LIBS ON CACHE BOOL "Build SDL_image shared library" FORCE) | |
set(SDLIMAGE_VENDORED ON CACHE BOOL "Use vendored libraries" FORCE) | |
set(FETCHCONTENT_UPDATES_DISCONNECTED_ZLIB OFF CACHE BOOL "Allow zlib updates" FORCE) | |
set(FETCHCONTENT_UPDATES_DISCONNECTED_LIBPNG OFF CACHE BOOL "Allow libpng updates" FORCE) | |
set(FETCHCONTENT_UPDATES_DISCONNECTED_LIBJPEG-TURBO OFF CACHE BOOL "Allow libjpeg-turbo updates" FORCE) | |
set(SDLIMAGE_BMP ON CACHE BOOL "Enable BMP support" FORCE) | |
set(SDLIMAGE_JPG ON CACHE BOOL "Enable JPG support" FORCE) | |
set(SDLIMAGE_PNG ON CACHE BOOL "Enable PNG support" FORCE) | |
FetchContent_Declare( | |
SDL3_image | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git | |
GIT_TAG release-3.2.0 | |
) | |
message(STATUS "Fetching and building SDL_image release-3.2.0...") | |
FetchContent_MakeAvailable(SDL3_image) | |
# Fetch SDL_mixer from main branch | |
# FetchContent_Declare( | |
# SDL3_mixer | |
# GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git | |
# GIT_TAG main | |
# ) | |
# message(STATUS "Fetching and building SDL_mixer from main branch...") | |
# set(SDL3MIXER_BUILD_SHARED_LIBS ON CACHE BOOL "Build SDL_mixer shared library" FORCE) | |
# set(SDL3MIXER_SAMPLES OFF CACHE BOOL "Build SDL_mixer sample programs" FORCE) | |
# set(SDL3MIXER_FLAC OFF CACHE BOOL "Support FLAC audio" FORCE) | |
# set(SDL3MIXER_MP3 OFF CACHE BOOL "Support MP3 audio via mpg123" FORCE) | |
# set(SDL3MIXER_OGG OFF CACHE BOOL "Support OGG Vorbis audio" FORCE) | |
# set(SDL3MIXER_OPUS OFF CACHE BOOL "Support Opus audio" FORCE) | |
# set(SDL3MIXER_MOD OFF CACHE BOOL "Support MOD audio" FORCE) | |
# set(SDL3MIXER_MIDI OFF CACHE BOOL "Support MIDI audio" FORCE) | |
# set(SDL3MIXER_WAV ON CACHE BOOL "Support WAV audio" FORCE) | |
# set(SDL3MIXER_VENDORED OFF CACHE BOOL "Use vendored libraries" FORCE) | |
# set(SDL3MIXER_DEPS_SHARED OFF CACHE BOOL "Link dependencies as shared libs" FORCE) | |
# FetchContent_MakeAvailable(SDL3_mixer) | |
# Fetch GLAD | |
FetchContent_Declare( | |
glad | |
GIT_REPOSITORY https://github.com/Dav1dde/glad.git | |
GIT_TAG v0.1.36 | |
) | |
message(STATUS "Fetching GLAD...") | |
FetchContent_MakeAvailable(glad) | |
# Find Python 3 (required for GLAD generation) | |
find_package(Python3 COMPONENTS Interpreter REQUIRED) | |
if(NOT Python3_FOUND) | |
message(FATAL_ERROR "Python 3 is required to generate GLAD sources. Please install Python 3.") | |
endif() | |
# Generate GLAD sources if not already present | |
set(GLAD_OUT_DIR "${CMAKE_BINARY_DIR}/glad_generated") | |
if(NOT EXISTS "${GLAD_OUT_DIR}/include/glad/glad.h") | |
message(STATUS "Generating GLAD sources for OpenGL 3.3 core profile...") | |
execute_process( | |
COMMAND ${Python3_EXECUTABLE} -m glad --generator=c --out-path=${GLAD_OUT_DIR} --profile=core --api=gl=3.3 | |
WORKING_DIRECTORY ${glad_SOURCE_DIR} | |
RESULT_VARIABLE GLAD_GENERATE_RESULT | |
OUTPUT_VARIABLE GLAD_GENERATE_OUTPUT | |
ERROR_VARIABLE GLAD_GENERATE_ERROR | |
) | |
if(NOT GLAD_GENERATE_RESULT EQUAL "0") | |
message(FATAL_ERROR "Failed to generate GLAD sources: ${GLAD_GENERATE_RESULT}\nOutput: ${GLAD_GENERATE_OUTPUT}\nError: ${GLAD_GENERATE_ERROR}") | |
endif() | |
endif() | |
# Add GLAD as a custom static library | |
add_library(glad_custom STATIC | |
"${GLAD_OUT_DIR}/src/glad.c" | |
) | |
target_include_directories(glad_custom PUBLIC "${GLAD_OUT_DIR}/include") | |
# Define main executable from src/main.c | |
add_executable(MySDLProject src/main.c) | |
target_compile_definitions(MySDLProject PRIVATE SDL_MAIN_USE_CALLBACKS) | |
# Custom command to copy assets folder | |
add_custom_target(copy_assets | |
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/assets" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" | |
COMMENT "Copying assets to build output directory" | |
) | |
add_dependencies(MySDLProject copy_assets) | |
# Conditionally build example executables | |
if(BUILD_EXAMPLES) | |
file(GLOB EXAMPLE_SOURCES "examples/*.c" "examples/*.cpp") | |
foreach(EXAMPLE_SOURCE ${EXAMPLE_SOURCES}) | |
get_filename_component(EXAMPLE_NAME ${EXAMPLE_SOURCE} NAME_WE) | |
add_executable(${EXAMPLE_NAME} ${EXAMPLE_SOURCE}) | |
if(${EXAMPLE_SOURCE} MATCHES "\\.c$") | |
target_compile_definitions(${EXAMPLE_NAME} PRIVATE SDL_MAIN_USE_CALLBACKS) | |
endif() | |
target_include_directories(${EXAMPLE_NAME} PRIVATE | |
"${sdl3_SOURCE_DIR}/include" | |
"${sdl3_ttf_SOURCE_DIR}" | |
"${sdl3_image_SOURCE_DIR}" | |
#"${sdl3_mixer_SOURCE_DIR}" | |
) | |
target_link_libraries(${EXAMPLE_NAME} PRIVATE | |
SDL3::SDL3 | |
SDL3_ttf::SDL3_ttf | |
SDL3_image::SDL3_image | |
#SDL3_mixer::SDL3_mixer | |
) | |
# Link GLAD for sdl3_open (or example_sdl3_opengl if you prefer that name) | |
if(${EXAMPLE_NAME} STREQUAL "sdl3_open" OR ${EXAMPLE_NAME} STREQUAL "example_sdl3_opengl") | |
target_include_directories(${EXAMPLE_NAME} PRIVATE "${GLAD_OUT_DIR}/include") | |
target_link_libraries(${EXAMPLE_NAME} PRIVATE glad_custom) | |
if(WIN32) | |
target_link_libraries(${EXAMPLE_NAME} PRIVATE opengl32) | |
elseif(UNIX AND NOT APPLE) | |
target_link_libraries(${EXAMPLE_NAME} PRIVATE GL) | |
elseif(APPLE) | |
target_link_libraries(${EXAMPLE_NAME} PRIVATE "-framework OpenGL") | |
endif() | |
endif() | |
add_dependencies(${EXAMPLE_NAME} copy_assets) | |
endforeach() | |
endif() | |
# Debug include paths | |
message(STATUS "SDL3 include dir: ${sdl3_SOURCE_DIR}/include") | |
message(STATUS "SDL_ttf include dir: ${sdl3_ttf_SOURCE_DIR}") | |
message(STATUS "SDL_image include dir: ${sdl3_image_SOURCE_DIR}") | |
message(STATUS "SDL_mixer include dir: ${sdl3_mixer_SOURCE_DIR}") | |
message(STATUS "GLAD include dir: ${GLAD_OUT_DIR}/include") | |
# Set include directories for the main executable | |
target_include_directories(MySDLProject PRIVATE | |
"${sdl3_SOURCE_DIR}/include" | |
"${sdl3_ttf_SOURCE_DIR}" | |
"${sdl3_image_SOURCE_DIR}" | |
#"${sdl3_mixer_SOURCE_DIR}" | |
) | |
# Link libraries to the main executable | |
target_link_libraries(MySDLProject PRIVATE | |
SDL3::SDL3 | |
SDL3_ttf::SDL3_ttf | |
SDL3_image::SDL3_image | |
#SDL3_mixer::SDL3_mixer | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// example_sdl3_opengl.c | |
#include <SDL3/SDL.h> | |
#include <glad/glad.h> | |
#include <stdio.h> | |
#include <stdbool.h> | |
#include <math.h> | |
// Vector structure | |
typedef struct { | |
float x, y, z; | |
} Vec3; | |
// Camera structure | |
typedef struct { | |
Vec3 position; | |
Vec3 front; | |
Vec3 up; | |
Vec3 right; | |
float yaw; | |
float pitch; | |
} Camera; | |
// Global variables | |
SDL_Window* window = NULL; | |
SDL_GLContext gl_context; | |
bool running = true; | |
GLuint shaderProgram; | |
Camera camera; | |
bool mouse_captured = false; | |
GLuint VAO, VBO; | |
// Vertex shader | |
const char* vertexShaderSource = "#version 330 core\n" | |
"layout (location = 0) in vec3 aPos;\n" | |
"uniform mat4 model;\n" | |
"uniform mat4 view;\n" | |
"uniform mat4 projection;\n" | |
"void main()\n" | |
"{\n" | |
" gl_Position = projection * view * model * vec4(aPos, 1.0);\n" | |
"}\0"; | |
// Fragment shader | |
const char* fragmentShaderSource = "#version 330 core\n" | |
"out vec4 FragColor;\n" | |
"uniform vec3 lightColor;\n" | |
"void main()\n" | |
"{\n" | |
" FragColor = vec4(lightColor, 1.0);\n" | |
"}\0"; | |
// Full cube vertices (36 vertices, 6 faces) | |
float vertices[] = { | |
-0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, | |
0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, | |
-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, | |
0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, | |
-0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, | |
-0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, | |
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, | |
0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, | |
-0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, | |
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, | |
-0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, | |
0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f | |
}; | |
// Simple matrix functions | |
void mat4_identity(float* m) { | |
for (int i = 0; i < 16; i++) m[i] = (i % 5 == 0) ? 1.0f : 0.0f; | |
} | |
void mat4_perspective(float* m, float fov, float aspect, float near, float far) { | |
float tanHalfFov = tanf(fov / 2.0f); | |
mat4_identity(m); | |
m[0] = 1.0f / (aspect * tanHalfFov); | |
m[5] = 1.0f / tanHalfFov; | |
m[10] = -(far + near) / (far - near); | |
m[11] = -1.0f; | |
m[14] = -(2.0f * far * near) / (far - near); | |
} | |
void mat4_lookat(float* m, Vec3 eye, Vec3 center, Vec3 up) { | |
Vec3 f = {center.x - eye.x, center.y - eye.y, center.z - eye.z}; | |
float len = sqrtf(f.x * f.x + f.y * f.y + f.z * f.z); | |
f.x /= len; f.y /= len; f.z /= len; | |
Vec3 s = {f.y * up.z - f.z * up.y, f.z * up.x - f.x * up.z, f.x * up.y - f.y * up.x}; | |
len = sqrtf(s.x * s.x + s.y * s.y + s.z * s.z); | |
s.x /= len; s.y /= len; s.z /= len; | |
Vec3 u = {s.y * f.z - s.z * f.y, s.z * f.x - s.x * f.z, s.x * f.y - s.y * f.x}; | |
mat4_identity(m); | |
m[0] = s.x; m[4] = s.y; m[8] = s.z; | |
m[1] = u.x; m[5] = u.y; m[9] = u.z; | |
m[2] = -f.x; m[6] = -f.y; m[10] = -f.z; | |
m[12] = -(s.x * eye.x + s.y * eye.y + s.z * eye.z); | |
m[13] = -(u.x * eye.x + u.y * eye.y + u.z * eye.z); | |
m[14] = -(-f.x * eye.x - f.y * eye.y - f.z * eye.z); | |
} | |
// Update camera direction based on yaw and pitch | |
void update_camera_direction(Camera* cam) { | |
float yaw_rad = cam->yaw * 3.14159f / 180.0f; | |
float pitch_rad = cam->pitch * 3.14159f / 180.0f; | |
cam->front.x = cosf(yaw_rad) * cosf(pitch_rad); | |
cam->front.y = sinf(pitch_rad); | |
cam->front.z = sinf(yaw_rad) * cosf(pitch_rad); | |
float len = sqrtf(cam->front.x * cam->front.x + cam->front.y * cam->front.y + cam->front.z * cam->front.z); | |
cam->front.x /= len; cam->front.y /= len; cam->front.z /= len; | |
Vec3 world_up = {0.0f, 1.0f, 0.0f}; | |
cam->right = (Vec3){ | |
cam->front.y * world_up.z - cam->front.z * world_up.y, | |
cam->front.z * world_up.x - cam->front.x * world_up.z, | |
cam->front.x * world_up.y - cam->front.y * world_up.x | |
}; | |
len = sqrtf(cam->right.x * cam->right.x + cam->right.y * cam->right.y + cam->right.z * cam->right.z); | |
cam->right.x /= len; cam->right.y /= len; cam->right.z /= len; | |
cam->up = (Vec3){ | |
cam->right.y * cam->front.z - cam->right.z * cam->front.y, | |
cam->right.z * cam->front.x - cam->right.x * cam->front.z, | |
cam->right.x * cam->front.y - cam->right.y * cam->front.x | |
}; | |
} | |
void init() { | |
if (SDL_Init(SDL_INIT_VIDEO) < 0) { | |
printf("SDL_Init failed: %s\n", SDL_GetError()); | |
exit(1); | |
} | |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); | |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); | |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); | |
window = SDL_CreateWindow("SDL3 OpenGL", 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); | |
if (!window) { | |
printf("Window creation failed: %s\n", SDL_GetError()); | |
SDL_Quit(); | |
exit(1); | |
} | |
gl_context = SDL_GL_CreateContext(window); | |
if (!gl_context) { | |
printf("GL context creation failed: %s\n", SDL_GetError()); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
exit(1); | |
} | |
SDL_GL_MakeCurrent(window, gl_context); | |
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { | |
printf("Failed to initialize GLAD\n"); | |
SDL_GL_DestroyContext(gl_context); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
exit(1); | |
} | |
camera.position = (Vec3){0.0f, 0.0f, 3.0f}; | |
camera.front = (Vec3){0.0f, 0.0f, -1.0f}; | |
camera.up = (Vec3){0.0f, 1.0f, 0.0f}; | |
camera.right = (Vec3){1.0f, 0.0f, 0.0f}; | |
camera.yaw = -90.0f; | |
camera.pitch = 0.0f; | |
update_camera_direction(&camera); | |
glEnable(GL_DEPTH_TEST); | |
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); | |
glCompileShader(vertexShader); | |
GLint success; | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) { | |
char infoLog[512]; | |
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | |
printf("Vertex shader compilation failed: %s\n", infoLog); | |
} | |
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); | |
glCompileShader(fragmentShader); | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
if (!success) { | |
char infoLog[512]; | |
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); | |
printf("Fragment shader compilation failed: %s\n", infoLog); | |
} | |
shaderProgram = glCreateProgram(); | |
glAttachShader(shaderProgram, vertexShader); | |
glAttachShader(shaderProgram, fragmentShader); | |
glLinkProgram(shaderProgram); | |
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); | |
if (!success) { | |
char infoLog[512]; | |
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); | |
printf("Shader program linking failed: %s\n", infoLog); | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO); | |
glBindVertexArray(VAO); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); | |
glEnableVertexAttribArray(0); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindVertexArray(0); | |
} | |
void handle_input(float deltaTime) { | |
SDL_Event event; | |
const Uint8* keyboard_state = SDL_GetKeyboardState(NULL); | |
while (SDL_PollEvent(&event)) { | |
if (event.type == SDL_EVENT_QUIT) running = false; | |
if (event.type == SDL_EVENT_KEY_DOWN) { | |
if (event.key.key == SDLK_ESCAPE) { | |
mouse_captured = false; | |
if (SDL_SetWindowRelativeMouseMode(window, false) != 0) { | |
printf("Failed to unset relative mouse mode: %s\n", SDL_GetError()); | |
} | |
} | |
} | |
if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && !mouse_captured) { | |
mouse_captured = true; | |
if (SDL_SetWindowRelativeMouseMode(window, true) != 0) { | |
printf("Failed to set relative mouse mode: %s\n", SDL_GetError()); | |
} | |
} | |
if (event.type == SDL_EVENT_MOUSE_MOTION && mouse_captured) { | |
float sensitivity = 0.1f; | |
camera.yaw += event.motion.xrel * sensitivity; | |
camera.pitch -= event.motion.yrel * sensitivity; | |
if (camera.pitch > 89.0f) camera.pitch = 89.0f; | |
if (camera.pitch < -89.0f) camera.pitch = -89.0f; | |
update_camera_direction(&camera); | |
} | |
} | |
float cameraSpeed = 2.5f * deltaTime; | |
if (keyboard_state[SDL_SCANCODE_W]) { | |
camera.position.x += cameraSpeed * camera.front.x; | |
camera.position.y += cameraSpeed * camera.front.y; | |
camera.position.z += cameraSpeed * camera.front.z; | |
} | |
if (keyboard_state[SDL_SCANCODE_S]) { | |
camera.position.x -= cameraSpeed * camera.front.x; | |
camera.position.y -= cameraSpeed * camera.front.y; | |
camera.position.z -= cameraSpeed * camera.front.z; | |
} | |
if (keyboard_state[SDL_SCANCODE_A]) { | |
camera.position.x -= cameraSpeed * camera.right.x; | |
camera.position.y -= cameraSpeed * camera.right.y; | |
camera.position.z -= cameraSpeed * camera.right.z; | |
} | |
if (keyboard_state[SDL_SCANCODE_D]) { | |
camera.position.x += cameraSpeed * camera.right.x; | |
camera.position.y += cameraSpeed * camera.right.y; | |
camera.position.z += cameraSpeed * camera.right.z; | |
} | |
} | |
void render() { | |
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glUseProgram(shaderProgram); | |
float model[16], view[16], projection[16]; | |
mat4_identity(model); | |
Vec3 center = { | |
camera.position.x + camera.front.x, | |
camera.position.y + camera.front.y, | |
camera.position.z + camera.front.z | |
}; | |
mat4_lookat(view, camera.position, center, camera.up); | |
mat4_perspective(projection, 45.0f * 3.14159f / 180.0f, 800.0f / 600.0f, 0.1f, 100.0f); | |
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, model); | |
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, view); | |
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, projection); | |
Vec3 lightColor = {1.0f, 1.0f, 1.0f}; | |
glUniform3f(glGetUniformLocation(shaderProgram, "lightColor"), | |
lightColor.x, lightColor.y, lightColor.z); | |
glBindVertexArray(VAO); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
glBindVertexArray(0); | |
SDL_GL_SwapWindow(window); | |
} | |
void cleanup() { | |
glDeleteVertexArrays(1, &VAO); | |
glDeleteBuffers(1, &VBO); | |
glDeleteProgram(shaderProgram); | |
SDL_GL_DestroyContext(gl_context); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
} | |
int main(int argc, char* argv[]) { | |
init(); | |
Uint64 previous = SDL_GetTicks(); | |
while (running) { | |
Uint64 current = SDL_GetTicks(); | |
float deltaTime = (current - previous) / 1000.0f; | |
previous = current; | |
handle_input(deltaTime); | |
render(); | |
} | |
cleanup(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment