assaultfish/engine/src/skybox.c
2026-01-13 04:28:36 +09:00

173 lines
3.7 KiB
C

#include <GearSrc/SkyBox.h>
#include <GearSrc/GL.h>
#include <GearSrc/String.h>
GSSkyBox GSSkyBoxOpen(GSClient client, const char* base) {
GSSkyBox 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.";
ptr[2] = &skybox->right;
ptr[3] = "/right.";
ptr[4] = &skybox->front;
ptr[5] = "/front.";
ptr[6] = &skybox->back;
ptr[7] = "/back.";
ptr[8] = &skybox->up;
ptr[9] = "/up.";
ptr[10] = &skybox->down;
ptr[11] = "/down.";
for(i = 0; i < 12; i += 2) {
char* b = GSStringConcat(base, ptr[i + 1]);
int j;
const char* fmt[] = {"png", "bmp", "jpg", "jpeg"};
for(j = 0; j < 4; j++) {
p = GSStringConcat(b, fmt[j]);
if(GSGLTextureLoadFile(client->gl, ptr[i], NULL, NULL, p)) {
free(p);
break;
}
free(p);
}
if(j == 4) {
GSSkyBoxClose(skybox);
return NULL;
}
free(b);
}
return skybox;
}
GSSkyBox GSSkyBoxTry(GSClient client, const char* name) {
const char* ns[] = {"game", "base"};
int i;
GSSkyBox sb = NULL;
for(i = 0; i < 2; i++) {
char* b = GSStringConcat(ns[i], ":/skybox/");
char* s = GSStringConcat(b, name);
sb = GSSkyBoxOpen(client, s);
free(s);
free(b);
if(sb != NULL) break;
}
return sb;
}
void GSSkyBoxDraw(GSSkyBox skybox) {
GSGL gl = skybox->engine->client->gl;
int i;
GSVector3 v[4];
GSVector2 t[4];
GSVector3 n = {0, 0, 0};
GSNumber s = 0.001;
t[0][0] = 0, t[0][1] = 0;
t[1][0] = 0, t[1][1] = 1;
t[2][0] = 1, t[2][1] = 1;
t[3][0] = 1, t[3][1] = 0;
GSGLIgnoreDepth(gl);
GSGLShadowDisable(gl);
for(i = 0; i < 6; i++) {
GLuint tex;
int j, k;
if(i == 0) {
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 == 1) {
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 == 2) {
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 == 3) {
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 == 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] *= GSGLMaxDistance / 2;
v[j][k] += gl->engine->client->camera[k];
}
}
GSGLTextureSet(gl, tex);
GSGLPolygon(gl, 4, v, t, n);
}
GSGLTextureSet(gl, 0);
GSGLShadowEnable(gl);
GSGLCareDepth(gl);
}
void GSSkyBoxClose(GSSkyBox skybox) {
GLuint* ptr[6];
int i;
ptr[0] = &skybox->left;
ptr[1] = &skybox->right;
ptr[2] = &skybox->front;
ptr[3] = &skybox->back;
ptr[4] = &skybox->up;
ptr[5] = &skybox->down;
for(i = 0; i < 6; i++) {
if(*ptr[i] > 0) GSGLTextureDelete(skybox->engine->client->gl, *ptr[i]);
}
free(skybox);
}