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);
}
static GSVector3 rot = {0, 0, 0};
static GSVector3 pos = {0, 0, 0};
static GSModel model = NULL;
GSPhysicsObject obj[128];
static void render(GSEngine self){
GSGL gl = GSClientGetGL(GSEngineGetClient(self));
int i;
GSVector4 col1 = {1, 0, 0, 1};
GSVector4 col2 = {1, 1, 1, 1};
GSVector3 v[] = {
{-5, -2, 5},
{-5, -2, -5},
{5, -2, -5},
{5, -2, 5}
{-10, 0, 10},
{-10, 0, -10},
{10, 0, -10},
{10, 0, 10}
};
GSVector3 pos = {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;
GSGLPushMatrix(gl);
GSGLSetPosition(gl, pos);
GSGLSetRotation(gl, rot);
if(model != NULL) GSModelDraw(model);
GSGLPopMatrix(gl);
GSPhysicsGetPosition(obj[i], rv);
GSPhysicsGetRotation(obj[i], rm);
pos[1] = 1;
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);
}
GSGLPushMatrix(gl);
GSGLSetPosition(gl, rv);
GSGLSetRotation3x3(gl, rm);
// GSGLTetrakis(gl, 0.5, col1, col2);
GSGLPopMatrix(gl);
}
GSGLSetColor(gl, col);
GSGLPushMatrix(gl);
GSGLSetPosition(gl, pos);
GSGLTetrakis(gl, 0.5, col1, col2);
GSGLPopMatrix(gl);
GSGLSetColor(gl, col2);
GSGLPolygon(gl, 4, v, NULL, n);
}
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
@ -126,24 +102,26 @@ int main(int argc, char** argv){
GSInit();
if((engine = GSEngineCreate(&param)) != NULL){
GSSound sound;
#ifndef _WIN32
signal(SIGINT, shutdown_engine);
signal(SIGTERM, shutdown_engine);
#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);
if((sound = GSSoundOpen(GSClientGetSoundEngine(GSEngineGetClient(engine)), "game:/desert2.mod")) != NULL){
GSSoundSetLoop(sound, 1);
GSSoundStart(sound);
pos[0] = ((GSNumber)rand() / RAND_MAX - 0.5) * 20;
pos[1] = 10;
pos[2] = ((GSNumber)rand() / RAND_MAX - 0.5) * 20;
GSPhysicsSetPosition(obj[i], pos);
}
GSClientSetSkybox(GSEngineGetClient(engine), GSTrue);
GSEngineLoop(engine);
GSEngineDestroy(engine);
}
}

View file

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

View file

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

View file

@ -11,6 +11,7 @@ extern "C" {
#endif
#define GSGLMaxDistance 100.0
#define GSGLMaxShadowDistance 1024
/* gl_shader.c */
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 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
}
#endif

View file

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

View file

@ -52,21 +52,22 @@ typedef struct _GSBinary GSBinary;
typedef struct _GSNetState GSNetState;
typedef struct _GSNetKV GSNetKV;
#ifdef _GEARSRC
typedef struct _GSClient* GSClient;
typedef struct _GSServer* GSServer;
typedef struct _GSEngine* GSEngine;
typedef struct _GSFile* GSFile;
typedef struct _GSResource* GSResource;
typedef struct _GSGL* GSGL;
typedef struct _GSSkyBox* GSSkyBox;
typedef struct _GSModel* GSModel;
typedef struct _GSSoundDriver* GSSoundDriver;
typedef struct _GSSoundEngine* GSSoundEngine;
typedef struct _GSSound* GSSound;
typedef struct _GSNetClient* GSNetClient;
typedef struct _GSNetServer* GSNetServer;
typedef struct _GSNetSocket* GSNetSocket;
typedef struct _GSPhysics* GSPhysics;
typedef struct _GSClient* GSClient;
typedef struct _GSServer* GSServer;
typedef struct _GSEngine* GSEngine;
typedef struct _GSFile* GSFile;
typedef struct _GSResource* GSResource;
typedef struct _GSGL* GSGL;
typedef struct _GSSkyBox* GSSkyBox;
typedef struct _GSModel* GSModel;
typedef struct _GSSoundDriver* GSSoundDriver;
typedef struct _GSSoundEngine* GSSoundEngine;
typedef struct _GSSound* GSSound;
typedef struct _GSNetClient* GSNetClient;
typedef struct _GSNetServer* GSNetServer;
typedef struct _GSNetSocket* GSNetSocket;
typedef struct _GSPhysics* GSPhysics;
typedef struct _GSPhysicsObject* GSPhysicsObject;
typedef struct _GSModelFace GSModelFace;
typedef struct _GSModelMaterial GSModelMaterial;
@ -88,6 +89,7 @@ typedef void* GSNetClient;
typedef void* GSNetServer;
typedef void* GSNetSocket;
typedef void* GSPhysics;
typedef void* GSPhysicsObject;
#endif
typedef float GSNumber;
typedef GSNumber GSVector2[2];
@ -321,6 +323,13 @@ struct _GSPhysics {
dJointGroupID contact_group;
};
struct _GSPhysicsObject {
GSEngine engine;
dGeomID geom;
dBodyID body;
};
struct _GSClient {
GSEngine engine;

View file

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

View file

@ -2,20 +2,22 @@
#include <GearSrc/Math.h>
#define SHADOW_WIDTH 512
#define SHADOW_HEIGHT 512
#define SHADOW_CULL
void GSGLShadowInit(GSGL gl) {
GLfloat color[] = {1, 1, 1, 1};
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);
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_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_WRAP_S, GL_CLAMP_TO_BORDER);
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);
@ -48,12 +50,16 @@ GSBool GSGLShadowBeforeMapping(GSGL gl) {
GSGLClear(gl);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glViewport(0, 0, GSGLMaxShadowDistance, GSGLMaxShadowDistance);
glMatrixMode(GL_PROJECTION);
glGetDoublev(GL_PROJECTION_MATRIX, gl->shadow_old_projection);
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);
@ -89,7 +95,7 @@ void GSGLShadowAfterMapping(GSGL gl) {
glActiveTexture(GL_TEXTURE7);
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);
glActiveTexture(GL_TEXTURE0);

View file

@ -16,11 +16,13 @@ GSPhysics GSPhysicsCreate(GSServer server) {
physics->engine = server->engine;
physics->world = dWorldCreate();
physics->space = dSimpleSpaceCreate(0);
physics->space = dHashSpaceCreate(0);
physics->contact_group = dJointGroupCreate(0);
dWorldSetGravity(physics->world, 0, 0, -9.81);
dCreatePlane(physics->space, 0, 0, 1, 0);
GSLog(server->engine, GSLogInfo, "Created physics engine");
return physics;
@ -67,3 +69,71 @@ void GSPhysicsStep(GSPhysics physics) {
dWorldStep(physics->world, 1.0 / physics->engine->tps);
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);
}
GSNetServer GSServerGetNetServer(GSServer server) {
return server->net;
}
GSPhysics GSServerGetPhysics(GSServer server) {
return server->physics;
}
void GSServerStep(GSServer server) {
GSPhysicsStep(server->physics);
GSNetServerStep(server->net);
}