509 lines
12 KiB
C
Executable File
509 lines
12 KiB
C
Executable File
#include "ogl.h"
|
|
|
|
|
|
BOOL LoadExtensionList(void){
|
|
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
|
if(wglChoosePixelFormatARB == NULL){
|
|
return FALSE;
|
|
}
|
|
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
|
if(wglCreateContextAttribsARB == NULL){
|
|
return FALSE;
|
|
}
|
|
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
|
|
if(wglSwapIntervalEXT == NULL){
|
|
return FALSE;
|
|
}
|
|
glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
|
|
if(!glAttachShader){
|
|
return FALSE;
|
|
}
|
|
|
|
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
|
|
if(!glBindBuffer){
|
|
return FALSE;
|
|
}
|
|
|
|
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray");
|
|
if(!glBindVertexArray){
|
|
return FALSE;
|
|
}
|
|
|
|
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
|
|
if(!glBufferData){
|
|
return FALSE;
|
|
}
|
|
|
|
glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
|
|
if(!glCompileShader){
|
|
return FALSE;
|
|
}
|
|
|
|
glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
|
|
if(!glCreateProgram){
|
|
return FALSE;
|
|
}
|
|
|
|
glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
|
|
if(!glCreateShader){
|
|
return FALSE;
|
|
}
|
|
|
|
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
|
|
if(!glDeleteBuffers){
|
|
return FALSE;
|
|
}
|
|
|
|
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram");
|
|
if(!glDeleteProgram){
|
|
return FALSE;
|
|
}
|
|
|
|
glDeleteShader = (PFNGLDELETESHADERPROC)wglGetProcAddress("glDeleteShader");
|
|
if(!glDeleteShader){
|
|
return FALSE;
|
|
}
|
|
|
|
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glDeleteVertexArrays");
|
|
if(!glDeleteVertexArrays){
|
|
return FALSE;
|
|
}
|
|
|
|
glDetachShader = (PFNGLDETACHSHADERPROC)wglGetProcAddress("glDetachShader");
|
|
if(!glDetachShader){
|
|
return FALSE;
|
|
}
|
|
|
|
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
|
|
if(!glEnableVertexAttribArray){
|
|
return FALSE;
|
|
}
|
|
|
|
glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
|
|
if(!glGenBuffers){
|
|
return FALSE;
|
|
}
|
|
|
|
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays");
|
|
if(!glGenVertexArrays){
|
|
return FALSE;
|
|
}
|
|
|
|
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
|
|
if(!glGetAttribLocation){
|
|
return FALSE;
|
|
}
|
|
|
|
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog");
|
|
if(!glGetProgramInfoLog){
|
|
return FALSE;
|
|
}
|
|
|
|
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv");
|
|
if(!glGetProgramiv){
|
|
return FALSE;
|
|
}
|
|
|
|
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog");
|
|
if(!glGetShaderInfoLog){
|
|
return FALSE;
|
|
}
|
|
|
|
glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv");
|
|
if(!glGetShaderiv){
|
|
return FALSE;
|
|
}
|
|
|
|
glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
|
|
if(!glLinkProgram){
|
|
return FALSE;
|
|
}
|
|
|
|
glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
|
|
if(!glShaderSource){
|
|
return FALSE;
|
|
}
|
|
|
|
glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
|
|
if(!glUseProgram){
|
|
return FALSE;
|
|
}
|
|
|
|
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
|
|
if(!glVertexAttribPointer){
|
|
return FALSE;
|
|
}
|
|
|
|
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)wglGetProcAddress("glBindAttribLocation");
|
|
if(!glBindAttribLocation){
|
|
return FALSE;
|
|
}
|
|
|
|
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");
|
|
if(!glGetUniformLocation){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
|
|
if(!glUniformMatrix4fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
|
|
if(!glActiveTexture){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i");
|
|
if(!glUniform1i){
|
|
return FALSE;
|
|
}
|
|
|
|
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmap");
|
|
if(!glGenerateMipmap){
|
|
return FALSE;
|
|
}
|
|
|
|
glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glDisableVertexAttribArray");
|
|
if(!glDisableVertexAttribArray){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1f = (PFNGLUNIFORM1FPROC)wglGetProcAddress("glUniform1f");
|
|
if(!glUniform1f){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform2f = (PFNGLUNIFORM2FPROC)wglGetProcAddress("glUniform2f");
|
|
if(!glUniform2f){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform3f = (PFNGLUNIFORM3FPROC)wglGetProcAddress("glUniform3f");
|
|
if(!glUniform3f){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f");
|
|
if(!glUniform4f){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i");
|
|
if(!glUniform1i){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform2i = (PFNGLUNIFORM2IPROC)wglGetProcAddress("glUniform2i");
|
|
if(!glUniform2i){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform3i = (PFNGLUNIFORM3IPROC)wglGetProcAddress("glUniform3i");
|
|
if(!glUniform3i){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform4i = (PFNGLUNIFORM4IPROC)wglGetProcAddress("glUniform4i");
|
|
if(!glUniform4i){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1ui = (PFNGLUNIFORM1UIPROC)wglGetProcAddress("glUniform1ui");
|
|
if(!glUniform1ui){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform2ui = (PFNGLUNIFORM2UIPROC)wglGetProcAddress("glUniform2ui");
|
|
if(!glUniform2ui){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform3ui = (PFNGLUNIFORM3UIPROC)wglGetProcAddress("glUniform3ui");
|
|
if(!glUniform3ui){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform4ui = (PFNGLUNIFORM4UIPROC)wglGetProcAddress("glUniform4ui");
|
|
if(!glUniform4ui){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1fv = (PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv");
|
|
if(!glUniform1fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv");
|
|
if(!glUniform2fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv");
|
|
if(!glUniform3fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv");
|
|
if(!glUniform4fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1iv = (PFNGLUNIFORM1IVPROC)wglGetProcAddress("glUniform1iv");
|
|
if(!glUniform1iv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform2iv = (PFNGLUNIFORM2IVPROC)wglGetProcAddress("glUniform2iv");
|
|
if(!glUniform2iv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform3iv = (PFNGLUNIFORM3IVPROC)wglGetProcAddress("glUniform3iv");
|
|
if(!glUniform3iv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform4iv = (PFNGLUNIFORM4IVPROC)wglGetProcAddress("glUniform4iv");
|
|
if(!glUniform4iv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform1uiv = (PFNGLUNIFORM1UIVPROC)wglGetProcAddress("glUniform1uiv");
|
|
if(!glUniform1uiv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform2uiv = (PFNGLUNIFORM2UIVPROC)wglGetProcAddress("glUniform2uiv");
|
|
if(!glUniform2uiv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform3uiv = (PFNGLUNIFORM3UIVPROC)wglGetProcAddress("glUniform3uiv");
|
|
if(!glUniform3uiv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniform4uiv = (PFNGLUNIFORM4UIVPROC)wglGetProcAddress("glUniform4uiv");
|
|
if(!glUniform4uiv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)wglGetProcAddress("glUniformMatrix2fv");
|
|
if(!glUniformMatrix2fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)wglGetProcAddress("glUniformMatrix3fv");
|
|
if(!glUniformMatrix3fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
|
|
if(!glUniformMatrix4fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)wglGetProcAddress("glUniformMatrix2x3fv");
|
|
if(!glUniformMatrix2x3fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)wglGetProcAddress("glUniformMatrix3x2fv");
|
|
if(!glUniformMatrix3x2fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)wglGetProcAddress("glUniformMatrix2x4fv");
|
|
if(!glUniformMatrix2x4fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)wglGetProcAddress("glUniformMatrix4x2fv");
|
|
if(!glUniformMatrix4x2fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)wglGetProcAddress("glUniformMatrix3x4fv");
|
|
if(!glUniformMatrix3x4fv){
|
|
return FALSE;
|
|
}
|
|
|
|
glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)wglGetProcAddress("glUniformMatrix4x3fv");
|
|
if(!glUniformMatrix4x3fv){
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// TODO: error handling
|
|
int InitializeOpenGLExtensions(void){
|
|
int error = 0;
|
|
|
|
WNDCLASS dummyClass = {
|
|
.style = CS_OWNDC,
|
|
.lpfnWndProc = DefWindowProc,
|
|
.hInstance = GetModuleHandle(0),
|
|
.lpszClassName = "dummyClass",
|
|
};
|
|
if(RegisterClassA(&dummyClass) == 0){
|
|
error = 1;
|
|
goto end_class;
|
|
}
|
|
|
|
HWND dummyWindow = CreateWindowEx(
|
|
0,
|
|
dummyClass.lpszClassName,
|
|
"dummyWindow",
|
|
0,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
NULL, NULL,
|
|
dummyClass.hInstance,
|
|
NULL
|
|
);
|
|
if(dummyWindow == NULL) {
|
|
error = 2;
|
|
goto end_window;
|
|
}
|
|
HDC dummyDC = GetDC(dummyWindow);
|
|
if(dummyDC == NULL){
|
|
error = 3;
|
|
goto end_DC;
|
|
}
|
|
|
|
PIXELFORMATDESCRIPTOR dummyPFD = {
|
|
.nSize = sizeof(PIXELFORMATDESCRIPTOR),
|
|
.nVersion = 1,
|
|
.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
|
.iPixelType = PFD_TYPE_RGBA,
|
|
.cColorBits = 32,
|
|
.cDepthBits = 24,
|
|
.cStencilBits = 8
|
|
};
|
|
int pf = ChoosePixelFormat(dummyDC, &dummyPFD);
|
|
if(pf == 0){
|
|
error = 4;
|
|
goto end_DC;
|
|
}
|
|
if(SetPixelFormat(dummyDC, pf, &dummyPFD) == FALSE){
|
|
error = 5;
|
|
goto end_DC;
|
|
}
|
|
|
|
HGLRC dummyContext = wglCreateContext(dummyDC);
|
|
if(dummyContext == NULL){
|
|
error = 6;
|
|
goto end_context;
|
|
}
|
|
if(wglMakeCurrent(dummyDC, dummyContext) == FALSE){
|
|
error = 7;
|
|
goto end_current;
|
|
}
|
|
|
|
if(LoadExtensionList() == FALSE){
|
|
error = 8;
|
|
}
|
|
|
|
end_current:
|
|
if(wglMakeCurrent(NULL, NULL) == FALSE){
|
|
error = 9;
|
|
}
|
|
end_context:
|
|
if(wglDeleteContext(dummyContext) == FALSE){
|
|
error = 10;
|
|
}else{
|
|
dummyContext = NULL;
|
|
}
|
|
end_DC:
|
|
if(ReleaseDC(dummyWindow, dummyDC) == 0){
|
|
error = 11;
|
|
}else{
|
|
dummyDC = NULL;
|
|
}
|
|
end_window:
|
|
if(DestroyWindow(dummyWindow) == 0){
|
|
error = 12;
|
|
}else{
|
|
dummyWindow = NULL;
|
|
}
|
|
end_class:
|
|
if(UnregisterClass(dummyClass.lpszClassName, dummyClass.hInstance) == 0){
|
|
error = 13;
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
// TODO: abstract away to a platform-independent library
|
|
static long getFileSize(FILE *fp){
|
|
long curr = ftell(fp);
|
|
fseek(fp, 0, SEEK_END);
|
|
long size = ftell(fp);
|
|
fseek(fp, curr, SEEK_SET);
|
|
return size;
|
|
}
|
|
|
|
GLuint LoadShaders(char *vertex_file_path, char *fragment_file_path){
|
|
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
// use str.h
|
|
char *VertexShaderCode;
|
|
FILE *VertexShaderStream = fopen(vertex_file_path, "rb");
|
|
if(VertexShaderStream != NULL){
|
|
long fsize = getFileSize(VertexShaderStream);
|
|
VertexShaderCode = calloc(fsize, sizeof(char));
|
|
fread(VertexShaderCode, sizeof(char), fsize, VertexShaderStream);
|
|
fclose(VertexShaderStream);
|
|
}else{
|
|
return 0;
|
|
}
|
|
|
|
// use str.h
|
|
char *FragmentShaderCode;
|
|
FILE *FragmentShaderStream = fopen(fragment_file_path, "rb");
|
|
if(FragmentShaderStream != NULL){
|
|
long fsize = getFileSize(VertexShaderStream);
|
|
FragmentShaderCode = calloc(fsize, sizeof(char));
|
|
fread(FragmentShaderCode, sizeof(char), fsize, FragmentShaderStream);
|
|
fclose(FragmentShaderStream);
|
|
}else{
|
|
return 0;
|
|
}
|
|
|
|
GLint Result;
|
|
|
|
glShaderSource(VertexShaderID, 1, &VertexShaderCode, NULL);
|
|
glCompileShader(VertexShaderID);
|
|
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
|
|
if(Result != GL_TRUE){
|
|
return 0;
|
|
}
|
|
|
|
glShaderSource(FragmentShaderID, 1, &FragmentShaderCode , NULL);
|
|
glCompileShader(FragmentShaderID);
|
|
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
|
|
if(Result != GL_TRUE){
|
|
return 0;
|
|
}
|
|
|
|
GLuint ProgramID = glCreateProgram();
|
|
glAttachShader(ProgramID, VertexShaderID);
|
|
glAttachShader(ProgramID, FragmentShaderID);
|
|
glLinkProgram(ProgramID);
|
|
|
|
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
|
if(Result != GL_TRUE){
|
|
return 0;
|
|
}
|
|
|
|
glDetachShader(ProgramID, VertexShaderID);
|
|
glDetachShader(ProgramID, FragmentShaderID);
|
|
glDeleteShader(VertexShaderID);
|
|
glDeleteShader(FragmentShaderID);
|
|
|
|
return ProgramID;
|
|
}
|
|
|