From 9d11089a75a16792b589478280e217f2040386a6 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sat, 10 Jan 2026 19:51:48 +0900 Subject: [PATCH] math functions --- engine/CMakeLists.txt | 2 +- {fonts => engine/font}/8x16.bdf | 0 engine/include/GearBox/GL.h | 12 ++++- engine/include/GearBox/Math.h | 12 +++-- engine/include/GearBox/TypeDefs.h | 17 +++++++ engine/resource/shader/shadow.fs | 8 +-- engine/src/client.c | 10 +++- engine/src/file.c | 6 ++- engine/src/gl.c | 38 ++++++++++++++ engine/src/gl_camera.c | 64 ++++++++++++++++++++++++ engine/src/gl_shader.c | 9 ++-- engine/src/gl_shadow.c | 30 +++++++++++ engine/src/gl_texture.c | 20 ++++++++ engine/src/math.c | 82 +++++++++++++++++++------------ engine/src/server.c | 4 +- 15 files changed, 266 insertions(+), 48 deletions(-) rename {fonts => engine/font}/8x16.bdf (100%) create mode 100644 engine/src/gl.c create mode 100644 engine/src/gl_camera.c create mode 100644 engine/src/gl_shadow.c create mode 100644 engine/src/gl_texture.c diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 9e265c8..fa84751 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -24,7 +24,7 @@ target_include_directories(GearBox PRIVATE lz4) target_compile_definitions(GearBox PRIVATE _GEARBOX) target_link_libraries(GearBox PRIVATE gbnet) if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") -target_link_libraries(GearBox PRIVATE m) + target_link_libraries(GearBox PRIVATE m) endif() install_target(GearBox) diff --git a/fonts/8x16.bdf b/engine/font/8x16.bdf similarity index 100% rename from fonts/8x16.bdf rename to engine/font/8x16.bdf diff --git a/engine/include/GearBox/GL.h b/engine/include/GearBox/GL.h index 82809b2..16f3fba 100644 --- a/engine/include/GearBox/GL.h +++ b/engine/include/GearBox/GL.h @@ -11,7 +11,17 @@ extern "C" { #endif /* gl_shader.c */ -GBDECL int GBGLShaderPrepare(GBEngine engine, GLuint* shader, const char* vs, const char* fs); +GBDECL int GBGLShaderPrepare(GBGL gl, GLuint* shader, const char* vs, const char* fs); + +/* gl_texture.c */ +GBDECL int GBGLTexturePrepare(GBGL gl, GLuint* texture, unsigned char* rgba, int width, int height); + +/* gl_shadow.c */ +GBDECL void GBGLShadowInit(GBGL gl); + +/* gl.c */ +GBDECL GBGL GBGLCreate(GBClient client); +GBDECL void GBGLDestroy(GBGL gl); #ifdef __cplusplus } diff --git a/engine/include/GearBox/Math.h b/engine/include/GearBox/Math.h index 70243e6..8c6af6d 100644 --- a/engine/include/GearBox/Math.h +++ b/engine/include/GearBox/Math.h @@ -8,9 +8,15 @@ extern "C" { #endif -GBDECL void GBMathCross(double* out, double v00, double v01, double v02, double v10, double v11, double v12); -GBDECL void GBMathNormal3(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22); -GBDECL void GBMathNormal4(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22, double v30, double v31, double v32); +#define GBMathPi 3.14159265358979323846 + +GBDECL void GBMathCross3(GBVector3 r, GBVector3 v0, GBVector3 v1); +GBDECL void GBMathNormalize3(GBVector3 vec); +GBDECL void GBMathSubtract3(GBVector3 r, GBVector3 v0, GBVector3 v1); +GBDECL void GBMathAdd3(GBVector3 r, GBVector3 v0, GBVector3 v1); +GBDECL void GBMathNormal3x3(GBVector3 r, GBVector3 v0, GBVector3 v1, GBVector3 v2); +GBDECL void GBMathNormal3x4(GBVector3 r, GBVector3 v0, GBVector3 v1, GBVector3 v2, GBVector3 v3); +GBDECL double GBMathCot(double x); #ifdef __cplusplus } diff --git a/engine/include/GearBox/TypeDefs.h b/engine/include/GearBox/TypeDefs.h index 006be09..eaeb48a 100644 --- a/engine/include/GearBox/TypeDefs.h +++ b/engine/include/GearBox/TypeDefs.h @@ -46,13 +46,17 @@ typedef struct _GBServer* GBServer; typedef struct _GBEngine* GBEngine; typedef struct _GBFile* GBFile; typedef struct _GBResource* GBResource; +typedef struct _GBGL* GBGL; #else typedef void* GBClient; typedef void* GBServer; typedef void* GBEngine; typedef void* GBFile; typedef void* GBResource; +typedef void* GBGL; #endif +typedef double GBVector3[3]; +typedef double GBVector4[4]; typedef void (*GBGLSwapBufferCallback)(void); typedef void (*GBReadyCallback)(int width, int height); @@ -66,8 +70,21 @@ struct _GBResourceKV { }; #ifdef _GEARBOX +#include + +struct _GBGL { + GBEngine engine; + + GLuint shadow_texture; + GLuint shadow_shader; +}; + struct _GBClient { GBEngine engine; + + GBGL gl; + GBVector3 look_at; + GBVector3 camera; }; struct _GBServer { diff --git a/engine/resource/shader/shadow.fs b/engine/resource/shader/shadow.fs index abd43a0..b2748d4 100644 --- a/engine/resource/shader/shadow.fs +++ b/engine/resource/shader/shadow.fs @@ -1,10 +1,10 @@ #version 110 -uniform sampler2DShadow texture; +uniform sampler2DShadow depth_texture; varying vec4 shadow; varying vec4 color; uniform float solid_color; -uniform sampler2D texture_in; +uniform sampler2D current_texture; void main (void){ vec4 c; @@ -12,8 +12,8 @@ void main (void){ if(solid_color > 0.5){ c = color; }else{ - c = texture2D(texture_in, gl_TexCoord[1].st); + c = texture2D(current_texture, gl_TexCoord[1].st); } - gl_FragColor = (shadow + (gl_Color - shadow) * shadow2DProj(texture, gl_TexCoord[0])) * c; + gl_FragColor = (shadow + (gl_Color - shadow) * shadow2DProj(depth_texture, gl_TexCoord[0])) * c; } diff --git a/engine/src/client.c b/engine/src/client.c index d6ea643..b14e9e5 100644 --- a/engine/src/client.c +++ b/engine/src/client.c @@ -1,6 +1,7 @@ #include #include +#include GBClient GBClientCreate(GBEngine engine) { GBClient client = malloc(sizeof(*client)); @@ -9,14 +10,21 @@ GBClient GBClientCreate(GBEngine engine) { client->engine = engine; - GBLog(GBLogInfo, "Creating client"); + client->gl = GBGLCreate(client); + + GBLog(GBLogInfo, "Created client"); return client; } void GBClientDestroy(GBClient client) { + GBGLDestroy(client->gl); + free(client); + + GBLog(GBLogInfo, "Destroyed client"); } void GBClientStep(GBClient client) { + client->engine->param->gl_swapbuffer(); } diff --git a/engine/src/file.c b/engine/src/file.c index 54e188b..2536249 100644 --- a/engine/src/file.c +++ b/engine/src/file.c @@ -13,8 +13,6 @@ GBFile GBFileOpen(GBEngine engine, const char* path) { memset(file, 0, sizeof(*file)); - GBLog(GBLogInfo, "Opening %s", path); - file->seek = 0; if((file->fp = fopen(path, "rb")) != NULL) { @@ -22,6 +20,8 @@ GBFile GBFileOpen(GBEngine engine, const char* path) { file->size = ftell(file->fp); fseek(file->fp, 0, SEEK_SET); + GBLog(GBLogInfo, "Opened %s", path); + return file; } @@ -37,6 +37,8 @@ GBFile GBFileOpen(GBEngine engine, const char* path) { if(strcmp(engine->resource[i].key, s) == 0) { if((file->data = GBResourceGet(engine->resource[i].value, nam, &file->size)) != NULL) { free(s); + + GBLog(GBLogInfo, "Opened %s", path); return file; } break; diff --git a/engine/src/gl.c b/engine/src/gl.c new file mode 100644 index 0000000..543240f --- /dev/null +++ b/engine/src/gl.c @@ -0,0 +1,38 @@ +#include + +GBGL GBGLCreate(GBClient client) { + GLfloat lightamb[] = {0.25, 0.25, 0.25, 1.0}; + GLfloat lightcol[] = {1.0, 1.0, 1.0, 1.0}; + GBGL gl; + + gl = malloc(sizeof(*client->gl)); + + gl->engine = client->engine; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + glEnable(GL_BLEND); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + glEnable(GL_CULL_FACE); + + glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol); + glLightfv(GL_LIGHT0, GL_SPECULAR, lightcol); + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + GBGLShadowInit(gl); + + return gl; +} + +void GBGLDestroy(GBGL gl) { +} diff --git a/engine/src/gl_camera.c b/engine/src/gl_camera.c new file mode 100644 index 0000000..c2f4753 --- /dev/null +++ b/engine/src/gl_camera.c @@ -0,0 +1,64 @@ +#include + +#include + +void GBGLPerspective(GBGL gl, double fovy, double znear, double zfar) { + GLint vp[4]; + double aspect; + double f; + GLdouble matrix[16]; + int i; + + glGetIntegerv(GL_VIEWPORT, vp); + + aspect = (double)vp[2] / vp[3]; + f = GBMathCot(fovy / 180 * GBMathPi / 2); + + for(i = 0; i < 16; i++) matrix[i] = 0; + matrix[4 * 0 + 0] = f / aspect; + matrix[4 * 1 + 1] = f; + matrix[4 * 2 + 2] = (zfar + znear) / (znear - zfar); + matrix[4 * 3 + 2] = ((double)2 * zfar * znear) / (znear - zfar); + matrix[4 * 2 + 3] = -1; + + glLoadIdentity(); + glLoadMatrixd(matrix); +} + +void GBGLSetCamera(GBGL gl) { + GLdouble matrix[16]; + GBVector3 f; + GBVector3 up; + GBVector3 s; + GBVector3 u; + int i; + + GBMathSubtract3(f, gl->engine->client->look_at, gl->engine->client->camera); + GBMathNormalize3(f); + + up[0] = 0; + up[1] = 1; + up[2] = 0; + GBMathNormalize3(up); + + GBMathCross3(s, f, up); + GBMathNormalize3(s); + + GBMathCross3(u, s, f); + + for(i = 0; i < 16; i++) matrix[i] = 0; + matrix[4 * 0 + 0] = s[0]; + matrix[4 * 1 + 0] = s[1]; + matrix[4 * 2 + 0] = s[2]; + matrix[4 * 0 + 1] = u[0]; + matrix[4 * 1 + 1] = u[1]; + matrix[4 * 2 + 1] = u[2]; + matrix[4 * 0 + 2] = -f[0]; + matrix[4 * 1 + 2] = -f[1]; + matrix[4 * 2 + 2] = -f[2]; + matrix[4 * 3 + 3] = 1; + + glLoadIdentity(); + glLoadMatrixd(matrix); + glTranslated(-gl->engine->client->camera[0], -gl->engine->client->camera[1], -gl->engine->client->camera[2]); +} diff --git a/engine/src/gl_shader.c b/engine/src/gl_shader.c index 4bb1697..6a35fb5 100644 --- a/engine/src/gl_shader.c +++ b/engine/src/gl_shader.c @@ -1,6 +1,7 @@ #include #include +#include static void err(const char* path, GLuint shader) { GLint len, ret; @@ -13,12 +14,12 @@ static void err(const char* path, GLuint shader) { glGetShaderInfoLog(shader, len, &ret, e); - fprintf(stderr, "%s: %s\n", path, e); + GBLog(GBLogError, "%s: %s\n", path, e); free(e); } -int GBGLShaderPrepare(GBEngine engine, GLuint* shader, const char* vs, const char* fs) { +int GBGLShaderPrepare(GBGL gl, GLuint* shader, const char* vs, const char* fs) { GLuint vsi; GLuint fsi; GBFile f; @@ -28,7 +29,7 @@ int GBGLShaderPrepare(GBEngine engine, GLuint* shader, const char* vs, const cha char* fss; GLint st; - if((f = GBFileOpen(engine, vs)) != NULL) { + if((f = GBFileOpen(gl->engine, vs)) != NULL) { int sz = GBFileSize(f); vss = malloc(sz + 1); @@ -40,7 +41,7 @@ int GBGLShaderPrepare(GBEngine engine, GLuint* shader, const char* vs, const cha return 0; } - if((f = GBFileOpen(engine, fs)) != NULL) { + if((f = GBFileOpen(gl->engine, fs)) != NULL) { int sz = GBFileSize(f); fss = malloc(sz + 1); diff --git a/engine/src/gl_shadow.c b/engine/src/gl_shadow.c new file mode 100644 index 0000000..ca1ec0a --- /dev/null +++ b/engine/src/gl_shadow.c @@ -0,0 +1,30 @@ +#include + +#define SHADOW_WIDTH 1024 +#define SHADOW_HEIGHT 1024 + +void GBGLShadowInit(GBGL gl) { + glGenTextures(1, &gl->shadow_texture); + glBindTexture(GL_TEXTURE_2D, gl->shadow_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + + glBindTexture(GL_TEXTURE_2D, 0); + + if(GBGLShaderPrepare(gl, &gl->shadow_shader, "base:/shader/shadow.vs", "base:/shader/shadow.fs")) { + glUseProgram(gl->shadow_shader); + glUniform1i(glGetUniformLocation(gl->shadow_shader, "shadow_texture"), 1); + glUniform1i(glGetUniformLocation(gl->shadow_shader, "current_texture"), 0); + } +} diff --git a/engine/src/gl_texture.c b/engine/src/gl_texture.c new file mode 100644 index 0000000..6edc89f --- /dev/null +++ b/engine/src/gl_texture.c @@ -0,0 +1,20 @@ +#include + +int GBGLTexturePrepare(GBGL gl, GLuint* texture, unsigned char* rgba, int width, int height) { + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, 0); +} + +void GBGLTextureEnable(GBGL gl, GLuint texture) { + glBindTexture(GL_TEXTURE_2D, texture); + glEnable(GL_TEXTURE_2D); +} + +void GBGLTextureDisable(GBGL gl, GLuint texture) { + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/engine/src/math.c b/engine/src/math.c index 8bc73c1..8d5c628 100644 --- a/engine/src/math.c +++ b/engine/src/math.c @@ -1,9 +1,40 @@ #include -void GBMathCross(double* out, double v00, double v01, double v02, double v10, double v11, double v12) { - out[0] = v01 * v12 - v02 * v11; - out[1] = v02 * v10 - v00 * v12; - out[2] = v00 * v11 - v01 * v10; +void GBMathCross3(GBVector3 r, GBVector3 v0, GBVector3 v1) { + r[0] = v0[1] * v1[2] - v0[2] * v1[1]; + r[1] = v0[2] * v1[0] - v0[0] * v1[2]; + r[2] = v0[0] * v1[1] - v0[1] * v1[0]; +} + +void GBMathNormalize3(GBVector3 vec) { + double l = 0; + int i; + + for(i = 0; i < 3; i++) l += vec[i] * vec[i]; + + l = sqrt(l); + + if(l > 0) { + l = (double)1 / l; + } else { + l = 0; + } + + vec[0] *= l; + vec[1] *= l; + vec[2] *= l; +} + +void GBMathSubtract3(GBVector3 r, GBVector3 v0, GBVector3 v1) { + int i; + + for(i = 0; i < 3; i++) r[i] = v0[i] - v1[i]; +} + +void GBMathAdd3(GBVector3 r, GBVector3 v0, GBVector3 v1) { + int i; + + for(i = 0; i < 3; i++) r[i] = v0[i] + v1[i]; } /* @@ -11,21 +42,15 @@ void GBMathCross(double* out, double v00, double v01, double v02, double v10, do * | / * v1/ */ -void GBMathNormal3(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22) { - double v[3]; - double l = 0; - int i; +void GBMathNormal3x3(GBVector3 r, GBVector3 v0, GBVector3 v1, GBVector3 v2) { + GBVector3 t0, t1; - GBMathCross(&v[0], /**/ - v10 - v00, v11 - v01, v12 - v02, /**/ - v20 - v00, v21 - v01, v22 - v02 /**/ - ); + GBMathSubtract3(t0, v1, v0); + GBMathSubtract3(t0, v2, v0); - l = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + GBMathCross3(r, t0, t1); - for(i = 0; i < 3; i++) { - out[i] = v[i] / l; - } + GBMathNormalize3(r); } /* @@ -33,22 +58,17 @@ void GBMathNormal3(double* out, double v00, double v01, double v02, double v10, * | | * v1-v2 */ -void GBMathNormal4(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22, double v30, double v31, double v32) { - double v0[3]; - double v1[3]; - int i; - double l = 0; +void GBMathNormal3x4(GBVector3 r, GBVector3 v0, GBVector3 v1, GBVector3 v2, GBVector3 v3) { + GBVector3 t0, t1; - GBMathNormal3(&v0[0], v00, v01, v02, v10, v11, v12, v30, v31, v32); - GBMathNormal3(&v1[0], v10, v11, v12, v20, v21, v22, v30, v31, v32); + GBMathNormal3x3(t0, v0, v1, v3); + GBMathNormal3x3(t1, v1, v2, v3); - for(i = 0; i < 3; i++) { - out[i] = v0[i] + v1[i]; - } + GBMathAdd3(r, t0, t1); - l = sqrt(out[0] * out[0] + out[1] * out[1] + out[2] * out[2]); - - for(i = 0; i < 3; i++) { - out[i] = out[i] / l; - } + GBMathNormalize3(r); +} + +double GBMathCot(double x) { + return (double)1 / tan(x); } diff --git a/engine/src/server.c b/engine/src/server.c index f4e6375..e619f0d 100644 --- a/engine/src/server.c +++ b/engine/src/server.c @@ -9,13 +9,15 @@ GBServer GBServerCreate(GBEngine engine) { server->engine = engine; - GBLog(GBLogInfo, "Creating server"); + GBLog(GBLogInfo, "Created server"); return server; } void GBServerDestroy(GBServer server) { free(server); + + GBLog(GBLogInfo, "Destroyed server"); } void GBServerStep(GBServer server) {