diff --git a/client/main.c b/client/main.c index c9b4270..045c0ea 100644 --- a/client/main.c +++ b/client/main.c @@ -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(¶m)) != 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); } } diff --git a/engine/data/shader/shadow.fs b/engine/data/shader/shadow.fs index 83400b2..60fbaf9 100644 --- a/engine/data/shader/shadow.fs +++ b/engine/data/shader/shadow.fs @@ -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(); diff --git a/engine/include/GearSrc/Client.h b/engine/include/GearSrc/Client.h index 1f631db..c4ce110 100644 --- a/engine/include/GearSrc/Client.h +++ b/engine/include/GearSrc/Client.h @@ -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 diff --git a/engine/include/GearSrc/GL.h b/engine/include/GearSrc/GL.h index e7909fa..2c9f26c 100644 --- a/engine/include/GearSrc/GL.h +++ b/engine/include/GearSrc/GL.h @@ -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); diff --git a/engine/include/GearSrc/Physics.h b/engine/include/GearSrc/Physics.h index 3925f67..e878e13 100644 --- a/engine/include/GearSrc/Physics.h +++ b/engine/include/GearSrc/Physics.h @@ -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 diff --git a/engine/include/GearSrc/Server.h b/engine/include/GearSrc/Server.h index ed8cfdf..1495b58 100644 --- a/engine/include/GearSrc/Server.h +++ b/engine/include/GearSrc/Server.h @@ -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 } diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index 6a7be03..de58f37 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -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; diff --git a/engine/src/client.c b/engine/src/client.c index 7504b7f..713202a 100644 --- a/engine/src/client.c +++ b/engine/src/client.c @@ -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; } diff --git a/engine/src/gl/gl_shadow.c b/engine/src/gl/gl_shadow.c index d0c4599..37b7308 100644 --- a/engine/src/gl/gl_shadow.c +++ b/engine/src/gl/gl_shadow.c @@ -2,20 +2,22 @@ #include -#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); diff --git a/engine/src/physics.c b/engine/src/physics.c index 9e3e51b..0f068fc 100644 --- a/engine/src/physics.c +++ b/engine/src/physics.c @@ -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); +} diff --git a/engine/src/server.c b/engine/src/server.c index 82807ca..41e8d06 100644 --- a/engine/src/server.c +++ b/engine/src/server.c @@ -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); }