diff --git a/meson.build b/meson.build index cda8d77..37c2772 100644 --- a/meson.build +++ b/meson.build @@ -10,6 +10,11 @@ dependencies = [] link_args = [] +include_dirs = [ + 'vendor/', + 'src/' +] + if host_machine.system() == 'linux' dependencies += [ dependency('libglvnd') @@ -34,9 +39,12 @@ endif executable( 'scuffedcraft', - 'src/main.c', + 'src/DynArray.c', + 'src/DynString.c', 'src/log.c', + 'src/main.c', c_args: cargs, dependencies: dependencies, - link_args: link_args + link_args: link_args, + include_directories: include_directories(include_dirs) ) diff --git a/src/DynArray.c b/src/DynArray.c new file mode 100644 index 0000000..51a9474 --- /dev/null +++ b/src/DynArray.c @@ -0,0 +1,3 @@ +#include "DynArray.h" + +DYN_ARRAY_IMPL(DynString); diff --git a/src/DynArray.h b/src/DynArray.h new file mode 100644 index 0000000..f02169e --- /dev/null +++ b/src/DynArray.h @@ -0,0 +1,63 @@ +#ifndef DYN_ARRAY_H_ +#define DYN_ARRAY_H_ + +#include +#include +#include + +#include "DynString.h" + +#define DYN_ARRAY_EXPANDER(macro, args) macro args + +#define DYN_ARRAY_IMPL(type) \ +DYN_ARRAY_ALLOC(type, DynArray_##type, DynArray_##type##_alloc) \ +DYN_ARRAY_PUSH_BACK(type, DynArray_##type, DynArray_##type##_push_back) \ + +#define DYN_ARRAY_SIGS(type) \ +DYN_ARRAY_ALLOC_SIG(DynArray_##type, DynArray_##type##_alloc); \ +DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type, DynArray_##type##_push_back); \ + +#define DYN_ARRAY_STRUCT(type) \ +typedef struct { \ + type* data; \ + size_t count; \ + size_t capacity; \ +} DynArray_##type + +// DYN_ARRAY_STRUCT(DynString); + +#define DYN_ARRAY_ALLOC_SIG(type_name, func_name) int func_name(type_name* darr, const size_t capacity) + +#define DYN_ARRAY_ALLOC(type, type_name, func_name) \ +DYN_ARRAY_ALLOC_SIG(type_name, func_name) { \ + darr->data = (type*) calloc(capacity, sizeof(type)); \ + if (darr->data == NULL) { \ + return -1; \ + } \ + darr->count = 0; \ + darr->capacity = capacity; \ + return 1; \ +} + +#define DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem) + +#define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \ +DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \ + if (darr->count + 1 > darr->capacity) { \ + darr->capacity *= 2; \ + darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \ + if (darr->data == NULL) { \ + return -1; \ + } \ + } \ + memcpy(darr->data + darr->count, new_elem, sizeof(type)); \ + darr->count++; \ + return 1; \ +} + +// DYN_ARRAY_PUSH_BACK(DynString, DynArray_DynString, DynArray_DynString_push_back); + +DYN_ARRAY_STRUCT(DynString); +DYN_ARRAY_SIGS(DynString); + +#endif // DYN_ARRAY_H_ diff --git a/src/DynString.c b/src/DynString.c new file mode 100644 index 0000000..5b99d7c --- /dev/null +++ b/src/DynString.c @@ -0,0 +1,17 @@ +#include +#include + +#include "DynString.h" + +short DynString_alloc(DynString* dstr, const char* str, const size_t len) { + dstr->data = (char*) malloc(sizeof(char) * len + 1); + if (dstr->data == NULL) { + return -1; + } + dstr->data = memcpy(dstr->data, str, len); + dstr->data[len] = '\0'; + dstr->len = len; + + return 1; +} + diff --git a/src/DynString.h b/src/DynString.h new file mode 100644 index 0000000..746dcf7 --- /dev/null +++ b/src/DynString.h @@ -0,0 +1,13 @@ +#ifndef DYN_STRING_H_ +#define DYN_STRING_H_ + +#include + +typedef struct { + char* data; + size_t len; +} DynString; + +short DynString_alloc(DynString* dstr, const char* str, const size_t len); + +#endif // DYN_STRING_H_ diff --git a/src/main.c b/src/main.c index a090bfb..3f97263 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,21 @@ +#include +#include +#include #include +#include #include +#include #include #include #include #include +#include "DynArray.h" +#include "DynString.h" #include "log.h" +HMODULE opengl_module = NULL; + // int _main() { // return 0; // } @@ -18,6 +27,23 @@ typedef struct { int num; } State; +void* gl_function_load(const char* name) { + assert(opengl_module != NULL); + void* gl_func = (void*) wglGetProcAddress(name); + if (gl_func == NULL || gl_func == (void*) 1 || gl_func == (void*) 2 || gl_func == (void*) 3 || gl_func == (void*) -1) { + void* gl32_func = (void*) GetProcAddress(opengl_module, name); + if (gl32_func == NULL || gl32_func == (void*) 1 || gl32_func == (void*) 2 || gl32_func == (void*) 3 || gl32_func == (void*) -1) { + LOG_ERRORF("wglGetProcAddress failed to load gl function %s. Returned %p\n", name, gl_func); + LOG_ERRORF("GetProcAddress failed to load gl function %s. Returned %p\n", name, gl32_func); + return NULL; + } + + return gl32_func; + } + + return gl_func; +} + void OnSize(HWND hwnd, UINT flag, int width, int height) { printf("Window resize: flag: %d, width: %d, height: %d\n", flag, width, height); } @@ -94,8 +120,92 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 1; } + PFNGLGETINTEGERVPROC glGetIntegerv = (PFNGLGETINTEGERVPROC) gl_function_load("glGetIntegerv"); + if (glGetIntegerv == NULL) { + return 1; + } + int major = 0; + int minor = 0; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + printf("OpenGL version %d.%d\n", major, minor); + + int profile_mask = 0; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile_mask); + if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT) { + printf("OpenGL profile: core\n"); + } else if (profile_mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) { + printf("OpenGL profile: compatibility\n"); + } else { + LOG_ERRORF( + "GL_CONTEXT_PROFILE_MASK did not contain either bit. profile_mask: %d", + profile_mask + ); + } + + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) gl_function_load("wglGetExtensionsStringARB"); + if (wglGetExtensionsStringARB == NULL) { + LOG_ERROR("Could not load wgl extensions string."); + return 1; + } + + // const char* wgl_extensions = wglGetExtensionsStringARB(hdc); + char* wgl_extensions = (char*) wglGetExtensionsStringARB(hdc); + printf("wgl extensions: %s\n", wgl_extensions); + + DynArray_DynString extensions_arr = { 0 }; + if (!DynArray_DynString_alloc(&extensions_arr, 1)) { + LOG_ERROR("Failed to allocate"); + } + + char* wgl_extensions_copy = strdup(wgl_extensions); + + char* ext = strtok(wgl_extensions_copy, " "); + if (ext == NULL) { + LOG_ERROR("wgl_extensions was empty"); + return 1; + } + DynString ext_dstr = { 0 }; + if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) { + LOG_ERROR("Failed to allocate extension string"); + return 1; + } + + if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) { + LOG_ERROR("Failed to push back extension string"); + return 1; + } + // printf("ext: %s\n", ext); + while (true) { + ext = strtok(NULL, " "); + // printf("ext: %s\n", ext); + if (ext == NULL) { + break; + } + + DynString ext_dstr = { 0 }; + if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) { + LOG_ERROR("Failed to allocate extension string"); + return 1; + } + + if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) { + LOG_ERROR("Failed to push back extension string"); + return 1; + } + } + + free(wgl_extensions_copy); + + printf("count: %zu\n", extensions_arr.count); + for (size_t i = 0; i < extensions_arr.count; i++) { + printf("%s\n", extensions_arr.data[i].data); + } + // glClearColor(1.0, 1.0, 0.0, 1.0); // glClear(GL_COLOR_BUFFER_BIT); + // const unsigned char* version = glGetString(GL_VERSION); + // printf("OpenGL version %s\n", version); return 0; } @@ -144,6 +254,8 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) { + opengl_module = LoadLibraryA("opengl32.dll"); + // Register the window class const wchar_t* CLASS_NAME = L"Sample Window Class";