This commit is contained in:
Nishi 2026-02-01 08:09:18 +09:00
commit ae67600abf
Signed by: nishi
GPG key ID: 27EF69B208EB9343
11 changed files with 178 additions and 94 deletions

View file

@ -38,70 +38,46 @@ static void tick(void){
while(!window->close && MwPending(window)) MwStep(window); while(!window->close && MwPending(window)) MwStep(window);
} }
static GSVector3 rot = {0, 0, 0}; GSPhysicsObject obj[128];
static GSVector3 pos = {0, 0, 0};
static GSModel model = NULL;
static void render(GSEngine self){ static void render(GSEngine self){
GSGL gl = GSClientGetGL(GSEngineGetClient(self)); GSGL gl = GSClientGetGL(GSEngineGetClient(self));
int i;
GSVector4 col1 = {1, 0, 0, 1};
GSVector4 col2 = {1, 1, 1, 1};
GSVector3 v[] = { GSVector3 v[] = {
{-5, -2, 5}, {-10, 0, 10},
{-5, -2, -5}, {-10, 0, -10},
{5, -2, -5}, {10, 0, -10},
{5, -2, 5} {10, 0, 10}
}; };
GSVector3 pos = {0, 1, 0};
GSVector3 n = {0, 1, 0}; GSVector3 n = {0, 1, 0};
GSVector4 col = {1, 1, 1, 1};
GSVector4 col2 = {1, 0, 0, 1};
int i, j;
pos[1] = 0; for(i = 0; i < sizeof(obj) / sizeof(obj[0]); i++){
GSVector3 rv;
GSMatrix3x3 rm;
GSPhysicsGetPosition(obj[i], rv);
GSPhysicsGetRotation(obj[i], rm);
GSGLPushMatrix(gl);
GSGLSetPosition(gl, rv);
GSGLSetRotation3x3(gl, rm);
// GSGLTetrakis(gl, 0.5, col1, col2);
GSGLPopMatrix(gl);
}
GSGLPushMatrix(gl); GSGLPushMatrix(gl);
GSGLSetPosition(gl, pos); GSGLSetPosition(gl, pos);
GSGLSetRotation(gl, rot); GSGLTetrakis(gl, 0.5, col1, col2);
if(model != NULL) GSModelDraw(model);
GSGLPopMatrix(gl); GSGLPopMatrix(gl);
pos[1] = 1; GSGLSetColor(gl, col2);
GSGLPushMatrix(gl);
GSGLSetPosition(gl, pos);
GSGLSetRotation(gl, rot);
if(model != NULL) GSModelDraw(model);
GSGLPopMatrix(gl);
for(i = -1; i <= 1; i++){
for(j = -1; j <= 1; j++){
GSVector3 pos2;
double s = fabs(sin(rot[0] / 180 * GSMathPi));
int n = (i + 1) * 3 + (j + 1);
pos2[0] = i * s * 2;
pos2[1] = 0;
pos2[2] = j * s * 2;
col2[2] = n & 1;
col2[1] = (n & 2) ? 1 : 0;
col2[0] = (n & 4) ? 1 : 0;
GSGLPushMatrix(gl);
GSGLSetPosition(gl, pos2);
GSGLSetRotation(gl, rot);
GSGLTetrakis(gl, s, col, col2);
GSGLPopMatrix(gl);
}
}
GSGLSetColor(gl, col);
GSGLPolygon(gl, 4, v, NULL, n); GSGLPolygon(gl, 4, v, NULL, n);
} }
static void after_render(GSEngine self){ static void after_render(GSEngine self){
rot[0] = rot[1] = rot[2] += (1.0 / GSEngineGetTPS(self)) * 90;
pos[0] = cos(rot[0] / 180 * GSMathPi);
pos[2] = sin(rot[0] / 180 * GSMathPi);
} }
#ifndef _WIN32 #ifndef _WIN32
@ -126,24 +102,26 @@ int main(int argc, char** argv){
GSInit(); GSInit();
if((engine = GSEngineCreate(&param)) != NULL){ if((engine = GSEngineCreate(&param)) != NULL){
GSSound sound;
#ifndef _WIN32 #ifndef _WIN32
signal(SIGINT, shutdown_engine); signal(SIGINT, shutdown_engine);
signal(SIGTERM, shutdown_engine); signal(SIGTERM, shutdown_engine);
#endif #endif
model = GSModelOpen(engine, "game:/mdl/fish.gsm"); int i;
GSVector3 pos = {0, 1, 0};
GSVector3 sz = {1, 1, 1};
for(i = 0; i < sizeof(obj) / sizeof(obj[0]); i++){
obj[i] = GSPhysicsCreateSphere(GSServerGetPhysics(GSEngineGetServer(engine)), 1, 0.5);
GSClientSetSkybox(GSEngineGetClient(engine), GSTrue); pos[0] = ((GSNumber)rand() / RAND_MAX - 0.5) * 20;
pos[1] = 10;
pos[2] = ((GSNumber)rand() / RAND_MAX - 0.5) * 20;
if((sound = GSSoundOpen(GSClientGetSoundEngine(GSEngineGetClient(engine)), "game:/desert2.mod")) != NULL){ GSPhysicsSetPosition(obj[i], pos);
GSSoundSetLoop(sound, 1);
GSSoundStart(sound);
} }
GSClientSetSkybox(GSEngineGetClient(engine), GSTrue);
GSEngineLoop(engine); GSEngineLoop(engine);
GSEngineDestroy(engine); GSEngineDestroy(engine);
} }
} }

View file

@ -33,27 +33,23 @@ vec4 PhongShading(void)
} }
float ShadowCoef(void){ float ShadowCoef(void){
vec4 shadow_coord = vShadowCoord / vShadowCoord.w; vec3 shadow_coord = vShadowCoord.xyz / vShadowCoord.w;
float view = shadow_coord.z; float view = shadow_coord.z;
vec2 d[4]; vec2 d[4];
float light = 1.0;
float shadow_coef = 1.0; float shadow_coef = 1.0;
int i; int i;
if(shadow_coord.z > 1.0) return 1.0;
d[0] = vec2(-0.94201624, -0.39906216); d[0] = vec2(-0.94201624, -0.39906216);
d[1] = vec2(0.94558609, -0.76890725); d[1] = vec2(0.94558609, -0.76890725);
d[2] = vec2(-0.094184101, -0.92938870); d[2] = vec2(-0.094184101, -0.92938870);
d[3] = vec2(0.34495938, 0.29387760); d[3] = vec2(0.34495938, 0.29387760);
light = texture2D(depth_texture, shadow_coord.xy).z;
for(i = 0; i < 4; i++){ for(i = 0; i < 4; i++){
vec2 p = shadow_coord.xy + d[i] / 700.0; vec2 p = shadow_coord.xy + d[i] / 700.0;
if(p.x < 0.0) continue; if(p.x < 0.0 || p.y < 0.0 || p.x > 1.0 || p.y > 1.0) shadow_coef += 1.0;
if(p.y < 0.0) continue;
if(p.x > 1.0) continue;
if(p.y > 1.0) continue;
if(texture2D(depth_texture, p).z < view){ if(texture2D(depth_texture, p).z < view){
shadow_coef -= 0.2; shadow_coef -= 0.2;
@ -64,7 +60,7 @@ float ShadowCoef(void){
} }
void main(void){ void main(void){
vec4 c = enable_lighting > 0.5 ? PhongShading() : vColor; vec4 c = PhongShading();
vec4 ambient = gl_LightSource[0].ambient; vec4 ambient = gl_LightSource[0].ambient;
float shadow_coef = ShadowCoef(); float shadow_coef = ShadowCoef();

View file

@ -13,6 +13,7 @@ GSDECL void GSClientDestroy(GSClient client);
GSDECL void GSClientStep(GSClient client); GSDECL void GSClientStep(GSClient client);
GSDECL GSGL GSClientGetGL(GSClient client); GSDECL GSGL GSClientGetGL(GSClient client);
GSDECL GSSoundEngine GSClientGetSoundEngine(GSClient client); GSDECL GSSoundEngine GSClientGetSoundEngine(GSClient client);
GSDECL GSNetClient GSClientGetNetClient(GSClient client);
GSDECL void GSClientSetSkybox(GSClient client, GSBool toggle); GSDECL void GSClientSetSkybox(GSClient client, GSBool toggle);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -11,6 +11,7 @@ extern "C" {
#endif #endif
#define GSGLMaxDistance 100.0 #define GSGLMaxDistance 100.0
#define GSGLMaxShadowDistance 1024
/* gl_shader.c */ /* gl_shader.c */
GSDECL GSBool GSGLShaderPrepare(GSGL gl, GLuint* shader, const char* vs, const char* fs); GSDECL GSBool GSGLShaderPrepare(GSGL gl, GLuint* shader, const char* vs, const char* fs);

View file

@ -13,6 +13,13 @@ GSDECL GSPhysics GSPhysicsCreate(GSServer server);
GSDECL void GSPhysicsDestroy(GSPhysics physics); GSDECL void GSPhysicsDestroy(GSPhysics physics);
GSDECL void GSPhysicsStep(GSPhysics physics); GSDECL void GSPhysicsStep(GSPhysics physics);
GSDECL GSPhysicsObject GSPhysicsCreateBox(GSPhysics physics, GSNumber mass, GSVector3 size);
GSDECL GSPhysicsObject GSPhysicsCreateSphere(GSPhysics physics, GSNumber mass, GSNumber radius);
GSDECL void GSPhysicsGetPosition(GSPhysicsObject obj, GSVector3 vec);
GSDECL void GSPhysicsSetPosition(GSPhysicsObject obj, GSVector3 vec);
GSDECL void GSPhysicsGetRotation(GSPhysicsObject obj, GSMatrix3x3 mat);
GSDECL void GSPhysicsDestroyObject(GSPhysicsObject obj);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -10,6 +10,8 @@ extern "C" {
GSDECL GSServer GSServerCreate(GSEngine engine); GSDECL GSServer GSServerCreate(GSEngine engine);
GSDECL void GSServerDestroy(GSServer server); GSDECL void GSServerDestroy(GSServer server);
GSDECL GSNetServer GSServerGetNetServer(GSServer server);
GSDECL GSPhysics GSServerGetPhysics(GSServer server);
GSDECL void GSServerStep(GSServer server); GSDECL void GSServerStep(GSServer server);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -67,6 +67,7 @@ typedef struct _GSNetClient* GSNetClient;
typedef struct _GSNetServer* GSNetServer; typedef struct _GSNetServer* GSNetServer;
typedef struct _GSNetSocket* GSNetSocket; typedef struct _GSNetSocket* GSNetSocket;
typedef struct _GSPhysics* GSPhysics; typedef struct _GSPhysics* GSPhysics;
typedef struct _GSPhysicsObject* GSPhysicsObject;
typedef struct _GSModelFace GSModelFace; typedef struct _GSModelFace GSModelFace;
typedef struct _GSModelMaterial GSModelMaterial; typedef struct _GSModelMaterial GSModelMaterial;
@ -88,6 +89,7 @@ typedef void* GSNetClient;
typedef void* GSNetServer; typedef void* GSNetServer;
typedef void* GSNetSocket; typedef void* GSNetSocket;
typedef void* GSPhysics; typedef void* GSPhysics;
typedef void* GSPhysicsObject;
#endif #endif
typedef float GSNumber; typedef float GSNumber;
typedef GSNumber GSVector2[2]; typedef GSNumber GSVector2[2];
@ -321,6 +323,13 @@ struct _GSPhysics {
dJointGroupID contact_group; dJointGroupID contact_group;
}; };
struct _GSPhysicsObject {
GSEngine engine;
dGeomID geom;
dBodyID body;
};
struct _GSClient { struct _GSClient {
GSEngine engine; GSEngine engine;

View file

@ -44,9 +44,9 @@ GSClient GSClientCreate(GSEngine engine) {
client->look_at[1] = 1; client->look_at[1] = 1;
client->look_at[2] = 0; client->look_at[2] = 0;
client->light0[0] = 2.5; client->light0[0] = 1;
client->light0[1] = 5; client->light0[1] = 1;
client->light0[2] = 5; client->light0[2] = 0;
client->light0[3] = 0; client->light0[3] = 0;
client->skybox_enabled = GSFalse; client->skybox_enabled = GSFalse;
@ -249,6 +249,7 @@ void GSClientStep(GSClient client) {
GSGLTextBold(client->gl, 1); GSGLTextBold(client->gl, 1);
GSGLText(client->gl, client->engine->width - tw, 0, buf2); GSGLText(client->gl, client->engine->width - tw, 0, buf2);
GSGLTextBold(client->gl, 0); GSGLTextBold(client->gl, 0);
GSGLSetColor(client->gl, white);
client->engine->param->gl_swapbuffer(); client->engine->param->gl_swapbuffer();
@ -263,6 +264,10 @@ GSSoundEngine GSClientGetSoundEngine(GSClient client) {
return client->sengine; return client->sengine;
} }
GSNetClient GSClientGetNetClient(GSClient client) {
return client->net;
}
void GSClientSetSkybox(GSClient client, GSBool toggle) { void GSClientSetSkybox(GSClient client, GSBool toggle) {
client->skybox_enabled = toggle; client->skybox_enabled = toggle;
} }

View file

@ -2,20 +2,22 @@
#include <GearSrc/Math.h> #include <GearSrc/Math.h>
#define SHADOW_WIDTH 512
#define SHADOW_HEIGHT 512
#define SHADOW_CULL #define SHADOW_CULL
void GSGLShadowInit(GSGL gl) { void GSGLShadowInit(GSGL gl) {
GLfloat color[] = {1, 1, 1, 1};
glGenTextures(1, &gl->shadow_texture); glGenTextures(1, &gl->shadow_texture);
glBindTexture(GL_TEXTURE_2D, 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); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GSGLMaxShadowDistance, GSGLMaxShadowDistance, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
@ -48,12 +50,16 @@ GSBool GSGLShadowBeforeMapping(GSGL gl) {
GSGLClear(gl); GSGLClear(gl);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glViewport(0, 0, GSGLMaxShadowDistance, GSGLMaxShadowDistance);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glGetDoublev(GL_PROJECTION_MATRIX, gl->shadow_old_projection); glGetDoublev(GL_PROJECTION_MATRIX, gl->shadow_old_projection);
glLoadIdentity(); glLoadIdentity();
GSGLCameraPerspective(gl, SHADOW_WIDTH, SHADOW_HEIGHT); if(gl->engine->client->light0[3]) {
GSGLCameraPerspective(gl, GSGLMaxShadowDistance, GSGLMaxShadowDistance);
} else {
glOrtho(-GSGLMaxShadowDistance / 2, GSGLMaxShadowDistance / 2, -GSGLMaxShadowDistance / 2, GSGLMaxShadowDistance / 2, -GSGLMaxDistance, GSGLMaxDistance);
}
glGetDoublev(GL_PROJECTION_MATRIX, gl->shadow_projection); glGetDoublev(GL_PROJECTION_MATRIX, gl->shadow_projection);
@ -89,7 +95,7 @@ void GSGLShadowAfterMapping(GSGL gl) {
glActiveTexture(GL_TEXTURE7); glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, gl->shadow_texture); glBindTexture(GL_TEXTURE_2D, gl->shadow_texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GSGLMaxShadowDistance, GSGLMaxShadowDistance);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);

View file

@ -16,11 +16,13 @@ GSPhysics GSPhysicsCreate(GSServer server) {
physics->engine = server->engine; physics->engine = server->engine;
physics->world = dWorldCreate(); physics->world = dWorldCreate();
physics->space = dSimpleSpaceCreate(0); physics->space = dHashSpaceCreate(0);
physics->contact_group = dJointGroupCreate(0); physics->contact_group = dJointGroupCreate(0);
dWorldSetGravity(physics->world, 0, 0, -9.81); dWorldSetGravity(physics->world, 0, 0, -9.81);
dCreatePlane(physics->space, 0, 0, 1, 0);
GSLog(server->engine, GSLogInfo, "Created physics engine"); GSLog(server->engine, GSLogInfo, "Created physics engine");
return physics; return physics;
@ -67,3 +69,71 @@ void GSPhysicsStep(GSPhysics physics) {
dWorldStep(physics->world, 1.0 / physics->engine->tps); dWorldStep(physics->world, 1.0 / physics->engine->tps);
dJointGroupEmpty(physics->contact_group); dJointGroupEmpty(physics->contact_group);
} }
GSPhysicsObject GSPhysicsCreateBox(GSPhysics physics, GSNumber mass, GSVector3 size) {
dMass m;
GSPhysicsObject obj = malloc(sizeof(*obj));
dMatrix3 mat;
memset(obj, 0, sizeof(*obj));
obj->geom = dCreateBox(physics->space, size[0], size[2], size[1]);
obj->body = dBodyCreate(physics->world);
dMassSetBox(&m, 1, size[0], size[2], size[1]);
dMassAdjust(&m, mass);
dBodySetMass(obj->body, &m);
dGeomSetBody(obj->geom, obj->body);
dRSetIdentity(mat);
dBodySetRotation(obj->body, mat);
return obj;
}
GSPhysicsObject GSPhysicsCreateSphere(GSPhysics physics, GSNumber mass, GSNumber radius) {
dMass m;
GSPhysicsObject obj = malloc(sizeof(*obj));
memset(obj, 0, sizeof(*obj));
obj->geom = dCreateSphere(physics->space, radius);
obj->body = dBodyCreate(physics->world);
dMassSetSphere(&m, 1, radius);
dMassAdjust(&m, mass);
dBodySetMass(obj->body, &m);
dGeomSetBody(obj->geom, obj->body);
return obj;
}
void GSPhysicsSetPosition(GSPhysicsObject obj, GSVector3 vec) {
dBodySetPosition(obj->body, vec[0], -vec[2], vec[1]);
}
void GSPhysicsGetPosition(GSPhysicsObject obj, GSVector3 vec) {
const dReal* r = dBodyGetPosition(obj->body);
vec[0] = r[0];
vec[1] = r[2];
vec[2] = -r[1];
}
void GSPhysicsGetRotation(GSPhysicsObject obj, GSMatrix3x3 mat) {
const dReal* r = dBodyGetRotation(obj->body);
int y, x;
for(y = 0; y < 3; y++) {
for(x = 0; x < 3; x++) mat[3 * y + x] = r[4 * y + x];
}
}
void GSPhysicsDestroyObject(GSPhysicsObject obj) {
dBodyDestroy(obj->body);
dGeomDestroy(obj->geom);
free(obj);
}

View file

@ -39,6 +39,15 @@ void GSServerDestroy(GSServer server) {
free(server); free(server);
} }
GSNetServer GSServerGetNetServer(GSServer server) {
return server->net;
}
GSPhysics GSServerGetPhysics(GSServer server) {
return server->physics;
}
void GSServerStep(GSServer server) { void GSServerStep(GSServer server) {
GSPhysicsStep(server->physics);
GSNetServerStep(server->net); GSNetServerStep(server->net);
} }