triangle
This commit is contained in:
@@ -40,6 +40,8 @@ endif
|
||||
|
||||
executable(
|
||||
'scuffedcraft',
|
||||
'src/pltf/gl_funcs.c',
|
||||
'src/pltf/pltf.c',
|
||||
'src/DynArray.c',
|
||||
'src/DynString.c',
|
||||
'src/log.c',
|
||||
|
||||
293
src/main.c
293
src/main.c
@@ -13,11 +13,8 @@
|
||||
#include "DynArray.h"
|
||||
#include "DynString.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
HMODULE opengl_module = NULL;
|
||||
#include "pltf/gl_funcs.h"
|
||||
#include "pltf/pltf.h"
|
||||
|
||||
// int _main() {
|
||||
// return 0;
|
||||
@@ -32,23 +29,6 @@ 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;
|
||||
}
|
||||
|
||||
bool has_wgl_extension(const DynString* name) {
|
||||
assert(!DynString_is_null(name));
|
||||
assert(!DynArray_DynString_is_null(&wgl_extensions));
|
||||
@@ -69,12 +49,35 @@ bool has_wgl_extension_c_str(const char* name) {
|
||||
return res;
|
||||
}
|
||||
|
||||
struct timespec thread_time_get() {
|
||||
struct timespec t = { 0 };
|
||||
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t) == -1) {
|
||||
LOG_FATALF("Failed to get thread time. errno: %d", errno);
|
||||
void print_opengl_info() {
|
||||
// assert(glGetIntegerv != NULL);
|
||||
|
||||
if (glGetIntegerv == NULL) {
|
||||
glGetIntegerv = (PFNGLGETINTEGERVPROC) pltf_gl_function_load("glGetIntegerv");
|
||||
if (glGetIntegerv == NULL) {
|
||||
LOG_FATAL("Could not load glGetIntegerv");
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
|
||||
int profile_mask = 0;
|
||||
char profile[sizeof("compatibility")] = { 0 };
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile_mask);
|
||||
if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT) {
|
||||
strncpy(profile, "core", strlen("core"));
|
||||
} else if (profile_mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) {
|
||||
strncpy(profile, "compatibility", strlen("compatibility"));
|
||||
} else {
|
||||
LOG_ERRORF(
|
||||
"GL_CONTEXT_PROFILE_MASK did not contain either bit. profile_mask: %d",
|
||||
profile_mask
|
||||
);
|
||||
}
|
||||
printf("OpenGL version %d.%d %s\n", major, minor, profile);
|
||||
}
|
||||
|
||||
void OnSize(HWND hwnd, UINT flag, int width, int height) {
|
||||
@@ -131,7 +134,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
0,
|
||||
};
|
||||
|
||||
HDC hdc = GetWindowDC(hwnd);
|
||||
HDC hdc = GetDC(hwnd);
|
||||
if (hdc == NULL) {
|
||||
LOG_ERROR("Failed to get window DC");
|
||||
return 1;
|
||||
@@ -153,37 +156,12 @@ 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);
|
||||
printf("Dummy context info: ");
|
||||
print_opengl_info();
|
||||
|
||||
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;
|
||||
}
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) pltf_gl_function_load("wglGetExtensionsStringARB");
|
||||
|
||||
char* wgl_extensions_str = (char*) wglGetExtensionsStringARB(hdc);
|
||||
printf("wgl extensions: %s\n", wgl_extensions_str);
|
||||
|
||||
char* wgl_extensions_str_copy = strdup(wgl_extensions_str);
|
||||
|
||||
@@ -209,20 +187,73 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
if (ext == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(wgl_extensions_str_copy);
|
||||
|
||||
for (size_t i = 0; i < wgl_extensions.len; i++) {
|
||||
const DynString* ext = DynArray_DynString_at(&wgl_extensions, i);
|
||||
printf("%.*s\n", DYN_STRING_FMT(*ext));
|
||||
// printf("Available WGL extensions:\n");
|
||||
// for (size_t i = 0; i < wgl_extensions.len; i++) {
|
||||
// const DynString* ext = DynArray_DynString_at(&wgl_extensions, i);
|
||||
// printf("%.*s\n", DYN_STRING_FMT(*ext));
|
||||
// }
|
||||
|
||||
if (!has_wgl_extension_c_str("WGL_ARB_pixel_format")) {
|
||||
LOG_FATAL("WGL_ARB_create_context extension required.");
|
||||
}
|
||||
if (!has_wgl_extension_c_str("WGL_ARB_create_context")) {
|
||||
LOG_FATAL("WGL_ARB_create_context extension is required");
|
||||
}
|
||||
|
||||
const struct timespec b = thread_time_get();
|
||||
has_wgl_extension_c_str("WGL_ARB_create_context");
|
||||
const struct timespec a = thread_time_get();
|
||||
printf("time: %ld\n", a.tv_nsec - b.tv_nsec);
|
||||
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) pltf_gl_function_load("wglChoosePixelFormatARB");
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) pltf_gl_function_load("wglCreateContextAttribsARB");
|
||||
|
||||
int wgl_pixel_format = 0;
|
||||
{
|
||||
UINT num_formats = 0;
|
||||
const int attribIList[] = {
|
||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
|
||||
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
|
||||
WGL_COLOR_BITS_ARB, 32,
|
||||
WGL_DEPTH_BITS_ARB, 24,
|
||||
WGL_STENCIL_BITS_ARB, 8,
|
||||
0
|
||||
};
|
||||
if (wglChoosePixelFormatARB(hdc, attribIList, NULL, 1, &wgl_pixel_format, &num_formats) == FALSE) {
|
||||
LOG_FATAL("Failed to get pixel format with wglChoosePixelFormatARB");
|
||||
}
|
||||
}
|
||||
|
||||
if (SetPixelFormat(hdc, wgl_pixel_format, &pfd) == FALSE) {
|
||||
LOG_FATAL("Failed to set wgl_pixel_format");
|
||||
}
|
||||
|
||||
if (wglDeleteContext(gl_ctx) == FALSE) {
|
||||
LOG_FATAL("Failed to delete dummy context");
|
||||
}
|
||||
|
||||
{
|
||||
const int attribIList[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 6,
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB
|
||||
};
|
||||
gl_ctx = wglCreateContextAttribsARB(hdc, NULL, attribIList);
|
||||
if (gl_ctx == NULL) {
|
||||
LOG_FATAL("wglCreateContextAttribsARB did not create a context");
|
||||
}
|
||||
}
|
||||
|
||||
if (wglMakeCurrent(hdc, gl_ctx) == FALSE) {
|
||||
LOG_FATAL("Failed to set proper context as current");
|
||||
}
|
||||
|
||||
printf("Proper context info: ");
|
||||
print_opengl_info();
|
||||
|
||||
pltf_load_gl_funcs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -271,7 +302,9 @@ 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");
|
||||
// opengl_module = LoadLibraryA("opengl32.dll");
|
||||
|
||||
pltf_init();
|
||||
|
||||
// Register the window class
|
||||
const wchar_t* CLASS_NAME = L"Sample Window Class";
|
||||
@@ -314,10 +347,136 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine,
|
||||
|
||||
// Message loop
|
||||
|
||||
MSG msg = { };
|
||||
while (GetMessage(&msg, NULL, 0, 0) > 0) {
|
||||
GLenum gl_err = 0;
|
||||
glClearColor(0.0f, 0.0f, 0.8f, 1.0f);
|
||||
float colors[4] = { 0 };
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, colors);
|
||||
printf("Clear color: %f, %f, %f, %f\n", colors[0], colors[1], colors[2], colors[3]);
|
||||
gl_err = glGetError();
|
||||
if (gl_err != GL_NO_ERROR) {
|
||||
LOG_FATALF("gl error: %d", gl_err);
|
||||
}
|
||||
|
||||
HDC hdc = GetDC(hwnd);
|
||||
|
||||
// clang-format off
|
||||
const float triangle_verts[] = {
|
||||
// pos
|
||||
0.0f, 0.5f, 0.0f, // top
|
||||
-0.5f, -0.5f, 0.0f, // bottom-left
|
||||
0.5f, -0.5f, 0.0f // bottom-right
|
||||
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
const size_t triangle_vert_count = sizeof(triangle_verts) / sizeof(triangle_verts[0]) / 3;
|
||||
|
||||
unsigned int triangle_vao = 0;
|
||||
glGenVertexArrays(1, &triangle_vao);
|
||||
glBindVertexArray(triangle_vao);
|
||||
|
||||
unsigned int triangle_vbo = 0;
|
||||
glGenBuffers(1, &triangle_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
sizeof(triangle_verts),
|
||||
triangle_verts,
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(float) * 3,
|
||||
(void*) 0
|
||||
);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
// clang-format off
|
||||
const char* vertex_shader_src =
|
||||
"#version 460 core\n"
|
||||
"layout (location = 0) in vec3 a_pos;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = vec4(a_pos, 1.0);\n"
|
||||
"}\n"
|
||||
;
|
||||
|
||||
const char* fragment_shader_src =
|
||||
"#version 460 core\n"
|
||||
"out vec4 frag_color;\n"
|
||||
"void main() {\n"
|
||||
" frag_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||
"}\n"
|
||||
;
|
||||
// clang-format on
|
||||
|
||||
const unsigned int vert_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
{
|
||||
const int len = strlen(vertex_shader_src);
|
||||
glShaderSource(vert_shader, 1, &vertex_shader_src, &len);
|
||||
glCompileShader(vert_shader);
|
||||
int compile_status = 0;
|
||||
glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &compile_status);
|
||||
if (compile_status != GL_TRUE) {
|
||||
int info_log_len = 0;
|
||||
glGetShaderiv(vert_shader, GL_INFO_LOG_LENGTH, &info_log_len);
|
||||
char* err_str = (char*) malloc(sizeof(char) * info_log_len);
|
||||
glGetShaderInfoLog(vert_shader, info_log_len - 1, NULL, err_str);
|
||||
LOG_FATALF("Failed to compile vertex shader: %s", err_str);
|
||||
}
|
||||
}
|
||||
const unsigned int frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
{
|
||||
const int len = strlen(fragment_shader_src);
|
||||
glShaderSource(frag_shader, 1, &fragment_shader_src, &len);
|
||||
glCompileShader(frag_shader);
|
||||
int compile_status = 0;
|
||||
glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &compile_status);
|
||||
if (compile_status != GL_TRUE) {
|
||||
int info_log_len = 0;
|
||||
glGetShaderiv(frag_shader, GL_INFO_LOG_LENGTH, &info_log_len);
|
||||
char* err_str = (char*) malloc(sizeof(char) * info_log_len);
|
||||
glGetShaderInfoLog(frag_shader, info_log_len - 1, NULL, err_str);
|
||||
LOG_FATALF("Failed to compile fragment shader: %s", err_str);
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned int shader_program = glCreateProgram();
|
||||
{
|
||||
|
||||
glAttachShader(shader_program, vert_shader);
|
||||
glAttachShader(shader_program, frag_shader);
|
||||
glLinkProgram(shader_program);
|
||||
int compile_status = 0;
|
||||
glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status);
|
||||
if (compile_status != GL_TRUE) {
|
||||
LOG_FATAL("Failed to link shader program.");
|
||||
}
|
||||
glDeleteShader(vert_shader);
|
||||
glDeleteShader(frag_shader);
|
||||
}
|
||||
|
||||
MSG msg = { 0 };
|
||||
while (true) {
|
||||
if (GetMessage(&msg, NULL, 0, 0) <= 0) {
|
||||
break;
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
printf("MSG LOOP\n");
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(shader_program);
|
||||
glBindVertexArray(triangle_vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, triangle_vert_count);
|
||||
|
||||
wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
33
src/pltf/gl_funcs.c
Normal file
33
src/pltf/gl_funcs.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "gl_funcs.h"
|
||||
#include "log.h"
|
||||
#include "pltf.h"
|
||||
|
||||
#define X(type, name) \
|
||||
type name = NULL
|
||||
|
||||
PLTF_GL_FUNCS(X)
|
||||
#undef X
|
||||
|
||||
#define X(type, name) \
|
||||
name = (type) pltf_gl_function_load(#name)
|
||||
|
||||
void* pltf_gl_function_load(const char* name) {
|
||||
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 pltf_load_gl_funcs() {
|
||||
PLTF_GL_FUNCS(X)
|
||||
}
|
||||
|
||||
40
src/pltf/gl_funcs.h
Normal file
40
src/pltf/gl_funcs.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef GL_FUNCS_H_
|
||||
#define GL_FUNCS_H_
|
||||
|
||||
#include <GL/glcorearb.h>
|
||||
|
||||
#define PLTF_GL_FUNCS(X) \
|
||||
X(PFNGLGETINTEGERVPROC, glGetIntegerv); \
|
||||
X(PFNGLGETFLOATVPROC, glGetFloatv); \
|
||||
X(PFNGLCLEARCOLORPROC, glClearColor); \
|
||||
X(PFNGLCLEARPROC, glClear); \
|
||||
X(PFNGLGETERRORPROC, glGetError); \
|
||||
X(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); \
|
||||
X(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); \
|
||||
X(PFNGLGENBUFFERSPROC, glGenBuffers); \
|
||||
X(PFNGLBINDBUFFERPROC, glBindBuffer); \
|
||||
X(PFNGLBUFFERDATAPROC, glBufferData); \
|
||||
X(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); \
|
||||
X(PFNGLCREATESHADERPROC, glCreateShader); \
|
||||
X(PFNGLSHADERSOURCEPROC, glShaderSource); \
|
||||
X(PFNGLCOMPILESHADERPROC, glCompileShader); \
|
||||
X(PFNGLGETSHADERIVPROC, glGetShaderiv); \
|
||||
X(PFNGLCREATEPROGRAMPROC, glCreateProgram); \
|
||||
X(PFNGLATTACHSHADERPROC, glAttachShader); \
|
||||
X(PFNGLLINKPROGRAMPROC, glLinkProgram); \
|
||||
X(PFNGLGETPROGRAMIVPROC, glGetProgramiv); \
|
||||
X(PFNGLUSEPROGRAMPROC, glUseProgram); \
|
||||
X(PFNGLDRAWARRAYSPROC, glDrawArrays); \
|
||||
X(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \
|
||||
X(PFNGLDELETESHADERPROC, glDeleteShader); \
|
||||
X(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \
|
||||
|
||||
#define X(type, name) extern type name
|
||||
|
||||
PLTF_GL_FUNCS(X)
|
||||
#undef X
|
||||
|
||||
void* pltf_gl_function_load(const char* name);
|
||||
void pltf_load_gl_funcs();
|
||||
|
||||
#endif // GL_FUNCS_H_
|
||||
14
src/pltf/pltf.c
Normal file
14
src/pltf/pltf.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <windows.h>
|
||||
#include <minwindef.h>
|
||||
|
||||
#include "pltf.h"
|
||||
#include "log.h"
|
||||
|
||||
HMODULE opengl_module = NULL;
|
||||
|
||||
void pltf_init() {
|
||||
opengl_module = LoadLibraryA("opengl32.dll");
|
||||
if (opengl_module == NULL) {
|
||||
LOG_FATAL("Failed to load opengl32.dll");
|
||||
}
|
||||
}
|
||||
10
src/pltf/pltf.h
Normal file
10
src/pltf/pltf.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef PLTF_H_
|
||||
#define PLTF_H_
|
||||
|
||||
#include <minwindef.h>
|
||||
|
||||
extern HMODULE opengl_module;
|
||||
|
||||
void pltf_init();
|
||||
|
||||
#endif // PLTF_H_
|
||||
Reference in New Issue
Block a user