libs/ogl/ogl.c
2025-01-06 00:50:11 +01:00

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;
}