Added GLFW3 support for the software renderer

A few things need cleaning-up
This commit is contained in:
Clownacy 2020-04-09 19:29:45 +01:00
parent 0582fa93d1
commit 1f06027403
6 changed files with 253 additions and 52 deletions

View file

@ -355,10 +355,13 @@ elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "OpenGLES2")
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()
@ -564,6 +567,11 @@ if(BACKEND_RENDERER MATCHES "OpenGLES2")
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()
#######################
# Resource conversion #

View file

@ -0,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);
}

View file

@ -2,6 +2,5 @@
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#undef GLFW_INCLUDE_NONE
extern GLFWwindow *window;

View file

@ -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 @@ typedef struct RenderBackend_Glyph
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_HandleRenderTargetLoss(void)
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);
}

View file

@ -0,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);
}

View file

@ -0,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);