win_opengl: Split shader loading to it's own file.
This commit is contained in:
23
src/include/86box/win_opengl_glslp.h
Normal file
23
src/include/86box/win_opengl_glslp.h
Normal file
@@ -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 <glad/glad.h>
|
||||||
|
|
||||||
|
GLuint load_custom_shaders();
|
||||||
|
GLuint load_default_shaders();
|
||||||
|
|
||||||
|
#endif /*!WIN_OPENGL_GLSLP_H*/
|
@@ -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
|
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_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)
|
if(MSVC)
|
||||||
# MSVC complains when we include the manifest from 86Box.rc...
|
# MSVC complains when we include the manifest from 86Box.rc...
|
||||||
|
@@ -451,7 +451,7 @@ ifeq ($(WX), y)
|
|||||||
UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o
|
UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o
|
||||||
else
|
else
|
||||||
UIOBJ := win_ui.o win_stbar.o \
|
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_dialog.o win_about.o \
|
||||||
win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.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
|
win_new_floppy.o win_jsconf.o win_media_menu.o
|
||||||
|
@@ -8,16 +8,12 @@
|
|||||||
*
|
*
|
||||||
* Rendering module for OpenGL
|
* Rendering module for OpenGL
|
||||||
*
|
*
|
||||||
* NOTE: This is very much still a work-in-progress.
|
|
||||||
* Expect missing functionality, hangs and bugs.
|
|
||||||
*
|
|
||||||
* TODO: More shader features
|
* TODO: More shader features
|
||||||
* - scaling
|
* - scaling
|
||||||
* - multipass
|
* - multipass
|
||||||
* - previous frames
|
* - previous frames
|
||||||
* (UI) options
|
* (UI) options
|
||||||
* More error handling
|
* More error handling
|
||||||
* ...
|
|
||||||
*
|
*
|
||||||
* Authors: Teemu Korhonen
|
* Authors: Teemu Korhonen
|
||||||
*
|
*
|
||||||
@@ -37,20 +33,18 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_syswm.h>
|
#include <SDL2/SDL_syswm.h>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <86box/86box.h>
|
#include <86box/86box.h>
|
||||||
#include <86box/plat.h>
|
#include <86box/plat.h>
|
||||||
#include <86box/video.h>
|
#include <86box/video.h>
|
||||||
#include <86box/win.h>
|
#include <86box/win.h>
|
||||||
#include <86box/win_opengl.h>
|
#include <86box/win_opengl.h>
|
||||||
|
#include <86box/win_opengl_glslp.h>
|
||||||
|
|
||||||
static const int INIT_WIDTH = 640;
|
static const int INIT_WIDTH = 640;
|
||||||
static const int INIT_HEIGHT = 400;
|
static const int INIT_HEIGHT = 400;
|
||||||
@@ -146,190 +140,6 @@ typedef struct
|
|||||||
int* fullscreen;
|
int* fullscreen;
|
||||||
} winmessage_data;
|
} 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.
|
* @brief Set or unset OpenGL context window as a child window.
|
||||||
*
|
*
|
||||||
|
224
src/win/win_opengl_glslp.c
Normal file
224
src/win/win_opengl_glslp.c
Normal file
@@ -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 <glad/glad.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
Reference in New Issue
Block a user