diff options
author | chai <chaifix@163.com> | 2020-02-22 18:17:06 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-02-22 18:17:06 +0800 |
commit | 9c89460e136ed6c6c43704d9a3a15105e0f006b0 (patch) | |
tree | cd56f1dfc10650cfbfe7007ee3432ee32227edc3 | |
parent | d49f3d3f73709a9a7c0bce53aa13ed28a2bd27cb (diff) |
*wog
-rw-r--r-- | src/config.h | 8 | ||||
-rw-r--r-- | src/core/device.c | 1 | ||||
-rw-r--r-- | src/core/rasterizer.c | 14 | ||||
-rw-r--r-- | src/core/shader.h | 1 | ||||
-rw-r--r-- | src/core/vert.h | 5 | ||||
-rw-r--r-- | src/example/01_dot/01_dot.c | 1 | ||||
-rw-r--r-- | src/example/02_cube/02_cube.c | 1 | ||||
-rw-r--r-- | src/example/03_texture/03_texture.c | 9 | ||||
-rw-r--r-- | src/example/04_bloom/04_bloom.c | 1 | ||||
-rw-r--r-- | src/example/example.h | 10 | ||||
-rw-r--r-- | src/extend/mesh.h | 1 | ||||
-rw-r--r-- | src/extern/wog.c | 666 | ||||
-rw-r--r-- | src/extern/wog.h | 140 | ||||
-rw-r--r-- | src/main.c | 54 | ||||
-rw-r--r-- | src/math/mat.c | 2 | ||||
-rw-r--r-- | src/math/math.h | 1 | ||||
-rw-r--r-- | src/math/vec4.c | 9 | ||||
-rw-r--r-- | src/shaders/common.h | 45 | ||||
-rw-r--r-- | src/window.h | 8 |
19 files changed, 908 insertions, 69 deletions
diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..43c45af --- /dev/null +++ b/src/config.h @@ -0,0 +1,8 @@ +#ifndef _SOFTSHADEROOM_CONFIG_H_ +#define _SOFTSHADEROOM_CONFIG_H_ + +#define WIN32 1 + +#define PLATFORM WIN32 + +#endif
\ No newline at end of file diff --git a/src/core/device.c b/src/core/device.c index 23e4bb3..70ae11f 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -500,6 +500,7 @@ static void render_prims_triangle(uint varying_flag) { /*back face culling*/ if (ssr_isenable(ENABLE_BACKFACECULL)) { + /*cull in ndc*/ float w0 = 1 / c0->w, w1 = 1 / c1->w, w2 = 1 / c2->w; Vec3 ab, ac; ab.x = c1->x * w1 - c0->x * w0; diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c index a7d3544..d6a9fc1 100644 --- a/src/core/rasterizer.c +++ b/src/core/rasterizer.c @@ -92,17 +92,17 @@ void ssrR_triangle( ) { ssr_assert(CA && CB && CC && program); - Vec3 SA, SB, SC; - vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA); - vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB); - vec4_dividew(CC, &SC); ssrU_viewport(&SC, &SC); + Vec4 SA, SB, SC; + vec4_dividewnoz(CA, &SA); ssrU_viewport(&SA, &SA); + vec4_dividewnoz(CB, &SB); ssrU_viewport(&SB, &SB); + vec4_dividewnoz(CC, &SC); ssrU_viewport(&SC, &SC); /* puttriangle(&SA, &SB, &SC, 0xffff0000); return; */ - Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; + Vec4 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4 *v4tmp; uint itmp; #define swap(t, a, b) {t = a; a = b; b = t;} /*sort in y axis*/ @@ -163,7 +163,9 @@ void ssrR_triangle( vec3_scale(&bc, 1.f / (bc.x + bc.y + bc.z), &bc); \ /*early depth testing*/ \ if(depth_test){ \ - depth = bc.x*sa->z+bc.y*sb->z+bc.z*sc->z; \ + depth = bc.x*sa->z + bc.y*sb->z + bc.z*sc->z; \ + depth /= bc.x*sa->w + bc.y*sb->w + bc.z*sc->w; \ + /*depth = bc.x*sa->z+bc.y*sb->z+bc.z*sc->z;*//*wrong*/ \ pass_depth_test = ssr_testdepth(p.x, p.y, depth); \ } \ /*early stencil testing*/ \ diff --git a/src/core/shader.h b/src/core/shader.h index 3737e8c..26606b8 100644 --- a/src/core/shader.h +++ b/src/core/shader.h @@ -152,6 +152,7 @@ typedef struct { byte* output; /*fragment-in*/ } ActiveReg; +/*interpolation registers*/ Register registers[REG_TOTAL]; ActiveReg active_regs[REG_TOTAL]; diff --git a/src/core/vert.h b/src/core/vert.h index 8578d87..6c968b5 100644 --- a/src/core/vert.h +++ b/src/core/vert.h @@ -22,16 +22,15 @@ Color color32_tocolor(Color32* c); void color_tocolor32(Color c, Color32* out); void color32_saturate(Color32* c); -/*readonly*/ typedef struct Vert { uint index; Vec3 position; Vec3 normal; - Vec4 tangent; + Vec4 tangent; // w for handness Vec2 texcoord; Color color; /* - Vec2 texcoord1; + Vec2 texcoord1; // for lightmap Vec4 joint; Vec4 weight; */ diff --git a/src/example/01_dot/01_dot.c b/src/example/01_dot/01_dot.c index e2902ca..3305137 100644 --- a/src/example/01_dot/01_dot.c +++ b/src/example/01_dot/01_dot.c @@ -10,7 +10,6 @@ void onloaddot(void* data) { } void oneventdot(void* data) { - SDL_Event* e = (SDL_Event*)data; } void onupdatedot(void*data) { diff --git a/src/example/02_cube/02_cube.c b/src/example/02_cube/02_cube.c index 4e540e0..7e0840e 100644 --- a/src/example/02_cube/02_cube.c +++ b/src/example/02_cube/02_cube.c @@ -26,7 +26,6 @@ void onloadcube(void* data) { } void oneventcube(void* data) { - SDL_Event* e = (SDL_Event*)data; } float _t = 0; diff --git a/src/example/03_texture/03_texture.c b/src/example/03_texture/03_texture.c index ab39298..f10c41a 100644 --- a/src/example/03_texture/03_texture.c +++ b/src/example/03_texture/03_texture.c @@ -40,7 +40,7 @@ static Mesh* yingham_mesh; static Texture* cyborg_albedo; static Mesh* cyborg_mesh; -void onloadtexture(void* data) { +void onload_texture(void* data) { ssr_matrixmode(MATRIX_PROJECTION); ssr_loadidentity(); ssr_perspective(90, ssr_getaspect(), 0.1, 10); @@ -66,14 +66,13 @@ void onloadtexture(void* data) { cyborg_mesh = mesh_loadfromobj("res/cyborg/cyborg.obj"); } -void oneventtexture(void* data) { - SDL_Event* e = (SDL_Event*)data; +void onevent_texture(void* data) { } static float _t = 0; static Quat q; -void onupdatetexture(void*data) { +void onupdate_texture(void*data) { uint dt = *(uint*)data; _t += dt / 1000.f; @@ -100,7 +99,7 @@ void onupdatetexture(void*data) { ssr_setuniformmat4(0, &world2object); } -void ondrawtexture(void*data) { +void ondraw_texture(void*data) { ssr_clearcolor(0xff202020); ssr_cleardepth(); ssr_clearstencil(0); diff --git a/src/example/04_bloom/04_bloom.c b/src/example/04_bloom/04_bloom.c index 4a79669..037a9e1 100644 --- a/src/example/04_bloom/04_bloom.c +++ b/src/example/04_bloom/04_bloom.c @@ -58,7 +58,6 @@ void onloadbloom(void* data) { } void oneventbloom(void* data) { - SDL_Event* e = (SDL_Event*)data; } static float _t = 0; diff --git a/src/example/example.h b/src/example/example.h index 6cb9a64..bcf9ebc 100644 --- a/src/example/example.h +++ b/src/example/example.h @@ -3,13 +3,13 @@ #include "../ssr.h" #include "../util/type.h" -#include "SDL2/SDL.h" +//#include "SDL2/SDL.h" #define EXAMPLE(i)\ -extern void onload##i(void*);\ -extern void onevent##i(void*);\ -extern void onupdate##i(void*);\ -extern void ondraw##i(void*); +extern void onload_##i(void*);\ +extern void onevent_##i(void*);\ +extern void onupdate_##i(void*);\ +extern void ondraw_##i(void*); #define EXAMPLECUR texture diff --git a/src/extend/mesh.h b/src/extend/mesh.h index 2c52669..aa2a398 100644 --- a/src/extend/mesh.h +++ b/src/extend/mesh.h @@ -3,6 +3,7 @@ #include "../core/vert.h" +// typedef struct Mesh { Vert* vertices; uint vert_count; uint* triangles; uint tris_count; diff --git a/src/extern/wog.c b/src/extern/wog.c new file mode 100644 index 0000000..7b8af8d --- /dev/null +++ b/src/extern/wog.c @@ -0,0 +1,666 @@ +/** +* Copyright (c) 2015~2017 chai(neonum) +* +* This library is free software; you can redistribute it and/or modify it +* under the terms of the MIT license. See LICENSE for details. +*/ + +#include "wog.h" +#include <windows.h> +#include <malloc.h> +#include <stdio.h> +#include <memory.h> +#include <assert.h> + +#if WOG_API == WOG_GL +#include <gl/GL.h> +#include <gl/GLU.h> +#endif + + +#if WOG_API == WOG_GL +/** +* We need opengl32.lib and glu32.lib for using opengl functions on +* windows platform. +*/ +#pragma comment( lib, "opengl32.lib" ) +#pragma comment( lib, "glu32.lib" ) +#endif + +#define WINDOW_CLASS "WOG_WND" + +#define heap_alloc(T, C) (T*)malloc(sizeof(T)*(C)) +#define stack_alloc(T, C) (T*)alloca(sizeof(T)*(C)) +#define zero_mem(I, L) memset(I, 0, L) + +#define max(a, b) (a < b ? b : a) +#define min(a, b) (a < b ? a : b) +#define clamp(x, minv, maxv) (max(minv, min(x, maxv))) + +typedef struct wog_Window +{ + HWND hwnd; // Window handler + HDC hdc; // Device Context +#if WOG_API == WOG_GDI + wog_Surface* surface; // render buffer +#endif +}wog_Window; + +#if WOG_API == WOG_GL +typedef struct wog_GLContext +{ + HGLRC hrc; // Rendering Context +}wog_GLContext; +#endif + + +void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) +{ + UINT uMsg; + WPARAM wParam; + LPARAM lParam; + uMsg = msg->message; + wParam = msg->wParam; + lParam = msg->lParam; + HWND hWnd = window->hwnd; + + switch (uMsg) + { + case WM_SYSCOMMAND: + { + switch (wParam) + { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return ; + } + break; + } + return ; + + case WM_CLOSE: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_ECLOSE; + return ; + } + + case WM_KEYDOWN: + if ((wParam >= 0) && (wParam <= 255)) + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EKEYDOWN; + e->key = wParam; + + return ; + } + break; + + case WM_KEYUP: + if ((wParam >= 0) && (wParam <= 255)) + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EKEYUP; + e->key = wParam; + + return ; + } + break; + + case WM_MOUSEMOVE: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEMOTION; + wog_getMouse(window, &e->pos.x, &e->pos.y); + + return ; + } + + case WM_MOUSEWHEEL: // mousewheel scroll + { + int zDelta = GET_WHEEL_DELTA_WPARAM(wParam); + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEWHEEL; + e->wheel = zDelta > 0 ? 1 : -1; + return ; + } + + case WM_LBUTTONDOWN: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEBUTTONDOWN; + e->button = WOG_MOUSE_LBUTTON; + return ; + } + + case WM_RBUTTONDOWN: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEBUTTONDOWN; + e->button = WOG_MOUSE_RBUTTON; + return ; + } + + case WM_MBUTTONDOWN: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEBUTTONDOWN; + e->button = WOG_MOUSE_MIDDLE; + return ; + } + + case WM_LBUTTONUP: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEBUTTONUP; + e->button = WOG_MOUSE_LBUTTON; + return ; + } + + case WM_RBUTTONUP: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEBUTTONUP; + e->button = WOG_MOUSE_RBUTTON; + return ; + } + + case WM_MBUTTONUP: + { + zero_mem(e, sizeof(wog_Event)); + e->type = WOG_EMOUSEBUTTONUP; + e->button = WOG_MOUSE_MIDDLE; + return ; + } + + break; + + default: + e->type = WOG_EUNKNOWN; + break; + } + DefWindowProc(hWnd, uMsg, wParam, lParam); + return ; +} + + +int wog_pollEvent(wog_Window* wnd, wog_Event* e) +{ + MSG msg; + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) return 0; + TranslateMessage(&msg); + wog_handleEvent(wnd, &msg, e); + return 1; + } + return 0; +} + + +// on size changed callback; +static wog_Callback onSizeChanged = 0; +static wog_Callback onQuit = 0; + + +static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + // Get The Window Context + wog_Window* window = (wog_Window*)(GetWindowLong(hWnd, GWL_USERDATA)); + + // call callback functions +#define call(callback)\ + if (callback) \ + callback(window) + + switch (uMsg) + { + case WM_CREATE: + { + CREATESTRUCT* creation = (CREATESTRUCT*)(lParam); // Store Window Structure Pointer + window = (wog_Window*)(creation->lpCreateParams); // Get wog_Window + SetWindowLong(hWnd, GWL_USERDATA, (LONG)(window)); // Save it + } + return 0; + + case WM_CLOSE: // Post WM_CLOSE to message queue. + PostMessage(hWnd, WM_CLOSE, wParam, lParam); + return 0; + + case WM_SIZE: + call(onSizeChanged); + return 0; + + case WM_QUIT: + call(onQuit); + return 0; + + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +#undef call +} + + +void wog_registerResizeCallback(wog_Callback cal) +{ + onSizeChanged = cal; +} + + +void wog_registerQuitCallback(wog_Callback cal) +{ + onQuit = cal; +} + +wog_Surface* wog_getsurface(wog_Window* wnd) { + return wnd->surface; +} + +static int registerWindowClass() +{ + // Register A Window Class + WNDCLASSEX windowClass; // Window Class + zero_mem(&windowClass, sizeof(WNDCLASSEX)); // Make Sure Memory Is Cleared + + windowClass.cbSize = sizeof(WNDCLASSEX); // Size Of The windowClass Structure + windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraws The Window For Any Movement / Resizing + windowClass.lpfnWndProc = (WNDPROC)(WindowProc); // WindowProc Handles Messages + windowClass.hInstance = GetModuleHandle(0); // Set The Instance + windowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); // Class Background Brush Color + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer + windowClass.lpszClassName = WINDOW_CLASS; // Sets The Applications Classname + + if (RegisterClassEx(&windowClass) == 0) // Did Registering The Class Fail? + { + // NOTE: Failure, Should Never Happen + MessageBox(HWND_DESKTOP, "RegisterClassEx Failed!", "Error", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return False (Failure) + } + return TRUE; +} + +static void create_surface(HWND handle, int width, int height, wog_Surface **out_surface, HDC *out_memory_dc) { + BITMAPINFOHEADER bi_header; + HDC window_dc; + HDC memory_dc; + HBITMAP dib_bitmap; + HBITMAP old_bitmap; + unsigned char *buffer; // color buffer + wog_Surface *surface; + + window_dc = GetDC(handle); + memory_dc = CreateCompatibleDC(window_dc); + ReleaseDC(handle, window_dc); + + memset(&bi_header, 0, sizeof(BITMAPINFOHEADER)); + bi_header.biSize = sizeof(BITMAPINFOHEADER); + bi_header.biWidth = width; + bi_header.biHeight = -height; /* top-down */ + bi_header.biPlanes = 1; + bi_header.biBitCount = 32; + bi_header.biCompression = BI_RGB; + dib_bitmap = CreateDIBSection(memory_dc, (BITMAPINFO*)&bi_header, + DIB_RGB_COLORS, (void**)&buffer, NULL, 0); + assert(dib_bitmap != NULL); + old_bitmap = (HBITMAP)SelectObject(memory_dc, dib_bitmap); + DeleteObject(old_bitmap); + + surface = (wog_Surface*)malloc(sizeof(wog_Surface)); + surface->width = width; + surface->height = height; + surface->channels = 4; + surface->buffer = buffer; + + *out_surface = surface; + *out_memory_dc = memory_dc; +} + + +wog_Window* wog_createWindow(const char* title, int width, int height, int x, int y, uint32 flags) +{ + int client_w = width, client_h = height; + + if (! registerWindowClass()) + { + printf("Register window class failed.\n"); + return 0; + } + + wog_Window* wnd = heap_alloc(wog_Window, 1); + zero_mem(wnd, sizeof(wog_Window)); + + DWORD windowStyle = 0; // Define Our Window Style + windowStyle |= WS_POPUP; + windowStyle |= WS_OVERLAPPED; + windowStyle |= WS_CAPTION; + windowStyle |= WS_SYSMENU; + windowStyle |= WS_MINIMIZEBOX; + windowStyle |= WS_VISIBLE; +#define hasbit(fs, f) ((fs & f) == f) + if (hasbit(flags, WOG_RESIZABLE)) windowStyle |= WS_SIZEBOX; + if (hasbit(flags, WOG_DISABLE)) windowStyle |= WS_DISABLED; + + DWORD windowExtendedStyle = WS_EX_APPWINDOW; // Define The Window's Extended Style + + PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window +#if WOG_API == WOG_GL + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL +#endif + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + 32, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 16, // 16Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + RECT windowRect = { 0, 0, width, height }; + AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle); + width = windowRect.right - windowRect.left; + height = windowRect.bottom - windowRect.top; + wnd->hwnd = CreateWindowEx( + windowExtendedStyle, + WINDOW_CLASS, + title, + windowStyle, + x, y, + width, height, + HWND_DESKTOP, + 0, + GetModuleHandle(0), + wnd + ); + + if (wnd->hwnd == 0) + return 0; + + if (hasbit(flags, WOG_HIDDEN)) wog_hide(wnd); + + // init device context + wnd->hdc = GetDC(wnd->hwnd); + if (wnd->hdc== 0) + { + DestroyWindow(wnd->hwnd); + wnd->hwnd = 0; + return 0; + } + +#if WOG_API == WOG_GDI + create_surface(wnd->hwnd, client_w, client_h, &wnd->surface, &wnd->hdc); +#endif + +#if WOG_API == WOG_GL + // set pixel format + unsigned int pixelformat; + pixelformat = ChoosePixelFormat(wnd->hdc, &pfd); + if (pixelformat == 0) + { + wog_destroyWindow(wnd); + return 0; + } + + // set pixel format + if (SetPixelFormat(wnd->hdc, pixelformat, &pfd) == 0 ) + { + wog_destroyWindow(wnd); + return 0; + } +#endif + + return wnd; +} + +#if WOG_API == WOG_GL +wog_GLContext* wog_createGLContext(wog_Window* wnd) +{ + wog_GLContext* cxt = heap_alloc(wog_GLContext, 1); + zero_mem(cxt, sizeof(wog_GLContext)); + cxt->hrc = wglCreateContext(wnd->hdc); // create opengl context base on device context + if (cxt->hrc == 0) + { + free(cxt); + return 0; + } + return cxt; +} +#endif + +#if WOG_API == WOG_GL +int wog_makeCurrent(wog_Window* wnd, wog_GLContext* cxt) +{ + if (wnd && cxt) + { + if (wglMakeCurrent(wnd->hdc, cxt->hrc) == 0) + { + return 0; + } + return 1; + } + + return 0; +} +#endif + +#if WOG_API == WOG_GL +void wog_destroyGLContext(wog_GLContext* cxt) +{ + if (cxt && cxt->hrc) + { + wglDeleteContext(cxt->hrc); + free(cxt); + } +} +#endif + +void wog_updateSurface(wog_Window* wnd) { + HDC window_dc = GetDC(wnd->hwnd); + HDC memory_dc = wnd->hdc; + wog_Surface *surface = wnd->surface; + int width = surface->width; + int height = surface->height; + BitBlt(window_dc, 0, 0, width, height, memory_dc, 0, 0, SRCCOPY); + ReleaseDC(wnd->hwnd, window_dc); +} + +void wog_destroyWindow(wog_Window* wnd) +{ + if (wnd) + { + ReleaseDC(wnd->hwnd, wnd->hdc); + DestroyWindow(wnd->hwnd); + free(wnd); + } +} + + +static void UnEscapeQuotes(char *arg) +{ + char *last = NULL; + + while (*arg) { + if (*arg == '"' && *last == '\\') { + char *c_curr = arg; + char *c_last = last; + + while (*c_curr) { + *c_last = *c_curr; + c_last = c_curr; + c_curr++; + } + *c_last = '\0'; + } + last = arg; + arg++; + } +} + + +/* Parse a command line buffer into arguments */ +static int ParseCommandLine(char *cmdline, char **argv) +{ + char *bufp; + char *lastp = NULL; + int argc, last_argc; + + argc = last_argc = 0; + for (bufp = cmdline; *bufp; ) { + /* Skip leading whitespace */ + while (isspace(*bufp)) { + ++bufp; + } + /* Skip over argument */ + if (*bufp == '"') { + ++bufp; + if (*bufp) { + if (argv) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while (*bufp && (*bufp != '"' || (lastp && *lastp == '\\'))) { + lastp = bufp; + ++bufp; + } + } + else { + if (*bufp) { + if (argv) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while (*bufp && !isspace(*bufp)) { + ++bufp; + } + } + if (*bufp) { + if (argv) { + *bufp = '\0'; + } + ++bufp; + } + + /* Strip out \ from \" sequences */ + if (argv && last_argc != argc) { + UnEscapeQuotes(argv[last_argc]); + } + last_argc = argc; + } + if (argv) { + argv[argc] = NULL; + } + return(argc); +} + + +#ifdef main +#undef main +#endif + + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +/* The VC++ compiler needs main defined */ +#define console_main main +#endif + +extern int wog_main(int argc, char* argv[]); + +/** +* Entry of console application. +*/ +int console_main(int argc, char* argv[]) +{ + int status = wog_main(argc, argv); + return status; +} + + +/** +* Entry of windows application. +*/ +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +{ + char* temp = GetCommandLine(); + int len = strlen(temp) + 1; + char* cmd = stack_alloc(char, len); + strcpy(cmd, temp); + cmd[len - 1] = '\0'; + + int argc = 0; + char** argv = 0; + argc = ParseCommandLine(cmd, 0); + ParseCommandLine(cmd, 0); + argv = stack_alloc(char*, argc + 1); + ParseCommandLine(cmd, argv); + + int status = console_main(argc, argv); + + return 0; +} + + +void wog_swapBuffers(wog_Window* wnd) +{ + if (wnd) + { + SwapBuffers(wnd->hdc); + } +} + + +void wog_getMouse(wog_Window* wnd, int *x, int *y) +{ + POINT p; + GetCursorPos(&p); + ScreenToClient(wnd->hwnd, &p); + int w, h; + wog_getwindowsize(wnd, &w, &h); + *x = clamp(p.x, 0, w); + *y = clamp(p.y, 0, h); +} + + +void wog_getwindowsize(wog_Window* wnd, int* width, int* height) +{ + RECT r; + GetClientRect(wnd->hwnd, &r); + *width = r.right; + *height = r.bottom; +} + + +void wog_show(wog_Window* wnd) +{ + ShowWindow(wnd->hwnd, SW_SHOW); +} + + +void wog_hide(wog_Window* wnd) +{ + ShowWindow(wnd->hwnd, SW_HIDE); +} + + +void wog_sleep(int ms) +{ + Sleep(ms); +} + +int wog_tick() +{ + return GetTickCount(); +}
\ No newline at end of file diff --git a/src/extern/wog.h b/src/extern/wog.h new file mode 100644 index 0000000..f616d82 --- /dev/null +++ b/src/extern/wog.h @@ -0,0 +1,140 @@ +/** +* Copyright (c) 2015~2017 chai(neonum) +* +* This library is free software; you can redistribute it and/or modify it +* under the terms of the MIT license. See LICENSE for details. +*/ + +#ifndef _WOG_H +#define _WOG_H +#include <Windows.h> // for virtual key value + +#define WOG_GL 1 +#define WOG_GDI 2 + +#define WOG_API WOG_GDI + +typedef unsigned int uint32; +typedef unsigned short uint16; + +enum // event type +{ + WOG_EUNKNOWN = 0, // unknown event + + WOG_EKEYDOWN, // key pressed + WOG_EKEYUP, // key released + + WOG_EMOUSEMOTION, // mouse motion + WOG_EMOUSEWHEEL, // mouse wheel scrolling + WOG_EMOUSEBUTTONDOWN, // mosue button down + WOG_EMOUSEBUTTONUP, // mosue button down + + WOG_ECLOSE, // close window +}; + +enum // mouse button event, e.button value +{ + WOG_MOUSE_LBUTTON, // left mouse button + WOG_MOUSE_RBUTTON, // right mouse button + WOG_MOUSE_MIDDLE, // middle button +}; + +typedef struct wog_Event +{ + int type; + union // event value + { + int key; // for key, simply use windows virtual key value + // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx + struct // for mouse motion + { + int x, y; // mouse position + }pos; + int wheel; // 1 indicate scroll up and -1 indicate scrool down + int button; // mouse button + }; +}wog_Event; + +typedef struct { + int width, height, channels; + unsigned char* buffer; +} wog_Surface; + +/** +* Entry of user program which defined in user project. You need provide +* this function's defination. +*/ +#define main wog_main +extern int wog_main(int argc, char* argv[]); + +typedef struct wog_Window wog_Window; + +#if WOG_API == WOG_GL +/** +* Struct that hold opengl context generated by wglCreateContext() which +* defined in opengl32.lib +*/ +typedef struct wog_GLContext wog_GLContext; +#endif + +enum // window style flag +{ + WOG_HIDDEN = 4, + WOG_RESIZABLE = 8, + WOG_DISABLE = 16, +}; + +/** +* Create window with given configures. +* flag would be: +* WOG_HIDDEN +* WOG_RESIZABLE +* WOG_DISABLE +* or just 0; +*/ +wog_Window* wog_createWindow(const char* title, int width, int height, int x, int y, uint32 flags); + +#if WOG_API == WOG_GL +wog_GLContext* wog_createGLContext(wog_Window* wnd); + +int wog_makeCurrent(wog_Window* wnd, wog_GLContext* cxt); + +void wog_destroyGLContext(wog_GLContext* cxt); +#endif + +void wog_destroyWindow(wog_Window* wnd); + +#if WOG_API == WOG_GL +void wog_swapBuffers(wog_Window* wnd); +#endif + +#if WOG_API == WOG_GDI +void wog_updateSurface(wog_Window* wnd); +#endif + +int wog_pollEvent(wog_Window* wnd, wog_Event* e); + +void wog_getMouse(wog_Window* wnd, int *x, int *y); + +// get current ticks +int wog_tick(); + +void wog_sleep(int ms); + +void wog_getwindowsize(wog_Window* wnd, int* width, int* height); + +void wog_show(wog_Window* wnd); + +void wog_hide(wog_Window* wnd); + +typedef void(*wog_Callback)(wog_Window* wnd) ; + +/** +* Register callback functions. +*/ +void wog_registerResizeCallback(wog_Callback cal); +void wog_registerQuitCallback(wog_Callback cal); + +wog_Surface* wog_getsurface(wog_Window* wnd); + +#endif
\ No newline at end of file @@ -1,12 +1,10 @@ -#include <SDL2/SDL.h> #include <stdio.h> #include <windows.h> #include "math/math.h" #include "util/assert.h" #include "ssr.h" #include "example/example.h" - -SDL_Surface* suf; +#include "extern/wog.h" #define SCREEN_WIDTH 600 #define SCREEN_HEIGHT 480 @@ -20,7 +18,7 @@ F ondraw; /*macro这里需要绕一下弯*/ /*https://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg*/ #define SETEXAMPLEF(f, e) \ -f = f##e; +f = f##_##e; #define SETEXAMPLE(i) \ SETEXAMPLEF(onload, i)\ @@ -28,46 +26,35 @@ SETEXAMPLEF(ondraw, i)\ SETEXAMPLEF(onevent, i)\ SETEXAMPLEF(onupdate, i) -int main(int argc, char* argv[]) -{ - if (SDL_Init(SDL_INIT_EVENTS | SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0) - return 1; - SDL_Window* wnd = SDL_CreateWindow("Soft Shade Room", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); - SDL_Event e; - suf = SDL_GetWindowSurface(wnd); - /* ARGB format */ - ssr_assert(suf->format->BitsPerPixel == 32); - ssr_assert(suf->format->Rshift == 16); - ssr_assert(suf->format->Gshift == 8); - ssr_assert(suf->format->Bshift == 0); - +int main(int argc, char* argv[]) { + wog_Window* wnd = wog_createWindow("test", SCREEN_WIDTH, SCREEN_HEIGHT, 500, 500, 0); + wog_show(wnd); + wog_Surface* surface = wog_getsurface(wnd); // ARGB format /* init ssr */ ssr_Config config = { SCREEN_WIDTH, SCREEN_HEIGHT, 0, - suf->pixels + surface->buffer }; ssr_init(&config); - SETEXAMPLE(EXAMPLECUR); - onload(0); - /* main loop */ - uint prev = SDL_GetTicks(); + uint prev = wog_tick(); uint dt = 0; uint frame_count = 0; uint time_stamp = 0; + wog_Event e; while (1) { - while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) { + while (wog_pollEvent(wnd, &e)) { + if (e.type == WOG_ECLOSE) { goto quit; } else { onevent(&e); } } - - dt = SDL_GetTicks() - prev; + + dt = wog_tick() - prev; prev += dt; time_stamp += dt; ++frame_count; @@ -76,17 +63,16 @@ int main(int argc, char* argv[]) time_stamp -= 1000; frame_count = 0; } - + onupdate(&dt); ondraw(0); ssr_present(); - SDL_UpdateWindowSurface(wnd); - - /*Sleep(1);*/ /*reduce cpu using*/ + wog_updateSurface(wnd); + Sleep(1); /*reduce cpu using*/ } + + quit: + wog_destroyWindow(wnd); -quit: - SDL_Quit(); - - return 0; + return 1; } diff --git a/src/math/mat.c b/src/math/mat.c index 8b32ba2..592dd5e 100644 --- a/src/math/mat.c +++ b/src/math/mat.c @@ -706,7 +706,7 @@ bool mat4_toeuler(Mat4* in, Euler* out) { } } -/*from unity src*/ +/*from unity source*/ /*https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/*/ void mat4_toquat(Mat4* in, Quat* out) { // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes diff --git a/src/math/math.h b/src/math/math.h index 1c2a9c0..1c65c01 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -179,6 +179,7 @@ void vec3_lerp(Vec3* v1, Vec3* v2, float t, Vec3* out); void vec3_slerp(Vec3* v1, Vec3* v2, float t, Vec3* out); void vec4_dividew(Vec4* v, Vec3* out); +void vec4_dividewnoz(Vec4* v, Vec4* out); void vec4_tostring(Vec4* v, char buf[]); void vec4_print(Vec4* v); diff --git a/src/math/vec4.c b/src/math/vec4.c index 71ec6b6..3d6df46 100644 --- a/src/math/vec4.c +++ b/src/math/vec4.c @@ -16,6 +16,15 @@ void vec4_dividew(Vec4* v, Vec3* out) { out->z = v->z * w; } +void vec4_dividewnoz(Vec4* v, Vec4* out) { + ssr_assert(out && v); + float w = 1.f / v->w; + out->x = v->x * w; + out->y = v->y * w; + out->z = v->z; + out->w = v->w; +} + void vec4_tostring(Vec4* v, char buf[]) { sprintf(buf, "%8.3f %8.3f %8.3f %8.3f", v->x, v->y, v->z, v->w); } diff --git a/src/shaders/common.h b/src/shaders/common.h index cae9309..7e0ca5f 100644 --- a/src/shaders/common.h +++ b/src/shaders/common.h @@ -1,12 +1,33 @@ #ifndef _SOFTSHADEROOM_COMMON_HEADER_H_ #define _SOFTSHADEROOM_COMMON_HEADER_H_ - -/* -** Common shader header -*/ #include "../core/shader.h" -extern void ssrR_putline(int x0, int y0, int x1, int y1, Color color); +/************************************************************************/ +/* constants */ +/************************************************************************/ + +#define SSR_PI 3.14159265359f +#define SSR_TWO_PI 6.28318530718f +#define SSR_FOUR_PI 12.56637061436f +#define SSR_INV_PI 0.31830988618f +#define SSR_INV_TWO_PI 0.15915494309f +#define SSR_INV_FOUR_PI 0.07957747155f +#define SSR_HALF_PI 1.57079632679f +#define SSR_INV_HALF_PI 0.636619772367f + +/************************************************************************/ +/* variables */ +/************************************************************************/ + +#define _model_matrix (uniforms->model) +#define _view_matrix (uniforms->view) +#define _proj_matrix (uniforms->projection) +#define _mvp_matrix (uniforms->mvp) +#define _it_model_matrix /*inverse-transpose model matrix if needed*/ + +/************************************************************************/ +/* functions */ +/************************************************************************/ /*shader built in functions*/ Vec3 normal_from_color(Color32 c32); @@ -20,6 +41,8 @@ Vec2 texsize(Texture* texture); do{ \ if(cond) return 0; \ }while(0) +#define discard() return 0 +#define keep() return 1 #define MVP_PROCESS \ do{ \ @@ -27,18 +50,16 @@ static Vec4 p; p.xyz = in->vertex->position; p.w = 1; \ mat4_mulvec4(uniforms->mvp, &p, clipcoord); \ }while(0) -#define _model_matrix (uniforms->model) -#define _view_matrix (uniforms->view) -#define _proj_matrix (uniforms->projection) -#define _mvp_matrix (uniforms->mvp) -#define _inverse_model_matrix (uniforms->inverse_model) - #define object2clip(pos, out) mat4_mulvec4(_mvp_matrix, pos, out); /*need defined _it_model_matrix of model matrix, i-nverse, t-ranspose*/ #define object2world_normal(normal, out) \ mat4_mulvec4(_it_model_matrix, normal, out) - +/*take sample from normal map and translate to normal*/ +#define unpack_normal(color, out_v3) \ +out_v3->x = color.x * 2 - 1; \ +out_v3->y = color.y * 2 - 1; \ +out_v3->z = color.z * 2 - 1; #endif
\ No newline at end of file diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..8983a89 --- /dev/null +++ b/src/window.h @@ -0,0 +1,8 @@ +#ifndef _SOFTSHADEROOM_WINDOW_H_ +#define _SOFTSHADEROOM_WINDOW_H_ + +typedef struct { + const char* code; +} Event; + +#endif
\ No newline at end of file |