opengl-cpp/src/sdl.cpp

190 lines
5.3 KiB
C++
Raw Normal View History

2025-01-05 13:17:26 +00:00
#include <GL/glew.h> // Include GLEW before <SDL2/SDL.h>?
2025-01-05 01:30:18 +00:00
#include "sdl.hpp"
#include <iostream>
SdlWindow::SdlWindow(const char* title, int width, int height)
: m_window(nullptr),
m_renderer(nullptr),
m_isRunning(false),
m_isFullscreen(false),
m_width(width),
2025-01-05 02:27:36 +00:00
m_height(height),
2025-01-05 13:17:26 +00:00
m_glContext(nullptr),
m_windowedWidth(width),
m_windowedHeight(height)
2025-01-05 01:30:18 +00:00
{
2025-01-05 02:27:36 +00:00
// 1. Set attributes
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);
2025-01-05 01:30:18 +00:00
2025-01-05 02:41:40 +00:00
// 2. Create the window with OpenGL flag
m_window = SDL_CreateWindow(title,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
width,
height,
2025-01-05 02:52:38 +00:00
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN| SDL_WINDOW_RESIZABLE);
2025-01-05 02:41:40 +00:00
2025-01-05 01:30:18 +00:00
if (!m_window) {
std::cerr << "Failed to create window: " << SDL_GetError() << std::endl;
return;
}
2025-01-05 02:41:40 +00:00
// 3. Create OpenGL context
m_glContext = SDL_GL_CreateContext(m_window);
if (!m_glContext) {
std::cerr << "Failed to create GL context: " << SDL_GetError() << std::endl;
return;
}
// 4. Optionally init GLEW (if not on macOS core profile)
#ifndef __APPLE__
glewExperimental = GL_TRUE;
2025-01-05 13:17:26 +00:00
GLenum glewErr = glewInit();
2025-01-05 02:41:40 +00:00
if (glewInit() != GLEW_OK) {
2025-01-05 13:17:26 +00:00
std::cerr << "Failed to init GLEW" << glewGetErrorString(glewErr) << std::endl;
2025-01-05 02:41:40 +00:00
return;
2025-01-05 01:30:18 +00:00
}
2025-01-05 13:17:26 +00:00
glGetError();
2025-01-05 02:41:40 +00:00
#endif
2025-01-05 01:30:18 +00:00
2025-01-05 02:41:40 +00:00
// 5. Set vsync (optional)
SDL_GL_SetSwapInterval(1);
// 6. Mark as running
m_isRunning = true;
2025-01-05 13:51:33 +00:00
2025-01-05 14:12:28 +00:00
float positions[6] = { // vertex for a triangle
//x,y
2025-01-05 13:51:33 +00:00
-0.5f, -0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
2025-01-05 14:12:28 +00:00
//vertex buffer
2025-01-05 13:51:33 +00:00
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer); //select buffer called 'buffer'
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); // assigne buffer size, static as we use many times, but does not change
2025-01-05 14:12:28 +00:00
//vertext attributes / layout
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
2025-01-05 01:30:18 +00:00
}
SdlWindow::~SdlWindow() {
2025-01-05 02:41:40 +00:00
// If using SDL Renderer, destroy it. But if youre purely using OpenGL, you might remove it.
2025-01-05 01:30:18 +00:00
if (m_renderer) {
2025-01-05 02:41:40 +00:00
SDL_DestroyRenderer(m_renderer);
m_renderer = nullptr;
2025-01-05 01:30:18 +00:00
}
2025-01-05 02:41:40 +00:00
// Delete the OpenGL context
if (m_glContext) {
SDL_GL_DeleteContext(m_glContext);
m_glContext = nullptr;
}
2025-01-05 01:30:18 +00:00
if (m_window) {
2025-01-05 02:41:40 +00:00
SDL_DestroyWindow(m_window);
m_window = nullptr;
2025-01-05 01:30:18 +00:00
}
2025-01-05 02:41:40 +00:00
2025-01-05 01:30:18 +00:00
SDL_Quit();
}
2025-01-05 02:41:40 +00:00
2025-01-05 01:30:18 +00:00
void SdlWindow::run() {
while (m_isRunning) {
processEvents();
update();
render();
}
}
void SdlWindow::processEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
m_isRunning = false;
}
// Handle other events (keyboard, mouse, etc.) here if needed
else if (event.type == SDL_KEYDOWN) {
// Check if the key pressed is Enter/Return
if (event.key.keysym.sym == SDLK_RETURN) {
std::cout << "input detected" << std::endl;
}
if (event.key.keysym.sym == SDLK_SPACE) {
std::cout << "Full screen togled!" << std::endl;
setFullscreen(!m_isFullscreen);
}
if (event.key.keysym.sym == SDLK_ESCAPE) {
std::cout << "Bye!" << std::endl;
m_isRunning = false; //exit application
}
}
2025-01-05 02:52:38 +00:00
else if (event.type == SDL_WINDOWEVENT) {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
// SDL gives the new width/height in event.window.data1/data2
int newWidth = event.window.data1;
int newHeight = event.window.data2;
// Update your internal width/height (if you keep track)
m_width = newWidth;
m_height = newHeight;
2025-01-05 13:17:26 +00:00
// If we are in windowed mode, update the "windowed" size.
if (!m_isFullscreen) {
m_windowedWidth = newWidth;
m_windowedHeight = newHeight;
}
2025-01-05 02:52:38 +00:00
// Update the OpenGL viewport
glViewport(0, 0, newWidth, newHeight);
// (Optional) If you have a projection matrix, update it here as well
// e.g., recalc the aspect ratio for a perspective projection
}
}
2025-01-05 01:30:18 +00:00
}
}
void SdlWindow::update() {
// Update game/application logic here
}
void SdlWindow::render() {
2025-01-05 02:41:40 +00:00
// Use GL calls instead of SDLs renderer
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
2025-01-05 01:30:18 +00:00
2025-01-05 02:41:40 +00:00
// TODO: Draw with OpenGL here (shaders, triangles, etc.)
2025-01-05 13:51:33 +00:00
glDrawArrays(GL_TRIANGLES, 0, 3);
2025-01-05 01:30:18 +00:00
2025-01-05 02:41:40 +00:00
// Swap buffers
SDL_GL_SwapWindow(m_window);
2025-01-05 01:30:18 +00:00
}
void SdlWindow::setFullscreen(bool fullscreen) {
if (m_window) {
m_isFullscreen = fullscreen;
if (m_isFullscreen) {
2025-01-05 13:17:26 +00:00
// Going TO fullscreen:
// (Optional) store the current size again, in case it changed
m_windowedWidth = m_width;
m_windowedHeight = m_height;
2025-01-05 01:30:18 +00:00
SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
} else {
2025-01-05 13:17:26 +00:00
// Returning FROM fullscreen:
2025-01-05 01:30:18 +00:00
SDL_SetWindowFullscreen(m_window, 0); // return to windowed
2025-01-05 13:17:26 +00:00
// Now restore the windows old size
SDL_SetWindowSize(m_window, m_windowedWidth, m_windowedHeight);
// Update m_width, m_height so they reflect the new (restored) size
m_width = m_windowedWidth;
m_height = m_windowedHeight;
2025-01-05 01:30:18 +00:00
}
}
}
2025-01-05 13:17:26 +00:00