math functions

This commit is contained in:
Nishi 2026-01-10 19:51:48 +09:00
commit 9d11089a75
Signed by: nishi
GPG key ID: 27EF69B208EB9343
15 changed files with 265 additions and 47 deletions

View file

@ -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)

View file

@ -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
}

View file

@ -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
}

View file

@ -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 <GearBox/GL/GL.h>
struct _GBGL {
GBEngine engine;
GLuint shadow_texture;
GLuint shadow_shader;
};
struct _GBClient {
GBEngine engine;
GBGL gl;
GBVector3 look_at;
GBVector3 camera;
};
struct _GBServer {

View file

@ -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;
}

View file

@ -1,6 +1,7 @@
#include <GearBox/Client.h>
#include <GearBox/Log.h>
#include <GearBox/GL.h>
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();
}

View file

@ -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;

38
engine/src/gl.c Normal file
View file

@ -0,0 +1,38 @@
#include <GearBox/GL.h>
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) {
}

64
engine/src/gl_camera.c Normal file
View file

@ -0,0 +1,64 @@
#include <GearBox/GL.h>
#include <GearBox/Math.h>
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]);
}

View file

@ -1,6 +1,7 @@
#include <GearBox/GL.h>
#include <GearBox/File.h>
#include <GearBox/Log.h>
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);

30
engine/src/gl_shadow.c Normal file
View file

@ -0,0 +1,30 @@
#include <GearBox/GL.h>
#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);
}
}

20
engine/src/gl_texture.c Normal file
View file

@ -0,0 +1,20 @@
#include <GearBox/GL.h>
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);
}

View file

@ -1,9 +1,40 @@
#include <GearBox/Math.h>
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);
}

View file

@ -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) {