2018-05-09 05:09:57 +02:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "opengl.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Program
|
|
|
|
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
|
|
|
|
PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
|
|
|
|
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
|
|
|
|
PFNGLATTACHSHADERPROC glAttachShader = NULL;
|
|
|
|
PFNGLDETACHSHADERPROC glDetachShader = NULL;
|
|
|
|
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
|
|
|
|
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
|
|
|
|
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
|
|
|
|
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
|
|
|
|
PFNGLUNIFORM1IPROC glUniform1i = NULL;
|
|
|
|
PFNGLUNIFORM1IVPROC glUniform1iv = NULL;
|
|
|
|
PFNGLUNIFORM2IVPROC glUniform2iv = NULL;
|
|
|
|
PFNGLUNIFORM3IVPROC glUniform3iv = NULL;
|
|
|
|
PFNGLUNIFORM4IVPROC glUniform4iv = NULL;
|
|
|
|
PFNGLUNIFORM1FPROC glUniform1f = NULL;
|
|
|
|
PFNGLUNIFORM1FVPROC glUniform1fv = NULL;
|
|
|
|
PFNGLUNIFORM2FVPROC glUniform2fv = NULL;
|
|
|
|
PFNGLUNIFORM3FVPROC glUniform3fv = NULL;
|
|
|
|
PFNGLUNIFORM4FVPROC glUniform4fv = NULL;
|
2018-05-12 12:28:07 +02:00
|
|
|
PFNGLUNIFORM4FPROC glUniform4f = NULL;
|
2018-05-09 05:09:57 +02:00
|
|
|
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL;
|
|
|
|
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
|
|
|
|
PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL;
|
|
|
|
PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv = NULL;
|
|
|
|
PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv = NULL;
|
|
|
|
PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv = NULL;
|
|
|
|
PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv = NULL;
|
|
|
|
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
|
|
|
|
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = NULL;
|
|
|
|
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = NULL;
|
|
|
|
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = NULL;
|
|
|
|
|
|
|
|
PFNGLCREATESHADERPROC glCreateShader = NULL;
|
|
|
|
PFNGLDELETESHADERPROC glDeleteShader = NULL;
|
|
|
|
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
|
|
|
|
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
|
|
|
|
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
|
|
|
|
|
|
|
|
PFNGLGENBUFFERSPROC glGenBuffers = NULL;
|
|
|
|
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
|
|
|
|
PFNGLBUFFERDATAPROC glBufferData = NULL;
|
2018-05-31 03:38:33 +02:00
|
|
|
PFNGLMAPBUFFERPROC glMapBuffer = NULL;
|
|
|
|
PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL;
|
|
|
|
PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL;
|
2018-05-09 05:09:57 +02:00
|
|
|
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
|
2018-05-12 12:28:07 +02:00
|
|
|
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;
|
2018-05-20 06:27:53 +02:00
|
|
|
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
|
|
|
|
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
|
|
|
|
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
|
2018-05-09 05:09:57 +02:00
|
|
|
|
2018-05-20 01:11:37 +02:00
|
|
|
PFNGLACTIVETEXTUREPROC glActiveTexture = NULL;
|
2018-05-09 05:09:57 +02:00
|
|
|
|
2018-05-12 12:28:07 +02:00
|
|
|
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL;
|
|
|
|
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL;
|
|
|
|
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL;
|
|
|
|
PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL;
|
|
|
|
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL;
|
|
|
|
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL;
|
|
|
|
|
2018-05-23 02:03:45 +02:00
|
|
|
PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = NULL;
|
2018-07-16 12:27:41 +02:00
|
|
|
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
2018-05-23 02:03:45 +02:00
|
|
|
|
2018-05-31 03:38:33 +02:00
|
|
|
PFNGLTEXBUFFERPROC glTexBuffer = NULL;
|
|
|
|
|
2018-05-09 05:09:57 +02:00
|
|
|
void OpenGL_Init()
|
|
|
|
{
|
|
|
|
// Program
|
|
|
|
glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
|
|
|
|
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram");
|
|
|
|
glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
|
|
|
|
glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
|
|
|
|
glDetachShader = (PFNGLDETACHSHADERPROC)wglGetProcAddress("glDetachShader");
|
|
|
|
glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
|
|
|
|
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv");
|
|
|
|
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog");
|
|
|
|
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");
|
|
|
|
glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i");
|
|
|
|
glUniform1iv = (PFNGLUNIFORM1IVPROC)wglGetProcAddress("glUniform1iv");
|
|
|
|
glUniform2iv = (PFNGLUNIFORM2IVPROC)wglGetProcAddress("glUniform2iv");
|
|
|
|
glUniform3iv = (PFNGLUNIFORM3IVPROC)wglGetProcAddress("glUniform3iv");
|
|
|
|
glUniform4iv = (PFNGLUNIFORM4IVPROC)wglGetProcAddress("glUniform4iv");
|
|
|
|
glUniform1f = (PFNGLUNIFORM1FPROC)wglGetProcAddress("glUniform1f");
|
|
|
|
glUniform1fv = (PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv");
|
|
|
|
glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv");
|
|
|
|
glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv");
|
|
|
|
glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv");
|
2018-05-12 12:28:07 +02:00
|
|
|
glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f");
|
2018-05-09 05:09:57 +02:00
|
|
|
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
|
|
|
|
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
|
|
|
|
glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)wglGetProcAddress("glVertexAttrib1f");
|
|
|
|
glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)wglGetProcAddress("glVertexAttrib1fv");
|
|
|
|
glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)wglGetProcAddress("glVertexAttrib2fv");
|
|
|
|
glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)wglGetProcAddress("glVertexAttrib3fv");
|
|
|
|
glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)wglGetProcAddress("glVertexAttrib4fv");
|
|
|
|
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
|
|
|
|
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)wglGetProcAddress("glBindAttribLocation");
|
|
|
|
|
|
|
|
glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
|
|
|
|
glDeleteShader = (PFNGLDELETESHADERPROC)wglGetProcAddress("glDeleteShader");
|
|
|
|
glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
|
|
|
|
glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
|
|
|
|
glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv");
|
|
|
|
|
|
|
|
glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
|
|
|
|
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
|
|
|
|
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
|
2018-05-31 03:38:33 +02:00
|
|
|
glMapBuffer = (PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer");
|
|
|
|
glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)wglGetProcAddress("glUnmapBuffer");
|
|
|
|
glBufferSubData = (PFNGLBUFFERSUBDATAPROC)wglGetProcAddress("glBufferSubData");
|
2018-05-09 05:09:57 +02:00
|
|
|
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
|
2018-05-12 12:28:07 +02:00
|
|
|
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
|
2018-05-20 06:27:53 +02:00
|
|
|
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays");
|
|
|
|
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray");
|
|
|
|
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glDeleteVertexArrays");
|
2018-05-09 05:09:57 +02:00
|
|
|
|
2018-05-20 01:11:37 +02:00
|
|
|
glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
|
2018-05-12 12:28:07 +02:00
|
|
|
|
|
|
|
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers");
|
|
|
|
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer");
|
|
|
|
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D");
|
|
|
|
glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffers");
|
|
|
|
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus");
|
|
|
|
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers");
|
2018-05-23 02:03:45 +02:00
|
|
|
|
|
|
|
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT)wglGetProcAddress("wglSwapIntervalEXT");
|
2018-07-16 12:27:41 +02:00
|
|
|
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
2018-05-31 03:38:33 +02:00
|
|
|
|
|
|
|
glTexBuffer = (PFNGLTEXBUFFERPROC)wglGetProcAddress("glTexBuffer");
|
2018-05-09 05:09:57 +02:00
|
|
|
}
|
|
|
|
|
2018-07-16 12:27:41 +02:00
|
|
|
BOOL OpenGL_ExtExists(char *ext, HDC hdc)
|
2018-05-09 05:09:57 +02:00
|
|
|
{
|
|
|
|
char *glext = (char *)glGetString(GL_EXTENSIONS);
|
|
|
|
if (glext)
|
|
|
|
{
|
|
|
|
if (strstr(glext, ext))
|
|
|
|
return TRUE;
|
|
|
|
}
|
2018-07-16 12:27:41 +02:00
|
|
|
|
|
|
|
if (wglGetExtensionsStringARB)
|
|
|
|
{
|
|
|
|
char *wglext = (char *)wglGetExtensionsStringARB(hdc);
|
|
|
|
if (wglext)
|
|
|
|
{
|
|
|
|
if (strstr(wglext, ext))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-09 05:09:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-05-12 12:28:07 +02:00
|
|
|
GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
|
2018-05-09 05:09:57 +02:00
|
|
|
{
|
|
|
|
if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram ||
|
2018-05-09 05:41:58 +02:00
|
|
|
!glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader)
|
2018-05-09 05:09:57 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
|
|
|
|
if (!vertShader || !fragShader)
|
|
|
|
return 0;
|
|
|
|
|
2018-05-12 18:16:17 +02:00
|
|
|
glShaderSource(vertShader, 1, &vertSource, NULL);
|
|
|
|
glShaderSource(fragShader, 1, &fragSource, NULL);
|
2018-05-09 05:09:57 +02:00
|
|
|
|
|
|
|
GLint isCompiled = 0;
|
|
|
|
|
|
|
|
glCompileShader(vertShader);
|
|
|
|
if (glGetShaderiv)
|
|
|
|
{
|
|
|
|
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &isCompiled);
|
|
|
|
if (isCompiled == GL_FALSE)
|
|
|
|
{
|
|
|
|
if (glDeleteShader)
|
|
|
|
glDeleteShader(vertShader);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glCompileShader(fragShader);
|
|
|
|
if (glGetShaderiv)
|
|
|
|
{
|
|
|
|
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &isCompiled);
|
|
|
|
if (isCompiled == GL_FALSE)
|
|
|
|
{
|
|
|
|
if (glDeleteShader)
|
2018-05-13 19:43:03 +02:00
|
|
|
{
|
2018-05-09 05:09:57 +02:00
|
|
|
glDeleteShader(fragShader);
|
2018-05-13 19:43:03 +02:00
|
|
|
glDeleteShader(vertShader);
|
|
|
|
}
|
2018-05-09 05:09:57 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GLuint program = glCreateProgram();
|
|
|
|
if (program)
|
|
|
|
{
|
|
|
|
glAttachShader(program, vertShader);
|
|
|
|
glAttachShader(program, fragShader);
|
|
|
|
|
|
|
|
glLinkProgram(program);
|
|
|
|
|
2018-05-09 05:41:58 +02:00
|
|
|
glDetachShader(program, vertShader);
|
|
|
|
glDetachShader(program, fragShader);
|
|
|
|
glDeleteShader(vertShader);
|
|
|
|
glDeleteShader(fragShader);
|
|
|
|
|
2018-05-09 05:09:57 +02:00
|
|
|
if (glGetProgramiv)
|
|
|
|
{
|
|
|
|
GLint isLinked = 0;
|
|
|
|
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
|
|
|
|
if (isLinked == GL_FALSE)
|
|
|
|
{
|
|
|
|
if (glDeleteProgram)
|
|
|
|
glDeleteProgram(program);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return program;
|
|
|
|
}
|
2018-05-12 12:28:07 +02:00
|
|
|
|
|
|
|
GLuint OpenGL_BuildProgramFromFile(const char *filePath)
|
|
|
|
{
|
|
|
|
GLuint program = 0;
|
|
|
|
|
|
|
|
FILE *file = fopen(filePath, "rb");
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
fseek(file, 0, SEEK_END);
|
|
|
|
long fileSize = ftell(file);
|
|
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
|
2018-05-12 18:16:17 +02:00
|
|
|
char *source = calloc(fileSize + 1, 1);
|
2018-05-12 12:28:07 +02:00
|
|
|
if (source)
|
|
|
|
{
|
|
|
|
fread(source, fileSize, 1, file);
|
|
|
|
fclose(file);
|
|
|
|
|
2018-05-12 18:16:17 +02:00
|
|
|
char *vertSource = calloc(fileSize + 50, 1);
|
|
|
|
char *fragSource = calloc(fileSize + 50, 1);
|
|
|
|
|
|
|
|
if (fragSource && vertSource)
|
|
|
|
{
|
2018-05-12 19:54:55 +02:00
|
|
|
char *versionStart = strstr(source, "#version");
|
2018-05-12 18:16:17 +02:00
|
|
|
if (versionStart)
|
|
|
|
{
|
|
|
|
const char deli[2] = "\n";
|
|
|
|
char *version = strtok(versionStart, deli);
|
|
|
|
|
|
|
|
strcpy(vertSource, source);
|
|
|
|
strcpy(fragSource, source);
|
|
|
|
strcat(vertSource, "\n#define VERTEX\n");
|
|
|
|
strcat(fragSource, "\n#define FRAGMENT\n");
|
|
|
|
strcat(vertSource, version + strlen(version) + 1);
|
|
|
|
strcat(fragSource, version + strlen(version) + 1);
|
|
|
|
|
|
|
|
program = OpenGL_BuildProgram(vertSource, fragSource);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcpy(vertSource, "#define VERTEX\n");
|
|
|
|
strcpy(fragSource, "#define FRAGMENT\n");
|
|
|
|
strcat(vertSource, source);
|
|
|
|
strcat(fragSource, source);
|
|
|
|
|
|
|
|
program = OpenGL_BuildProgram(vertSource, fragSource);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(vertSource);
|
|
|
|
free(fragSource);
|
|
|
|
}
|
2018-05-12 12:28:07 +02:00
|
|
|
|
|
|
|
free(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return program;
|
|
|
|
}
|