From 7a83b463c22074757ba217005a47fbce34c75621 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Fri, 16 Apr 2021 19:42:02 +0300 Subject: [PATCH] win_opengl: Split shader loading to it's own file. --- src/include/86box/win_opengl_glslp.h | 23 +++ src/win/CMakeLists.txt | 2 +- src/win/Makefile.mingw | 2 +- src/win/win_opengl.c | 192 +---------------------- src/win/win_opengl_glslp.c | 224 +++++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 193 deletions(-) create mode 100644 src/include/86box/win_opengl_glslp.h create mode 100644 src/win/win_opengl_glslp.c diff --git a/src/include/86box/win_opengl_glslp.h b/src/include/86box/win_opengl_glslp.h new file mode 100644 index 000000000..1a9e5a9ca --- /dev/null +++ b/src/include/86box/win_opengl_glslp.h @@ -0,0 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header file for shader file parser. + * + * Authors: Teemu Korhonen + * + * Copyright 2021 Teemu Korhonen + */ +#ifndef WIN_OPENGL_GLSLP_H +#define WIN_OPENGL_GLSLP_H + +#include + +GLuint load_custom_shaders(); +GLuint load_default_shaders(); + +#endif /*!WIN_OPENGL_GLSLP_H*/ \ No newline at end of file diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 07e9a8315..1377abda7 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -20,7 +20,7 @@ add_library(plat OBJECT win.c win_dynld.c win_thread.c win_cdrom.c add_library(ui OBJECT win_ui.c win_stbar.c win_sdl.c win_dialog.c win_about.c win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c - win_jsconf.c win_media_menu.c 86Box.rc glad.c win_opengl.c) + win_jsconf.c win_media_menu.c 86Box.rc glad.c win_opengl.c win_opengl_glslp.c) if(MSVC) # MSVC complains when we include the manifest from 86Box.rc... diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b8d6ecbcd..9716c3915 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -451,7 +451,7 @@ ifeq ($(WX), y) UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o else UIOBJ := win_ui.o win_stbar.o \ - win_sdl.o win_opengl.o glad.o \ + win_sdl.o win_opengl.o win_opengl_glslp.o glad.o \ win_dialog.o win_about.o \ win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o \ win_new_floppy.o win_jsconf.o win_media_menu.o diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 3d320b7bb..c469d9397 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -8,16 +8,12 @@ * * Rendering module for OpenGL * - * NOTE: This is very much still a work-in-progress. - * Expect missing functionality, hangs and bugs. - * * TODO: More shader features * - scaling * - multipass * - previous frames * (UI) options * More error handling - * ... * * Authors: Teemu Korhonen * @@ -37,20 +33,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #define UNICODE #include #include #include #include -#include - #include <86box/86box.h> #include <86box/plat.h> #include <86box/video.h> #include <86box/win.h> #include <86box/win_opengl.h> +#include <86box/win_opengl_glslp.h> static const int INIT_WIDTH = 640; static const int INIT_HEIGHT = 400; @@ -146,190 +140,6 @@ typedef struct int* fullscreen; } winmessage_data; -/** - * @brief Default vertex shader. -*/ -static const GLchar* vertex_shader = "#version 330 core\n\ -in vec2 VertexCoord;\n\ -in vec2 TexCoord;\n\ -out vec2 tex;\n\ -void main(){\n\ - gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ - tex = TexCoord;\n\ -}\n"; - -/** - * @brief Default fragment shader. - */ -static const GLchar* fragment_shader = "#version 330 core\n\ -in vec2 tex;\n\ -uniform sampler2D texsampler;\n\ -void main() {\n\ - gl_FragColor = texture(texsampler, tex);\n\ -}\n"; - -/** - * @brief Reads a whole file into a null terminated string. - * @param Path Path to the file relative to executable path. - * @return Pointer to the string or NULL on error. Remember to free() after use. -*/ -static char* read_file_to_string(const char* path) -{ - char* full_path = (char*)malloc(sizeof(char) * (strlen(path) + strlen(exe_path) + 1)); - - plat_append_filename(full_path, exe_path, path); - - FILE* file_handle = plat_fopen(full_path, "rb"); - - free(full_path); - - if (file_handle != NULL) - { - /* get file size */ - fseek(file_handle, 0, SEEK_END); - long file_size = ftell(file_handle); - fseek(file_handle, 0, SEEK_SET); - - /* read to buffer and close */ - char* content = (char*)malloc(sizeof(char) * (file_size + 1)); - size_t length = fread(content, sizeof(char), file_size, file_handle); - fclose(file_handle); - content[length] = 0; - - return content; - } - return NULL; -} - -/** - * @brief Compile custom shaders into a program. - * @return Shader program identifier. -*/ -static GLuint load_custom_shaders() -{ - GLint status = GL_FALSE; - int info_log_length; - - /* TODO: get path from config */ - char* shader = read_file_to_string("shaders/shader.glsl"); - - if (shader != NULL) - { - int success = 1; - - const char* vertex_sources[2] = { "#define VERTEX\n", shader }; - const char* fragment_sources[2] = { "#define FRAGMENT\n", shader }; - - GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); - GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertex_id, 2, vertex_sources, NULL); - glCompileShader(vertex_id); - glGetShaderiv(vertex_id, GL_COMPILE_STATUS, &status); - - if (status == GL_FALSE) - { - glGetShaderiv(vertex_id, GL_INFO_LOG_LENGTH, &info_log_length); - - GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); - - glGetShaderInfoLog(vertex_id, info_log_length, NULL, info_log_text); - - /* TODO: error logging */ - - free(info_log_text); - - success = 0; - } - - glShaderSource(fragment_id, 2, fragment_sources, NULL); - glCompileShader(fragment_id); - glGetShaderiv(fragment_id, GL_COMPILE_STATUS, &status); - - if (status == GL_FALSE) - { - glGetShaderiv(fragment_id, GL_INFO_LOG_LENGTH, &info_log_length); - - GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); - - glGetShaderInfoLog(fragment_id, info_log_length, NULL, info_log_text); - - /* TODO: error logging */ - - free(info_log_text); - - success = 0; - } - - free(shader); - - GLuint prog_id = 0; - - if (success) - { - prog_id = glCreateProgram(); - - glAttachShader(prog_id, vertex_id); - glAttachShader(prog_id, fragment_id); - glLinkProgram(prog_id); - glGetProgramiv(prog_id, GL_LINK_STATUS, &status); - - if (status == GL_FALSE) - { - glGetProgramiv(prog_id, GL_INFO_LOG_LENGTH, &info_log_length); - - GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); - - glGetProgramInfoLog(prog_id, info_log_length, NULL, info_log_text); - - /* TODO: error logging */ - - free(info_log_text); - } - - glDetachShader(prog_id, vertex_id); - glDetachShader(prog_id, fragment_id); - } - - glDeleteShader(vertex_id); - glDeleteShader(fragment_id); - - return prog_id; - } - return 0; -} - -/** - * @brief Compile default shaders into a program. - * @return Shader program identifier. -*/ -static GLuint load_default_shaders() -{ - GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); - GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertex_id, 1, &vertex_shader, NULL); - glCompileShader(vertex_id); - - glShaderSource(fragment_id, 1, &fragment_shader, NULL); - glCompileShader(fragment_id); - - GLuint prog_id = glCreateProgram(); - - glAttachShader(prog_id, vertex_id); - glAttachShader(prog_id, fragment_id); - - glLinkProgram(prog_id); - - glDetachShader(prog_id, vertex_id); - glDetachShader(prog_id, fragment_id); - - glDeleteShader(vertex_id); - glDeleteShader(fragment_id); - - return prog_id; -} - /** * @brief Set or unset OpenGL context window as a child window. * diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c new file mode 100644 index 000000000..adfaa9cc0 --- /dev/null +++ b/src/win/win_opengl_glslp.c @@ -0,0 +1,224 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * File parser for .glslp and .glsl shader files + * in the format of libretro. + * + * TODO: Read .glslp files for multipass shaders and settings. + * + * Authors: Teemu Korhonen + * + * Copyright 2021 Teemu Korhonen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include + +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/win_opengl_glslp.h> + + /** + * @brief Default vertex shader. + */ +static const GLchar* vertex_shader = "#version 330 core\n\ +in vec2 VertexCoord;\n\ +in vec2 TexCoord;\n\ +out vec2 tex;\n\ +void main(){\n\ + gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ + tex = TexCoord;\n\ +}\n"; + +/** + * @brief Default fragment shader. + */ +static const GLchar* fragment_shader = "#version 330 core\n\ +in vec2 tex;\n\ +uniform sampler2D texsampler;\n\ +void main() {\n\ + gl_FragColor = texture(texsampler, tex);\n\ +}\n"; + +/** + * @brief Reads a whole file into a null terminated string. + * @param Path Path to the file relative to executable path. + * @return Pointer to the string or NULL on error. Remember to free() after use. +*/ +static char* read_file_to_string(const char* path) +{ + char* full_path = (char*)malloc(sizeof(char) * (strlen(path) + strlen(exe_path) + 1)); + + plat_append_filename(full_path, exe_path, path); + + FILE* file_handle = plat_fopen(full_path, "rb"); + + free(full_path); + + if (file_handle != NULL) + { + /* get file size */ + fseek(file_handle, 0, SEEK_END); + long file_size = ftell(file_handle); + fseek(file_handle, 0, SEEK_SET); + + /* read to buffer and close */ + char* content = (char*)malloc(sizeof(char) * (file_size + 1)); + size_t length = fread(content, sizeof(char), file_size, file_handle); + fclose(file_handle); + content[length] = 0; + + return content; + } + return NULL; +} + +/** + * @brief Compile custom shaders into a program. + * @return Shader program identifier. +*/ +GLuint load_custom_shaders() +{ + GLint status = GL_FALSE; + int info_log_length; + + /* TODO: get path from config */ + char* shader = read_file_to_string("shaders/shader.glsl"); + + if (shader != NULL) + { + int success = 1; + + const char* vertex_sources[2] = { "#define VERTEX\n", shader }; + const char* fragment_sources[2] = { "#define FRAGMENT\n", shader }; + + GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); + GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); + + glShaderSource(vertex_id, 2, vertex_sources, NULL); + glCompileShader(vertex_id); + glGetShaderiv(vertex_id, GL_COMPILE_STATUS, &status); + + if (status == GL_FALSE) + { + glGetShaderiv(vertex_id, GL_INFO_LOG_LENGTH, &info_log_length); + + GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); + + glGetShaderInfoLog(vertex_id, info_log_length, NULL, info_log_text); + + /* TODO: error logging */ + + free(info_log_text); + + success = 0; + } + + glShaderSource(fragment_id, 2, fragment_sources, NULL); + glCompileShader(fragment_id); + glGetShaderiv(fragment_id, GL_COMPILE_STATUS, &status); + + if (status == GL_FALSE) + { + glGetShaderiv(fragment_id, GL_INFO_LOG_LENGTH, &info_log_length); + + GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); + + glGetShaderInfoLog(fragment_id, info_log_length, NULL, info_log_text); + + /* TODO: error logging */ + + free(info_log_text); + + success = 0; + } + + free(shader); + + GLuint prog_id = 0; + + if (success) + { + prog_id = glCreateProgram(); + + glAttachShader(prog_id, vertex_id); + glAttachShader(prog_id, fragment_id); + glLinkProgram(prog_id); + glGetProgramiv(prog_id, GL_LINK_STATUS, &status); + + if (status == GL_FALSE) + { + glGetProgramiv(prog_id, GL_INFO_LOG_LENGTH, &info_log_length); + + GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); + + glGetProgramInfoLog(prog_id, info_log_length, NULL, info_log_text); + + /* TODO: error logging */ + + free(info_log_text); + } + + glDetachShader(prog_id, vertex_id); + glDetachShader(prog_id, fragment_id); + } + + glDeleteShader(vertex_id); + glDeleteShader(fragment_id); + + return prog_id; + } + return 0; +} + +/** + * @brief Compile default shaders into a program. + * @return Shader program identifier. +*/ +GLuint load_default_shaders() +{ + GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); + GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); + + glShaderSource(vertex_id, 1, &vertex_shader, NULL); + glCompileShader(vertex_id); + + glShaderSource(fragment_id, 1, &fragment_shader, NULL); + glCompileShader(fragment_id); + + GLuint prog_id = glCreateProgram(); + + glAttachShader(prog_id, vertex_id); + glAttachShader(prog_id, fragment_id); + + glLinkProgram(prog_id); + + glDetachShader(prog_id, vertex_id); + glDetachShader(prog_id, fragment_id); + + glDeleteShader(vertex_id); + glDeleteShader(fragment_id); + + return prog_id; +} \ No newline at end of file