ref: 1f06027403aef46e13fe093ef854605cd7647ba5
parent: 0582fa93d142a8929030c61c6f52c8837a6ca8a6
author: Clownacy <[email protected]>
date: Thu Apr 9 15:29:45 EDT 2020
Added GLFW3 support for the software renderer A few things need cleaning-up
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -355,10 +355,13 @@
elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "SDLTexture")
elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "SDLSurface")
elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "Software")
+ target_sources(CSE2 PRIVATE "src/Backends/SDL2/Window-Software.cpp")
elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "OpenGL3")
target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-OpenGL3.cpp")
elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "OpenGLES2")
target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-OpenGLES2.cpp")
+elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "Software")
+ target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-Software.cpp")
else()
message(FATAL_ERROR "Invalid BACKEND_PLATFORM/BACKEND_RENDERER combination")
endif()
@@ -562,6 +565,11 @@
find_package(OpenGLES2 REQUIRED)
target_include_directories(CSE2 PRIVATE ${OPENGLES2_INCLUDE_DIR})
target_link_libraries(CSE2 PRIVATE ${OPENGLES2_LIBRARIES})
+endif()
+
+if(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "Software")
+ find_package(OpenGL REQUIRED)
+ target_link_libraries(CSE2 PRIVATE OpenGL::GL)
endif()
--- /dev/null
+++ b/src/Backends/GLFW3/Window-Software.cpp
@@ -1,0 +1,151 @@
+#include "../Window-Software.h"
+#include "Window.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#if defined(__APPLE__)
+ #include <OpenGL/gl.h>
+#else
+ #include <GL/gl.h>
+#endif
+#include <GLFW/glfw3.h>
+
+#include "../../WindowsWrapper.h"
+
+#include "../Misc.h"
+
+GLFWwindow *window;
+
+static unsigned char *framebuffer;
+static int framebuffer_width;
+static int framebuffer_height;
+
+static float framebuffer_x_ratio;
+static float framebuffer_y_ratio;
+
+static GLuint screen_texture_id;
+
+unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, BOOL fullscreen, size_t *pitch)
+{
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+
+ framebuffer_width = screen_width;
+ framebuffer_height = screen_height;
+
+ GLFWmonitor *monitor = NULL;
+
+ if (fullscreen)
+ {
+ monitor = glfwGetPrimaryMonitor();
+
+ if (monitor != NULL)
+ {
+ const GLFWvidmode *mode = glfwGetVideoMode(monitor);
+
+ screen_width = mode->width;
+ screen_height = mode->height;
+ }
+ }
+
+ window = glfwCreateWindow(screen_width, screen_height, window_title, monitor, NULL);
+
+ if (window != NULL)
+ {
+ glfwMakeContextCurrent(window);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glEnable(GL_TEXTURE_2D);
+
+ // Create screen texture
+ glGenTextures(1, &screen_texture_id);
+ glBindTexture(GL_TEXTURE_2D, screen_texture_id);
+
+ int framebuffer_texture_width = 1;
+ while (framebuffer_texture_width < framebuffer_width)
+ framebuffer_texture_width <<= 1;
+
+ int framebuffer_texture_height = 1;
+ while (framebuffer_texture_height < framebuffer_height)
+ framebuffer_texture_height <<= 1;
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, framebuffer_texture_width, framebuffer_texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ framebuffer_x_ratio = (float)framebuffer_width / framebuffer_texture_width;
+ framebuffer_y_ratio = (float)framebuffer_height / framebuffer_texture_height;
+
+ framebuffer = (unsigned char*)malloc(framebuffer_width * framebuffer_height * 3);
+
+ *pitch = framebuffer_width * 3;
+
+ Backend_PostWindowCreation();
+
+ return framebuffer;
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
+ }
+
+ return NULL;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ free(framebuffer);
+ glDeleteTextures(1, &screen_texture_id);
+ glfwDestroyWindow(window);
+}
+
+void WindowBackend_Software_Display(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer_width, framebuffer_height, GL_RGB, GL_UNSIGNED_BYTE, framebuffer);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(0.0f, framebuffer_y_ratio);
+ glVertex2f(-1.0f, -1.0f);
+ glTexCoord2f(framebuffer_x_ratio, framebuffer_y_ratio);
+ glVertex2f(1.0f, -1.0f);
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(-1.0f, 1.0f);
+ glTexCoord2f(framebuffer_x_ratio, 0.0f);
+ glVertex2f(1.0f, 1.0f);
+ glEnd();
+
+ glfwSwapBuffers(window);
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+ // Do some viewport trickery, to fit the framebuffer in the center of the screen
+ GLint viewport_x;
+ GLint viewport_y;
+ GLsizei viewport_width;
+ GLsizei viewport_height;
+
+ if (width > height)
+ {
+ viewport_y = 0;
+ viewport_height = height;
+
+ viewport_width = framebuffer_width * ((float)height / (float)framebuffer_height);
+ viewport_x = (width - viewport_width) / 2;
+ }
+ else
+ {
+ viewport_x = 0;
+ viewport_width = width;
+
+ viewport_height = framebuffer_height * ((float)width / (float)framebuffer_width);
+ viewport_y = (height - viewport_height) / 2;
+ }
+
+ glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
+}
--- a/src/Backends/GLFW3/Window.h
+++ b/src/Backends/GLFW3/Window.h
@@ -2,6 +2,5 @@
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
-#undef GLFW_INCLUDE_NONE
extern GLFWwindow *window;
--- a/src/Backends/Rendering/Software.cpp
+++ b/src/Backends/Rendering/Software.cpp
@@ -4,12 +4,10 @@
#include <stdlib.h>
#include <string.h>
-#include "SDL.h"
-
#include "../../WindowsWrapper.h"
#include "../Misc.h"
-#include "../SDL2/Window.h"
+#include "../Window-Software.h"
#include "../../Attributes.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -30,64 +28,30 @@
unsigned int height;
} RenderBackend_Glyph;
-static SDL_Surface *window_sdlsurface;
-static SDL_Surface *framebuffer_sdlsurface;
static RenderBackend_Surface framebuffer;
static unsigned char glyph_colour_channels[3];
static RenderBackend_Surface *glyph_destination_surface;
-SDL_Window *window;
-
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
{
- window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, 0);
+ size_t pitch;
+ framebuffer.pixels = WindowBackend_Software_CreateWindow(window_title, screen_width, screen_height, fullscreen, &pitch);
+ framebuffer.width = screen_width;
+ framebuffer.height = screen_height;
+ framebuffer.pitch = pitch;
- if (window != NULL)
- {
- if (fullscreen)
- SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
-
- window_sdlsurface = SDL_GetWindowSurface(window);
-
- framebuffer_sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, window_sdlsurface->w, window_sdlsurface->h, 0, SDL_PIXELFORMAT_RGB24);
-
- if (framebuffer_sdlsurface != NULL)
- {
- framebuffer.pixels = (unsigned char*)framebuffer_sdlsurface->pixels;
- framebuffer.width = framebuffer_sdlsurface->w;
- framebuffer.height = framebuffer_sdlsurface->h;
- framebuffer.pitch = framebuffer_sdlsurface->pitch;
-
- Backend_PostWindowCreation();
-
- return &framebuffer;
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (software rendering backend)", "Could not create framebuffer surface");
- }
-
- SDL_DestroyWindow(window);
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (software rendering backend)", "Could not create window");
- }
-
- return NULL;
+ return &framebuffer;
}
void RenderBackend_Deinit(void)
{
- SDL_FreeSurface(framebuffer_sdlsurface);
- SDL_DestroyWindow(window);
+ WindowBackend_Software_DestroyWindow();
}
void RenderBackend_DrawScreen(void)
{
- SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL);
- SDL_UpdateWindowSurface(window);
+ WindowBackend_Software_Display();
}
RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height)
@@ -372,10 +336,5 @@
void RenderBackend_HandleWindowResize(unsigned int width, unsigned int height)
{
- (void)width;
- (void)height;
-
- // https://wiki.libsdl.org/SDL_GetWindowSurface
- // We need to fetch a new surface pointer
- window_sdlsurface = SDL_GetWindowSurface(window);
+ WindowBackend_Software_HandleWindowResize(width, height);
}
--- /dev/null
+++ b/src/Backends/SDL2/Window-Software.cpp
@@ -1,0 +1,74 @@
+#include "../Window-Software.h"
+#include "Window.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "SDL.h"
+
+#include "../../WindowsWrapper.h"
+
+#include "../Misc.h"
+
+SDL_Window *window;
+
+static SDL_Surface *window_sdlsurface;
+static SDL_Surface *framebuffer_sdlsurface;
+
+unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, BOOL fullscreen, size_t *pitch)
+{
+ window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, 0);
+
+ if (window != NULL)
+ {
+ if (fullscreen)
+ SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
+
+ window_sdlsurface = SDL_GetWindowSurface(window);
+
+ framebuffer_sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, window_sdlsurface->w, window_sdlsurface->h, 0, SDL_PIXELFORMAT_RGB24);
+
+ if (framebuffer_sdlsurface != NULL)
+ {
+ *pitch = framebuffer_sdlsurface->pitch;
+
+ Backend_PostWindowCreation();
+
+ return (unsigned char*)framebuffer_sdlsurface->pixels;
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (software rendering backend)", "Could not create framebuffer surface");
+ }
+
+ SDL_DestroyWindow(window);
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (software rendering backend)", "Could not create window");
+ }
+
+ return NULL;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ SDL_FreeSurface(framebuffer_sdlsurface);
+ SDL_DestroyWindow(window);
+}
+
+void WindowBackend_Software_Display(void)
+{
+ SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL);
+ SDL_UpdateWindowSurface(window);
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+ (void)width;
+ (void)height;
+
+ // https://wiki.libsdl.org/SDL_GetWindowSurface
+ // We need to fetch a new surface pointer
+ window_sdlsurface = SDL_GetWindowSurface(window);
+}
--- /dev/null
+++ b/src/Backends/Window-Software.h
@@ -1,0 +1,10 @@
+#pragma once
+
+#include <stddef.h>
+
+#include "../WindowsWrapper.h"
+
+unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, BOOL fullscreen, size_t *pitch);
+void WindowBackend_Software_DestroyWindow(void);
+void WindowBackend_Software_Display(void);
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height);