This commit is contained in:
Nishi 2026-01-12 01:03:18 +09:00
commit 57685ed075
Signed by: nishi
GPG key ID: 27EF69B208EB9343
20 changed files with 282 additions and 13 deletions

View file

@ -2,6 +2,7 @@
#include <GearBox/Log.h>
#include <GearBox/GL.h>
#include <GearBox/SkyBox.h>
#include <GearBox/Math.h>
GBClient GBClientCreate(GBEngine engine) {
@ -11,12 +12,12 @@ GBClient GBClientCreate(GBEngine engine) {
client->engine = engine;
client->camera[0] = 5;
client->camera[1] = 5;
client->camera[2] = 5;
client->camera[0] = 0;
client->camera[1] = 0;
client->camera[2] = 0;
client->look_at[0] = 0;
client->look_at[1] = 0;
client->look_at[1] = 1;
client->look_at[2] = 0;
client->light0[0] = 5;
@ -26,6 +27,8 @@ GBClient GBClientCreate(GBEngine engine) {
client->gl = GBGLCreate(client);
client->skybox = GBSkyBoxOpen(client, "base:/skybox");
GBLog(GBLogInfo, "Created client");
return client;
@ -39,8 +42,6 @@ void GBClientDestroy(GBClient client) {
GBLog(GBLogInfo, "Destroyed client");
}
static double r = 0;
static void scene(GBClient client) {
}
@ -54,13 +55,16 @@ void GBClientStep(GBClient client) {
GBGLShadowAfterMapping(client->gl);
}
if(client->skybox != NULL) GBSkyBoxDraw(client->skybox);
scene(client);
GBGLShadowEnd(client->gl);
client->engine->param->gl_swapbuffer();
client->camera[0] = cos(r) * 5;
client->camera[2] = sin(r) * 5;
static double r = 0;
client->look_at[0] = cos(r) * 5;
client->look_at[2] = sin(r) * 5;
r += 0.1;
}

View file

@ -60,3 +60,14 @@ void GBGLSetLight(GBGL gl) {
glLightfv(GL_LIGHT0, GL_POSITION, f);
}
void GBGLPolygon(GBGL gl, int pairs, GBVector3* vert, GBVector2* tex) {
int i;
glBegin(GL_POLYGON);
for(i = 0; i < pairs; i++) {
if(tex != NULL) glTexCoord2f(tex[i][0], tex[i][1]);
glVertex3f(vert[i][0], vert[i][1], vert[i][2]);
}
glEnd();
}

View file

@ -9,7 +9,7 @@ void GBGLCameraPerspective(GBGL gl, GBNumber width, GBNumber height) {
int i;
GBNumber fovy = 60.0;
GBNumber znear = 0.01;
GBNumber zfar = 100.0;
GBNumber zfar = GBGLMaxDistance;
aspect = width / height;
f = GBMathCot(fovy / 180 * GBMathPi / 2);

View file

@ -1,6 +1,29 @@
#include <GearBox/GL.h>
int GBGLTexturePrepare(GBGL gl, GLuint* texture, unsigned char* rgba, int width, int height) {
#include <GearBox/File.h>
#include <stb_image.h>
void GBGLTexturePrepare(GBGL gl, GLuint* texture, unsigned char* rgba, int width, int height) {
int y;
/* image gets flipped here... because opengl coord system is quite confusing */
for(y = 0; y < height / 2; y++) {
int x;
for(x = 0; x < width; x++) {
int p;
for(p = 0; p < 4; p++) {
unsigned char* s1 = &rgba[(y * width + x) * 4 + p];
unsigned char* s2 = &rgba[((height - 1 - y) * width + x) * 4 + p];
unsigned char p1 = *s1;
unsigned char p2 = *s2;
*s2 = p1;
*s1 = p2;
}
}
}
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
@ -18,3 +41,48 @@ void GBGLTextureDisable(GBGL gl, GLuint texture) {
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
int GBGLTextureLoadFile(GBGL gl, GLuint* texture, int* width, int* height, const char* filename) {
GBFile f = GBFileOpen(gl->engine, filename);
unsigned char* data;
unsigned char* rgba;
unsigned long sz;
int ch;
int st = 1;
int w, h;
if(f == NULL) return 0;
sz = GBFileSize(f);
data = malloc(sz);
GBFileRead(f, data, sz);
GBFileClose(f);
if((rgba = stbi_load_from_memory(data, sz, &w, &h, &ch, 4)) == NULL) {
st = 0;
} else {
GBGLTexturePrepare(gl, texture, rgba, w, h);
free(rgba);
}
if(width != NULL) *width = w;
if(height != NULL) *height = h;
free(data);
return st;
}
void GBGLTextureSet(GBGL gl, GLuint texture) {
glBindTexture(GL_TEXTURE_2D, texture);
if(texture == 0) {
glDisable(GL_TEXTURE_2D);
} else {
glEnable(GL_TEXTURE_2D);
}
}
void GBGLTextureDelete(GBGL gl, GLuint texture) {
glDeleteTextures(1, &texture);
}

129
engine/src/skybox.c Normal file
View file

@ -0,0 +1,129 @@
#include <GearBox/SkyBox.h>
#include <GearBox/GL.h>
#include <GearBox/String.h>
GBSkyBox GBSkyBoxOpen(GBClient client, const char* base) {
GBSkyBox skybox = malloc(sizeof(*skybox));
char* p;
void* ptr[12];
int i;
memset(skybox, 0, sizeof(*skybox));
skybox->engine = client->engine;
ptr[0] = &skybox->left;
ptr[1] = "/left.png";
ptr[2] = &skybox->right;
ptr[3] = "/right.png";
ptr[4] = &skybox->front;
ptr[5] = "/front.png";
ptr[6] = &skybox->back;
ptr[7] = "/back.png";
ptr[8] = &skybox->up;
ptr[9] = "/up.png";
ptr[10] = &skybox->down;
ptr[11] = "/down.png";
for(i = 0; i < 12; i += 2) {
p = GBStringConcat(base, ptr[i + 1]);
if(!GBGLTextureLoadFile(client->gl, ptr[i], NULL, NULL, p)) {
free(p);
GBSkyBoxClose(skybox);
return NULL;
}
free(p);
}
return skybox;
}
void GBSkyBoxDraw(GBSkyBox skybox) {
GBGL gl = skybox->engine->client->gl;
int i;
GBVector3 v[4];
GBVector2 t[4];
GBNumber s = 0.0001;
t[0][0] = 0, t[0][1] = 1;
t[1][0] = 0, t[1][1] = 0;
t[2][0] = 1, t[2][1] = 0;
t[3][0] = 1, t[3][1] = 1;
GBGLIgnoreDepth(gl);
GBGLShadowDisable(gl);
for(i = 0; i < 6; i++) {
GLuint tex;
int j, k;
if(i == 0) {
tex = skybox->front;
v[0][0] = -1 - s, v[0][1] = 1 + s, v[0][2] = -1;
v[1][0] = -1 - s, v[1][1] = -1 - s, v[1][2] = -1;
v[2][0] = 1 + s, v[2][1] = -1 - s, v[2][2] = -1;
v[3][0] = 1 + s, v[3][1] = 1 + s, v[3][2] = -1;
} else if(i == 1) {
tex = skybox->back;
v[0][0] = 1 + s, v[0][1] = 1 + s, v[0][2] = 1;
v[1][0] = 1 + s, v[1][1] = -1 - s, v[1][2] = 1;
v[2][0] = -1 - s, v[2][1] = -1 - s, v[2][2] = 1;
v[3][0] = -1 - s, v[3][1] = 1 + s, v[3][2] = 1;
} else if(i == 2) {
tex = skybox->left;
v[0][0] = -1, v[0][1] = 1 + s, v[0][2] = 1 + s;
v[1][0] = -1, v[1][1] = -1 - s, v[1][2] = 1 + s;
v[2][0] = -1, v[2][1] = -1 - s, v[2][2] = -1 - s;
v[3][0] = -1, v[3][1] = 1 + s, v[3][2] = -1 - s;
} else if(i == 3) {
tex = skybox->right;
v[0][0] = 1, v[0][1] = 1 + s, v[0][2] = -1 - s;
v[1][0] = 1, v[1][1] = -1 - s, v[1][2] = -1 - s;
v[2][0] = 1, v[2][1] = -1 - s, v[2][2] = 1 + s;
v[3][0] = 1, v[3][1] = 1 + s, v[3][2] = 1 + s;
} else if(i == 4) {
tex = skybox->up;
v[0][0] = -1 - s, v[0][1] = 1, v[0][2] = 1 + s;
v[1][0] = -1 - s, v[1][1] = 1, v[1][2] = -1 - s;
v[2][0] = 1 + s, v[2][1] = 1, v[2][2] = -1 - s;
v[3][0] = 1 + s, v[3][1] = 1, v[3][2] = 1 + s;
} else if(i == 5) {
tex = skybox->down;
v[0][0] = -1 - s, v[0][1] = -1, v[0][2] = -1 - s;
v[1][0] = -1 - s, v[1][1] = -1, v[1][2] = 1 + s;
v[2][0] = 1 + s, v[2][1] = -1, v[2][2] = 1 + s;
v[3][0] = 1 + s, v[3][1] = -1, v[3][2] = -1 - s;
}
for(j = 0; j < 4; j++) {
for(k = 0; k < 3; k++) {
v[j][k] *= GBGLMaxDistance / 2;
v[j][k] += gl->engine->client->camera[k];
}
}
GBGLTextureSet(gl, tex);
GBGLPolygon(gl, 4, v, t);
}
GBGLTextureSet(gl, 0);
GBGLShadowEnable(gl);
GBGLCareDepth(gl);
}
void GBSkyBoxClose(GBSkyBox skybox) {
if(skybox->left > 0) GBGLTextureDelete(skybox->engine->client->gl, skybox->left);
free(skybox);
}

2
engine/src/stb_image.c Normal file
View file

@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

View file

@ -7,3 +7,12 @@ char* GBStringDuplicate(const char* str) {
return s;
}
char* GBStringConcat(const char* str1, const char* str2) {
char* r = malloc(strlen(str1) + strlen(str2) + 1);
strcpy(r, str1);
strcat(r, str2);
return r;
}