#include #include #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; PFNGLUNIFORM4FPROC glUniform4f = NULL; 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; PFNGLMAPBUFFERPROC glMapBuffer = NULL; PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL; PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL; PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL; PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL; PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL; PFNGLACTIVETEXTUREPROC glActiveTexture = NULL; PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL; PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL; PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL; PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL; PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL; PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = NULL; PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; PFNGLTEXBUFFERPROC glTexBuffer = NULL; 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"); glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f"); 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"); glMapBuffer = (PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer"); glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)wglGetProcAddress("glUnmapBuffer"); glBufferSubData = (PFNGLBUFFERSUBDATAPROC)wglGetProcAddress("glBufferSubData"); glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"); glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays"); glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray"); glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glDeleteVertexArrays"); glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"); glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"); glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"); glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"); glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffers"); glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus"); glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers"); wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT)wglGetProcAddress("wglSwapIntervalEXT"); wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); glTexBuffer = (PFNGLTEXBUFFERPROC)wglGetProcAddress("glTexBuffer"); } BOOL OpenGL_ExtExists(char *ext, HDC hdc) { char *glext = (char *)glGetString(GL_EXTENSIONS); if (glext) { if (strstr(glext, ext)) return TRUE; } if (wglGetExtensionsStringARB) { char *wglext = (char *)wglGetExtensionsStringARB(hdc); if (wglext) { if (strstr(wglext, ext)) return TRUE; } } return FALSE; } GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource) { if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram || !glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader) return 0; GLuint vertShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER); if (!vertShader || !fragShader) return 0; glShaderSource(vertShader, 1, &vertSource, NULL); glShaderSource(fragShader, 1, &fragSource, NULL); 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) { glDeleteShader(fragShader); glDeleteShader(vertShader); } return 0; } } GLuint program = glCreateProgram(); if (program) { glAttachShader(program, vertShader); glAttachShader(program, fragShader); glLinkProgram(program); glDetachShader(program, vertShader); glDetachShader(program, fragShader); glDeleteShader(vertShader); glDeleteShader(fragShader); if (glGetProgramiv) { GLint isLinked = 0; glGetProgramiv(program, GL_LINK_STATUS, &isLinked); if (isLinked == GL_FALSE) { if (glDeleteProgram) glDeleteProgram(program); return 0; } } } return program; } 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); char *source = calloc(fileSize + 1, 1); if (source) { fread(source, fileSize, 1, file); fclose(file); char *vertSource = calloc(fileSize + 50, 1); char *fragSource = calloc(fileSize + 50, 1); if (fragSource && vertSource) { char *versionStart = strstr(source, "#version"); 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); } free(source); } } return program; }