diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 69bdbf3..7c5bb13 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -28,8 +28,7 @@ jobs: sudo apt-get update && sudo apt-get install -y \ libx11-dev \ libxrandr-dev \ - mesa-common-dev \ - glslang-tools + mesa-common-dev - name: package run: CXX=clang++ ./src_build/make.sh - name: release diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 09948cb..74a0dbd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -56,10 +56,6 @@ jobs: sudo apt-get update && sudo apt-get install -y \ libx11-dev \ libxrandr-dev \ - mesa-common-dev \ - glslang-tools + mesa-common-dev - name: build run: CXX=clang++ ./src_build/make.sh build - - name: analyze - if: ${{ !contains(matrix.os, '-arm') }} - uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3 diff --git a/src/carbon_memory.c b/src/carbon_memory.c index 00f5927..54f6131 100644 --- a/src/carbon_memory.c +++ b/src/carbon_memory.c @@ -1,12 +1,23 @@ // SPDX-License-Identifier: AGPL-3.0-only // Copyright (C) Wasym A. Alonso. All Rights Reserved. -#define CARBON_MEMORY__HDR_SZ (sizeof(usz)) +#define CARBON_MEMORY__MAX_ALIGN 16 +#define CARBON_MEMORY__HDR_SZ ((sizeof(usz) + CARBON_MEMORY__MAX_ALIGN - 1) & ~(CARBON_MEMORY__MAX_ALIGN - 1)) + +#ifdef _WIN32 +#define CARBON_MEMORY__ALLOC(sz) _aligned_malloc((sz), CARBON_MEMORY__MAX_ALIGN) +#define CARBON_MEMORY__REALLOC(p, sz) _aligned_realloc((p), (sz), CARBON_MEMORY__MAX_ALIGN) +#define CARBON_MEMORY__FREE(p) _aligned_free((p)) +#else +#define CARBON_MEMORY__ALLOC(sz) __builtin_malloc((sz)) +#define CARBON_MEMORY__REALLOC(p, sz) __builtin_realloc((p), (sz)) +#define CARBON_MEMORY__FREE(p) __builtin_free((p)) +#endif static usz carbon_memory__usage; void *carbon_memory_alloc(usz size) { - u8 *p = __builtin_malloc(size + CARBON_MEMORY__HDR_SZ); + u8 *p = CARBON_MEMORY__ALLOC(size + CARBON_MEMORY__HDR_SZ); CBN_ASSERT(p && "failed to allocate memory"); *(usz *)p = size; carbon_memory__usage += size; @@ -23,7 +34,7 @@ void *carbon_memory_realloc(void *p, usz size) { if (!p) return carbon_memory_alloc(size); u8 *raw_p = (u8 *)p - CARBON_MEMORY__HDR_SZ; usz old_sz = *(usz *)raw_p; - u8 *new_p = __builtin_realloc(raw_p, size + CARBON_MEMORY__HDR_SZ); + u8 *new_p = CARBON_MEMORY__REALLOC(raw_p, size + CARBON_MEMORY__HDR_SZ); CBN_ASSERT(new_p && "failed to reallocate memory"); *(usz *)new_p = size; carbon_memory__usage -= old_sz; @@ -35,7 +46,7 @@ void carbon_memory_free(void *p) { if (!p) return; u8 *raw_p = (u8 *)p - CARBON_MEMORY__HDR_SZ; carbon_memory__usage -= *(usz *)raw_p; - __builtin_free(raw_p); + CARBON_MEMORY__FREE(raw_p); } usz carbon_memory_usage(void) { @@ -43,8 +54,8 @@ usz carbon_memory_usage(void) { } void *carbon_memory_copy(void *dst, const void *src, usz n) { - u8 *d = (u8 *) dst; - const u8 *s = (const u8 *) src; + u8 *d = (u8 *)dst; + const u8 *s = (const u8 *)src; if (d == s || !n) return dst; if (d < s) while (n--) *d++ = *s++; else while (n--) d[n] = s[n]; @@ -52,20 +63,20 @@ void *carbon_memory_copy(void *dst, const void *src, usz n) { } void *carbon_memory_copy_raw(void *dst, const void *src, usz n) { - u8 *d = (u8 *) dst; - const u8 *s = (const u8 *) src; + u8 *d = (u8 *)dst; + const u8 *s = (const u8 *)src; while (n--) *d++ = *s++; return dst; } i32 carbon_memory_cmp(const void *v1, const void *v2, usz n) { - const u8 *l = (const u8 *) v1, *r = (const u8 *) v2; + const u8 *l = (const u8 *)v1, *r = (const u8 *)v2; for (; n && *l == *r; --n, ++l, ++r); return n ? *l - *r : 0; } void *carbon_memory_set(void *dst, i32 c, usz n) { - u8 *d = (u8 *) dst; - while (n--) *d++ = (u8) c; + u8 *d = (u8 *)dst; + while (n--) *d++ = (u8)c; return dst; } diff --git a/src/carbon_win.c b/src/carbon_win.c index c7a6dfc..5403cf8 100644 --- a/src/carbon_win.c +++ b/src/carbon_win.c @@ -2,6 +2,7 @@ // Copyright (C) Wasym A. Alonso. All Rights Reserved. static bool carbon_win__should_close; +static usz carbon_win__renderer_w, carbon_win__renderer_h; static CBN_Image carbon_win__icon; static bool carbon_win__cursor_visible = true; @@ -26,8 +27,7 @@ CBNINL bool carbon_win__poll_event(void); #if defined(__APPLE__) #include "carbon_win_macos.m" #elif defined(_WIN32) -// ... -#error Not implemented yet +#include "carbon_win_win32.inl" #elif defined(__linux__) || defined(__FreeBSD__) #include "carbon_win_x11.inl" #else diff --git a/src/carbon_win_gl.inl b/src/carbon_win_gl.inl new file mode 100644 index 0000000..124d83d --- /dev/null +++ b/src/carbon_win_gl.inl @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// Copyright (C) Wasym A. Alonso. All Rights Reserved. + +#pragma once + +#ifndef GL_VERTEX_SHADER +#define GL_VERTEX_SHADER 0x8B31 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_TEXTURE0 0x84C0 +#endif + +typedef char GLchar; + +static GLuint carbon_win__gl_tex; +static GLuint carbon_win__gl_vao; + +#define CARBON_WIN__GL_PROCS \ + x(GLuint, glCreateShader, GLenum) \ + x(void, glShaderSource, GLuint, GLsizei, const GLchar **, const GLint *) \ + x(void, glCompileShader, GLuint) \ + x(GLuint, glCreateProgram, void) \ + x(void, glAttachShader, GLuint, GLuint) \ + x(void, glLinkProgram, GLuint) \ + x(void, glUseProgram, GLuint) \ + x(void, glGenVertexArrays, GLsizei, GLuint *) \ + x(void, glBindVertexArray, GLuint) \ + x(void, glGetShaderiv, GLuint, GLenum, GLint *) \ + x(void, glGetProgramiv, GLuint, GLenum, GLint *) \ + x(void, glGetShaderInfoLog, GLuint, GLsizei, GLsizei *, GLchar *) \ + x(void, glGetProgramInfoLog, GLuint, GLsizei, GLsizei *, GLchar *) + +#define x(ret, name, ...) \ + typedef ret (*name ## _t)(__VA_ARGS__); \ + static name ## _t name; +CARBON_WIN__GL_PROCS; +#ifdef _WIN32 +x(void, glActiveTexture, GLenum); +#endif +#undef x + +CBNINL void *carbon_win__gl_func_loader(const char *name); + +CBNINL void carbon_win__gl_load_funcs(void) { +#define x(ret, name, ...) \ + name = (name ## _t) carbon_win__gl_func_loader(#name); \ + CBN_ASSERT(name && #name " failed to load"); + CARBON_WIN__GL_PROCS; +#ifdef _WIN32 + x(void, glActiveTexture, GLenum); +#endif +#undef x +} + +CBNINL void carbon_win__gl_init(usz w, usz h) { + carbon_win__renderer_w = w; + carbon_win__renderer_h = h; + carbon_win__gl_load_funcs(); + GLuint vert = glCreateShader(GL_VERTEX_SHADER); { + const GLchar *src = (const GLchar *)__src_carbon_win_shader_vert_glsl; + const GLint len = (GLint)__src_carbon_win_shader_vert_glsl_len; + glShaderSource(vert, 1, &src, &len); + glCompileShader(vert); + GLint ok; + glGetShaderiv(vert, GL_COMPILE_STATUS, &ok); + if (!ok) { + char log[512]; + glGetShaderInfoLog(vert, 512, 0, log); + CBN_ERROR("vert compile error: %s", log); + CARBON_UNREACHABLE; + } + } + GLuint frag = glCreateShader(GL_FRAGMENT_SHADER); { + const GLchar *src = (const GLchar *)__src_carbon_win_shader_frag_glsl; + const GLint len = (GLint)__src_carbon_win_shader_frag_glsl_len; + glShaderSource(frag, 1, &src, &len); + glCompileShader(frag); + GLint ok; + glGetShaderiv(frag, GL_COMPILE_STATUS, &ok); + if (!ok) { + char log[512]; + glGetShaderInfoLog(frag, 512, 0, log); + CBN_ERROR("frag compile error: %s", log); + CARBON_UNREACHABLE; + } + } + GLuint prog = glCreateProgram(); { + glAttachShader(prog, vert); + glAttachShader(prog, frag); + glLinkProgram(prog); + GLint ok; + glGetProgramiv(prog, GL_LINK_STATUS, &ok); + if (!ok) { + char log[512]; + glGetProgramInfoLog(prog, 512, 0, log); + CBN_ERROR("prog link error: %s", log); + CARBON_UNREACHABLE; + } + } + glUseProgram(prog); + glGenVertexArrays(1, &carbon_win__gl_vao); + glBindVertexArray(carbon_win__gl_vao); + glGenTextures(1, &carbon_win__gl_tex); + glBindTexture(GL_TEXTURE_2D, carbon_win__gl_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, + carbon_win__renderer_w, + carbon_win__renderer_h, + 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0); +} + +CBNINL void carbon_win__gl_render(const u32 *pixels, usz w, usz h) { + if (w != carbon_win__renderer_w || h != carbon_win__renderer_h) { + carbon_win__renderer_w = w; + carbon_win__renderer_h = h; + glViewport(0, 0, carbon_win__renderer_w, carbon_win__renderer_h); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, + carbon_win__renderer_w, + carbon_win__renderer_h, + 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0); + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, carbon_win__gl_tex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + carbon_win__renderer_w, + carbon_win__renderer_h, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, + pixels); + glClear(GL_COLOR_BUFFER_BIT); + glBindVertexArray(carbon_win__gl_vao); + glDrawArrays(GL_TRIANGLES, 0, 3); +} + +// Local Variables: +// mode: c +// End: diff --git a/src/carbon_win_macos.m b/src/carbon_win_macos.m index ff6a643..f5d1656 100644 --- a/src/carbon_win_macos.m +++ b/src/carbon_win_macos.m @@ -37,8 +37,6 @@ - (BOOL)windowShouldClose:(NSWindow *)win { static NSWindow *carbon_win__window; static CBNDelegate *carbon_win__delegate; -static usz carbon_win__renderer_w, carbon_win__renderer_h; - static id carbon_win__mtl_device; static id carbon_win__mtl_queue; static CAMetalLayer *carbon_win__mtl_layer; diff --git a/src/carbon_win_shader.frag.glsl b/src/carbon_win_shader.frag.glsl index 868c03e..030c7a6 100644 --- a/src/carbon_win_shader.frag.glsl +++ b/src/carbon_win_shader.frag.glsl @@ -1,8 +1,8 @@ -#version 450 +#version 330 core -layout(location = 0) in vec2 uv; -layout(location = 0) out vec4 color; -layout(binding = 0) uniform sampler2D tex; +in vec2 uv; +out vec4 color; +uniform sampler2D tex; void main() { color = texture(tex, uv); diff --git a/src/carbon_win_shader.vert.glsl b/src/carbon_win_shader.vert.glsl index f8113ad..ad7ef3a 100644 --- a/src/carbon_win_shader.vert.glsl +++ b/src/carbon_win_shader.vert.glsl @@ -1,6 +1,6 @@ -#version 450 +#version 330 core -layout(location = 0) out vec2 uv; +out vec2 uv; void main() { vec2 pos[] = vec2[3](vec2(-1, -1), vec2(3, -1), vec2(-1, 3)); diff --git a/src/carbon_win_win32.inl b/src/carbon_win_win32.inl new file mode 100644 index 0000000..55e3887 --- /dev/null +++ b/src/carbon_win_win32.inl @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// Copyright (C) Wasym A. Alonso. All Rights Reserved. + +#pragma once + +#include +#include + +#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#endif + +typedef HGLRC(WINAPI *wglCreateContextAttribsARB_t)(HDC, HGLRC, const int*); + +static HWND carbon_win__hwnd; +static HDC carbon_win__hdc; +static HGLRC carbon_win__hglrc; + +#include "carbon_win_gl.inl" + +CBNINL void *carbon_win__gl_func_loader(const char *name) { + return wglGetProcAddress(name); +} + +CBNINL CBN_Vec2 carbon_win__get_window_size(void) { + RECT r; + GetClientRect(carbon_win__hwnd, &r); + return carbon_math_vec2(r.right - r.left, r.bottom - r.top); +} + +CBN_Vec2 carbon_win_get_mouse_position(void) { + POINT p; + GetCursorPos(&p); + ScreenToClient(carbon_win__hwnd, &p); + CBN_Vec2 s = carbon_win__get_window_size(); + f32 sf_w = (f32)carbon_win__renderer_w/s.x, sf_h = (f32)carbon_win__renderer_h/s.y; + usz x = carbon_math_clamp(p.x * sf_w, 0, carbon_win__renderer_w - 1); + usz y = carbon_math_clamp(p.y * sf_h, 0, carbon_win__renderer_h - 1); + return carbon_math_vec2(x, y); +} + +CBNINL void carbon_win__renderer_init(usz w, usz h) { + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 0, + PFD_MAIN_PLANE, 0, 0, 0, 0 + }; + int pf = ChoosePixelFormat(carbon_win__hdc, &pfd); + SetPixelFormat(carbon_win__hdc, pf, &pfd); + HGLRC dummy = wglCreateContext(carbon_win__hdc); + wglMakeCurrent(carbon_win__hdc, dummy); + wglCreateContextAttribsARB_t wglCreateContextAttribsARB = (wglCreateContextAttribsARB_t)wglGetProcAddress("wglCreateContextAttribsARB"); + CBN_ASSERT(wglCreateContextAttribsARB && "WGL_ARB_create_context extension not supported"); + int attrs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0 + }; + carbon_win__hglrc = wglCreateContextAttribsARB(carbon_win__hdc, 0, attrs); + if (!carbon_win__hglrc) { + CBN_ERROR("Win32 error code: %lu", GetLastError()); + } CBN_ASSERT(carbon_win__hglrc && "wglCreateContextAttribsARB failed"); + wglMakeCurrent(carbon_win__hdc, 0); + wglDeleteContext(dummy); + wglMakeCurrent(carbon_win__hdc, carbon_win__hglrc); + carbon_win__gl_init(w, h); +} + +CBNINL CBN_Win_KeyCode carbon_win__map_key_code(WPARAM key) { + if (key >= 'A' && key <= 'Z') return CBN_Win_KeyCode_A + (key - 'A'); + if (key >= '0' && key <= '9') return CBN_Win_KeyCode_Zero + (key - '0'); + if (key >= VK_F1 && key <= VK_F12) return CBN_Win_KeyCode_F1 + (key - VK_F1); + switch (key) { + case VK_OEM_3: return CBN_Win_KeyCode_BackQuote; + case VK_ESCAPE: return CBN_Win_KeyCode_Escape; + case VK_TAB: return CBN_Win_KeyCode_Tab; + case VK_CAPITAL: return CBN_Win_KeyCode_CapsLock; + case VK_LSHIFT: return CBN_Win_KeyCode_LeftShift; + case VK_LCONTROL: return CBN_Win_KeyCode_LeftCtrl; + case VK_LWIN: return CBN_Win_KeyCode_LeftMeta; + case VK_LMENU: return CBN_Win_KeyCode_LeftAlt; + case VK_SPACE: return CBN_Win_KeyCode_Space; + case VK_RMENU: return CBN_Win_KeyCode_RightAlt; + case VK_RWIN: return CBN_Win_KeyCode_RightMeta; + case VK_RCONTROL: return CBN_Win_KeyCode_RightCtrl; + case VK_RSHIFT: return CBN_Win_KeyCode_RightShift; + case VK_RETURN: return CBN_Win_KeyCode_Return; + case VK_UP: return CBN_Win_KeyCode_UpArrow; + case VK_DOWN: return CBN_Win_KeyCode_DownArrow; + case VK_LEFT: return CBN_Win_KeyCode_LeftArrow; + case VK_RIGHT: return CBN_Win_KeyCode_RightArrow; + default: return CBN_Win_KeyCode_Count; + } +} + +LRESULT CALLBACK carbon_win__wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { + switch (msg) { + case WM_CLOSE: + carbon_win__should_close = true; + return 0; + case WM_SIZE: + if (carbon_win__hglrc) glViewport(0, 0, LOWORD(lp), HIWORD(lp)); + return 0; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: { + CBN_Win_KeyCode k = carbon_win__map_key_code(wp); + if (k != CBN_Win_KeyCode_Count) carbon_win__keys[k] = true; + return 0; + } + case WM_KEYUP: + case WM_SYSKEYUP: { + CBN_Win_KeyCode k = carbon_win__map_key_code(wp); + if (k != CBN_Win_KeyCode_Count) carbon_win__keys[k] = false; + return 0; + } + case WM_LBUTTONDOWN: + carbon_win__mouse_buttons[CBN_Win_MouseButton_Left] = true; + return 0; + case WM_LBUTTONUP: + carbon_win__mouse_buttons[CBN_Win_MouseButton_Left] = false; + return 0; + case WM_RBUTTONDOWN: + carbon_win__mouse_buttons[CBN_Win_MouseButton_Right] = true; + return 0; + case WM_RBUTTONUP: + carbon_win__mouse_buttons[CBN_Win_MouseButton_Right] = false; + return 0; + case WM_MBUTTONDOWN: + carbon_win__mouse_buttons[CBN_Win_MouseButton_Middle] = true; + return 0; + case WM_MBUTTONUP: + carbon_win__mouse_buttons[CBN_Win_MouseButton_Middle] = false; + return 0; + } + return DefWindowProcA(hwnd, msg, wp, lp); +} + +CBNINL void carbon_win__create_window(usz w, usz h, const char *title) { + HINSTANCE hinst = GetModuleHandleA(0); + WNDCLASSEXA wc = { + .cbSize = sizeof(WNDCLASSEXA), + .style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW, + .lpfnWndProc = carbon_win__wndproc, + .hInstance = hinst, + .hCursor = LoadCursor(NULL, IDC_ARROW), + .lpszClassName = "CarbonWinClass" + }; + RegisterClassExA(&wc); + DWORD style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; + RECT rect = {0, 0, w, h}; + AdjustWindowRect(&rect, style, FALSE); + carbon_win__hwnd = CreateWindowExA(0, wc.lpszClassName, title, style, + CW_USEDEFAULT, CW_USEDEFAULT, + rect.right - rect.left, rect.bottom - rect.top, + 0, 0, hinst, 0); + CBN_ASSERT(carbon_win__hwnd && "CreateWindowExA failed"); + carbon_win__hdc = GetDC(carbon_win__hwnd); + carbon_win__renderer_init(w, h); +} + +CBNINL void carbon_win__renderer_shutdown(void) { + wglMakeCurrent(0, 0); + if (carbon_win__hglrc) wglDeleteContext(carbon_win__hglrc); + carbon_win__hglrc = 0; +} + +CBNINL void carbon_win__destroy_window(void) { + carbon_win__renderer_shutdown(); + if (carbon_win__hdc) ReleaseDC(carbon_win__hwnd, carbon_win__hdc); + if (carbon_win__hwnd) DestroyWindow(carbon_win__hwnd); + carbon_win__hdc = 0; + carbon_win__hwnd = 0; +} + +CBNINL void carbon_win__renderer_present(const u32 *pixels, usz w, usz h) { + carbon_win__gl_render(pixels, w, h); + SwapBuffers(carbon_win__hdc); +} + +CBNINL bool carbon_win__poll_event(void) { + MSG msg; + if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) carbon_win__should_close = true; + else { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + return true; + } + return false; +} + +// Local Variables: +// mode: c +// End: diff --git a/src/carbon_win_x11.inl b/src/carbon_win_x11.inl index 85c6274..a992e2b 100644 --- a/src/carbon_win_x11.inl +++ b/src/carbon_win_x11.inl @@ -11,45 +11,15 @@ static Display *carbon_win__display; static Window carbon_win__window; static Atom carbon_win__wm_delete; static GLXContext carbon_win__glx_ctx; - static i32 carbon_win__glx_attrs[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; -static GLuint carbon_win__gl_tex; -static GLuint carbon_win__gl_vao; - -static usz carbon_win__renderer_w, carbon_win__renderer_h; - -//////////// GL functions //////////// -#define CARBON_WIN__GL_PROCS \ - x(GLuint, glCreateShader, GLenum) \ - x(void, glShaderBinary, GLsizei, const GLuint *, GLenum, const void *, GLsizei) \ - x(void, glSpecializeShader, GLuint, const GLchar *, GLuint, const GLuint *, const GLuint *) \ - x(GLuint, glCreateProgram, void) \ - x(void, glAttachShader, GLuint, GLuint) \ - x(void, glLinkProgram, GLuint) \ - x(void, glUseProgram, GLuint) \ - x(void, glGenVertexArrays, GLsizei, GLuint *) \ - x(void, glBindVertexArray, GLuint) \ - x(void, glGetShaderiv, GLuint, GLenum, GLint *) \ - x(void, glGetProgramiv, GLuint, GLenum, GLint *) \ - x(void, glGetProgramInfoLog, GLuint, GLsizei, GLsizei *, GLchar *) - -#define x(ret, name, ...) \ - typedef ret (*name ## _t)(__VA_ARGS__); \ - static name ## _t name; -CARBON_WIN__GL_PROCS; -#undef x +#include "carbon_win_gl.inl" -CBNINL void carbon_win__renderer_gl_load_funcs(void) { -#define x(ret, name, ...) \ - name = (name ## _t) glXGetProcAddress((const GLubyte *) #name); \ - CBN_ASSERT(name && #name " failed to load"); - CARBON_WIN__GL_PROCS; -#undef x +CBNINL void *carbon_win__gl_func_loader(const char *name) { + return glXGetProcAddress((const GLubyte *)name); } -////////////////////////////////////// CBNINL CBN_Vec2 carbon_win__get_window_size(void) { XWindowAttributes attrs; @@ -101,64 +71,14 @@ void carbon_win_set_fullscreen(bool yn) { } CBNINL void carbon_win__renderer_init(usz w, usz h) { - carbon_win__renderer_w = w; - carbon_win__renderer_h = h; - {// GLX context - i32 scr = DefaultScreen(carbon_win__display); - XVisualInfo *vi = glXChooseVisual(carbon_win__display, scr, carbon_win__glx_attrs); - CBN_ASSERT(vi && "glXChooseVisual failed"); - carbon_win__glx_ctx = glXCreateContext(carbon_win__display, vi, 0, GL_TRUE); - CBN_ASSERT(carbon_win__glx_ctx && "glXCreateContext failed"); - glXMakeCurrent(carbon_win__display, carbon_win__window, carbon_win__glx_ctx); - XFree(vi); - } - carbon_win__renderer_gl_load_funcs(); - {// GLSL shader - GLuint vert = glCreateShader(GL_VERTEX_SHADER); { - glShaderBinary(1, &vert, - GL_SHADER_BINARY_FORMAT_SPIR_V, - carbon_win_shader_vert_spv, - carbon_win_shader_vert_spv_len); - glSpecializeShader(vert, "main", 0, 0, 0); - GLint ok; - glGetShaderiv(vert, GL_COMPILE_STATUS, &ok); - CBN_ASSERT(ok && "vert specialization failed"); - } - GLuint frag = glCreateShader(GL_FRAGMENT_SHADER); { - glShaderBinary(1, &frag, - GL_SHADER_BINARY_FORMAT_SPIR_V, - carbon_win_shader_frag_spv, - carbon_win_shader_frag_spv_len); - glSpecializeShader(frag, "main", 0, 0, 0); - GLint ok; - glGetShaderiv(frag, GL_COMPILE_STATUS, &ok); - CBN_ASSERT(ok && "frag specialization failed"); - } - GLuint prog = glCreateProgram(); { - glAttachShader(prog, vert); - glAttachShader(prog, frag); - glLinkProgram(prog); - GLint ok; - glGetProgramiv(prog, GL_LINK_STATUS, &ok); - if (!ok) { - char log[512]; - glGetProgramInfoLog(prog, 512, 0, log); - CBN_ERROR("prog link error: %s", log); - CARBON_UNREACHABLE; - } - } - glUseProgram(prog); - glGenVertexArrays(1, &carbon_win__gl_vao); - glBindVertexArray(carbon_win__gl_vao); - glGenTextures(1, &carbon_win__gl_tex); - glBindTexture(GL_TEXTURE_2D, carbon_win__gl_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, - carbon_win__renderer_w, - carbon_win__renderer_h, - 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0); - } + i32 scr = DefaultScreen(carbon_win__display); + XVisualInfo *vi = glXChooseVisual(carbon_win__display, scr, carbon_win__glx_attrs); + CBN_ASSERT(vi && "glXChooseVisual failed"); + carbon_win__glx_ctx = glXCreateContext(carbon_win__display, vi, 0, GL_TRUE); + CBN_ASSERT(carbon_win__glx_ctx && "glXCreateContext failed"); + glXMakeCurrent(carbon_win__display, carbon_win__window, carbon_win__glx_ctx); + XFree(vi); + carbon_win__gl_init(w, h); } CBNINL void carbon_win__create_window(usz w, usz h, const char *title) { @@ -332,25 +252,7 @@ CBNINL bool carbon_win__poll_event(void) { } CBNINL void carbon_win__renderer_present(const u32 *pixels, usz w, usz h) { - if (w != carbon_win__renderer_w || h != carbon_win__renderer_h) { - carbon_win__renderer_w = w; - carbon_win__renderer_h = h; - glViewport(0, 0, carbon_win__renderer_w, carbon_win__renderer_h); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, - carbon_win__renderer_w, - carbon_win__renderer_h, - 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0); - } - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, carbon_win__gl_tex); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - carbon_win__renderer_w, - carbon_win__renderer_h, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, - pixels); - glClear(GL_COLOR_BUFFER_BIT); - glBindVertexArray(carbon_win__gl_vao); - glDrawArrays(GL_TRIANGLES, 0, 3); + carbon_win__gl_render(pixels, w, h); glXSwapBuffers(carbon_win__display, carbon_win__window); } diff --git a/src_build/hdrs/compiler_flags.h b/src_build/hdrs/compiler_flags.h index 1726dc8..492aec7 100644 --- a/src_build/hdrs/compiler_flags.h +++ b/src_build/hdrs/compiler_flags.h @@ -16,7 +16,7 @@ #if defined(__APPLE__) #define LDFLAGS "-framework Metal -framework QuartzCore -framework AppKit" #elif defined(_WIN32) -#define LDFLAGS "-ldnsapi -lws2_32 -lgdi32 -lntdll -lpthread -static" +#define LDFLAGS "-ldnsapi -lws2_32 -lopengl32 -lgdi32 -lntdll -lpthread -static" #elif defined(__linux__) || defined(__FreeBSD__) #define LDFLAGS "-lX11 -lGL" #else diff --git a/src_build/hdrs/dirs_n_files.h b/src_build/hdrs/dirs_n_files.h index 74a4c82..2f50d01 100644 --- a/src_build/hdrs/dirs_n_files.h +++ b/src_build/hdrs/dirs_n_files.h @@ -41,9 +41,8 @@ #define SHADER_OUT_FILE SHADER_NAME ".metallib" #define SHADER_INL_FILE SHADER_OUT_FILE ".inl" #elif defined(_WIN32) || defined(__linux__) || defined(__FreeBSD__) -#define SHADER_IN_FILE(stage) SRC_DIR "/" SHADER_NAME "." stage ".glsl" -#define SHADER_OUT_FILE(stage) SHADER_NAME "." stage ".spv" -#define SHADER_INL_FILE(stage) SHADER_OUT_FILE(stage) ".inl" +#define SHADER_FILE(stage) SRC_DIR "/" SHADER_NAME "." stage ".glsl" +#define SHADER_INL_FILE(stage) SHADER_NAME "." stage ".inl" #else #error Target platform is not supported #endif diff --git a/src_build/hdrs/utils.hh b/src_build/hdrs/utils.hh index c999f81..eac7fe2 100644 --- a/src_build/hdrs/utils.hh +++ b/src_build/hdrs/utils.hh @@ -15,7 +15,7 @@ inline void RunMetaprogram(fs::path &&exe) { RunCmd(s_exe.c_str()); #ifdef _WIN32 using namespace std::chrono_literals; - std::this_thread::sleep_for(100ms); + std::this_thread::sleep_for(500ms); assert(fs::remove(std::format("{}.exe", s_exe).c_str())); #else assert(fs::remove(s_exe)); diff --git a/src_build/make.cc b/src_build/make.cc index 0f438ac..3d55c70 100644 --- a/src_build/make.cc +++ b/src_build/make.cc @@ -69,21 +69,17 @@ void src_amalgamation(void) { } } -void build_and_embed_shader(void) { +void embed_shader(void) { #if defined(__APPLE__) printf(" METAL " SHADER_OUT_FILE "\n"); RunCmd("xcrun --sdk macosx metal " SHADER_IN_FILE " -o " SHADER_OUT_FILE " -target air64-apple-macos11.0"); printf(" GEN " SHADER_INL_FILE "\n"); RunCmd("xxd -i " SHADER_OUT_FILE " > " SHADER_INL_FILE); #elif defined(_WIN32) || defined(__linux__) || defined(__FreeBSD__) - printf(" SPIR-V " SHADER_OUT_FILE("vert") "\n"); - RunCmd("glslangValidator --quiet -G " SHADER_IN_FILE("vert") " -o " SHADER_OUT_FILE("vert")); - printf(" SPIR-V " SHADER_OUT_FILE("frag") "\n"); - RunCmd("glslangValidator --quiet -G " SHADER_IN_FILE("frag") " -o " SHADER_OUT_FILE("frag")); printf(" GEN " SHADER_INL_FILE("vert") "\n"); - RunCmd("xxd -i " SHADER_OUT_FILE("vert") " > " SHADER_INL_FILE("vert")); + RunCmd("xxd -i " SHADER_FILE("vert") " > " SHADER_INL_FILE("vert")); printf(" GEN " SHADER_INL_FILE("frag") "\n"); - RunCmd("xxd -i " SHADER_OUT_FILE("frag") " > " SHADER_INL_FILE("frag")); + RunCmd("xxd -i " SHADER_FILE("frag") " > " SHADER_INL_FILE("frag")); #else #error Target platform is not supported #endif @@ -112,10 +108,6 @@ void compile_and_link_lib(void) { printf(" RM " SHADER_INL_FILE "\n"); assert(fs::remove(SHADER_INL_FILE)); #elif defined(_WIN32) || defined(__linux__) || defined(__FreeBSD__) - printf(" RM " SHADER_OUT_FILE("vert") "\n"); - assert(fs::remove(SHADER_OUT_FILE("vert"))); - printf(" RM " SHADER_OUT_FILE("frag") "\n"); - assert(fs::remove(SHADER_OUT_FILE("frag"))); printf(" RM " SHADER_INL_FILE("vert") "\n"); assert(fs::remove(SHADER_INL_FILE("vert"))); printf(" RM " SHADER_INL_FILE("frag") "\n"); @@ -144,7 +136,7 @@ void build(void) { license_amalgamation(); hdr_amalgamation(); src_amalgamation(); - build_and_embed_shader(); + embed_shader(); compile_and_link_lib(); RunMetaprogram(TEST_EXE); build_tutorials();