diff --git a/engine/include/GearBox/GL.h b/engine/include/GearBox/GL.h index 16f3fba..c5a5ce9 100644 --- a/engine/include/GearBox/GL.h +++ b/engine/include/GearBox/GL.h @@ -18,11 +18,19 @@ GBDECL int GBGLTexturePrepare(GBGL gl, GLuint* texture, unsigned char* rgba, int /* gl_shadow.c */ GBDECL void GBGLShadowInit(GBGL gl); +GBDECL void GBGLShadowBeforeMapping(GBGL gl); +GBDECL void GBGLShadowAfterMapping(GBGL gl); +GBDECL void GBGLShadowEnd(GBGL gl); /* gl.c */ GBDECL GBGL GBGLCreate(GBClient client); GBDECL void GBGLDestroy(GBGL gl); +/* gl_camera.c */ +GBDECL void GBGLPerspective(GBGL gl, double width, double height); +GBDECL void GBGLSetCamera(GBGL gl); +GBDECL void GBGLLookAt(GBGL gl, GBVector3 camera, GBVector3 look_at); + #ifdef __cplusplus } #endif diff --git a/engine/include/GearBox/TypeDefs.h b/engine/include/GearBox/TypeDefs.h index eaeb48a..d91000d 100644 --- a/engine/include/GearBox/TypeDefs.h +++ b/engine/include/GearBox/TypeDefs.h @@ -75,8 +75,11 @@ struct _GBResourceKV { struct _GBGL { GBEngine engine; - GLuint shadow_texture; - GLuint shadow_shader; + GLuint shadow_texture; + GLuint shadow_shader; + GLdouble shadow_modelview[16]; + GLdouble shadow_old_projection[16]; + GLdouble shadow_old_modelview[16]; }; struct _GBClient { @@ -85,6 +88,7 @@ struct _GBClient { GBGL gl; GBVector3 look_at; GBVector3 camera; + GBVector4 light0; }; struct _GBServer { @@ -96,6 +100,8 @@ struct _GBEngine { GBClient client; GBServer server; GBResourceKV* resource; + int width; + int height; }; struct _GBFile { diff --git a/engine/resource/shader/shadow.fs b/engine/resource/shader/shadow.fs index b2748d4..215c7fe 100644 --- a/engine/resource/shader/shadow.fs +++ b/engine/resource/shader/shadow.fs @@ -12,8 +12,9 @@ void main (void){ if(solid_color > 0.5){ c = color; }else{ - c = texture2D(current_texture, gl_TexCoord[1].st); + c = texture2D(current_texture, gl_TexCoord[0].st); } + c = color; - gl_FragColor = (shadow + (gl_Color - shadow) * shadow2DProj(depth_texture, gl_TexCoord[0])) * c; + gl_FragColor = (shadow + (gl_Color - shadow) * shadow2DProj(depth_texture, gl_TexCoord[1])) * c; } diff --git a/engine/resource/shader/shadow.vs b/engine/resource/shader/shadow.vs index a4ce21d..c1beaaf 100644 --- a/engine/resource/shader/shadow.vs +++ b/engine/resource/shader/shadow.vs @@ -22,7 +22,7 @@ void main(void){ gl_FrontColor += temp + gl_FrontLightProduct[0].specular * specular; } - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_ModelViewMatrix * gl_Vertex; - gl_TexCoord[1] = gl_MultiTexCoord0; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_TexCoord[1] = gl_TextureMatrix[1] * gl_ModelViewMatrix * gl_Vertex; gl_Position = ftransform(); } diff --git a/engine/src/client.c b/engine/src/client.c index b14e9e5..1385858 100644 --- a/engine/src/client.c +++ b/engine/src/client.c @@ -10,6 +10,19 @@ GBClient GBClientCreate(GBEngine engine) { client->engine = engine; + client->camera[0] = 0; + client->camera[1] = 1.5; + client->camera[2] = 0; + + client->look_at[0] = 0; + client->look_at[1] = 0; + client->look_at[2] = 0; + + client->light0[0] = 0; + client->light0[1] = 1; + client->light0[2] = -5; + client->light0[3] = 1; + client->gl = GBGLCreate(client); GBLog(GBLogInfo, "Created client"); @@ -25,6 +38,66 @@ void GBClientDestroy(GBClient client) { GBLog(GBLogInfo, "Destroyed client"); } -void GBClientStep(GBClient client) { - client->engine->param->gl_swapbuffer(); +static void scene(void) { + glColor3f(1, 1, 1); + glBegin(GL_QUADS); + glNormal3f(0, 1, 0); + glVertex3f(-1, 0, -1); + glVertex3f(-1, 0, 1); + glVertex3f(1, 0, 1); + glVertex3f(1, 0, -1); + glEnd(); + + int i; + + glColor3f(1, 0, 0); + for(i = 0; i < 2; i++) { + glPushMatrix(); + glRotatef(180 * i, 0, 1, 0); + glBegin(GL_QUADS); + glNormal3f(-1, 0, 0); + glVertex3f(-1, 0.5, 0); + glVertex3f(-1, 0, 0); + glVertex3f(1, 0, 0); + glVertex3f(1, 0.5, 0); + glEnd(); + glPopMatrix(); + } +} + +void GBClientStep(GBClient client) { + GLfloat f[4]; + int i; + + for(i = 0; i < 4; i++) f[i] = client->light0[i]; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + GBGLPerspective(client->gl, client->engine->width, client->engine->height); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + GBGLSetCamera(client->gl); + + glLightfv(GL_LIGHT0, GL_POSITION, f); + + GBGLShadowBeforeMapping(client->gl); + scene(); + GBGLShadowAfterMapping(client->gl); + scene(); + GBGLShadowEnd(client->gl); + + client->engine->param->gl_swapbuffer(); + + static double r = 0; + + client->camera[0] = cos(r) * 2; + client->camera[2] = sin(r) * 2; + + // client->light0[0] = -cos(r) * 2; + // client->light0[2] = -sin(r) * 2; + + r += 0.1; } diff --git a/engine/src/core.c b/engine/src/core.c index 12eff7d..c978f6d 100644 --- a/engine/src/core.c +++ b/engine/src/core.c @@ -38,8 +38,11 @@ GBEngine GBEngineCreate(GBEngineParam* param) { engine->param = malloc(sizeof(*engine->param)); memcpy(engine->param, param, sizeof(*param)); - if(param->ready != NULL) { - param->ready(1024, 768); + engine->width = 1024; + engine->height = 768; + + if(param->ready != NULL && param->client) { + param->ready(engine->width, engine->height); } sh_new_strdup(engine->resource); diff --git a/engine/src/gl.c b/engine/src/gl.c index 543240f..d6e1e89 100644 --- a/engine/src/gl.c +++ b/engine/src/gl.c @@ -1,7 +1,7 @@ #include GBGL GBGLCreate(GBClient client) { - GLfloat lightamb[] = {0.25, 0.25, 0.25, 1.0}; + GLfloat lightamb[] = {0.5, 0.5, 0.5, 1.0}; GLfloat lightcol[] = {1.0, 1.0, 1.0, 1.0}; GBGL gl; @@ -35,4 +35,6 @@ GBGL GBGLCreate(GBClient client) { } void GBGLDestroy(GBGL gl) { + + free(gl); } diff --git a/engine/src/gl_camera.c b/engine/src/gl_camera.c index c2f4753..0ca84df 100644 --- a/engine/src/gl_camera.c +++ b/engine/src/gl_camera.c @@ -2,16 +2,16 @@ #include -void GBGLPerspective(GBGL gl, double fovy, double znear, double zfar) { - GLint vp[4]; +void GBGLPerspective(GBGL gl, double width, double height) { double aspect; double f; GLdouble matrix[16]; int i; + double fovy = 60.0; + double znear = 0.01; + double zfar = 10.0; - glGetIntegerv(GL_VIEWPORT, vp); - - aspect = (double)vp[2] / vp[3]; + aspect = width / height; f = GBMathCot(fovy / 180 * GBMathPi / 2); for(i = 0; i < 16; i++) matrix[i] = 0; @@ -21,11 +21,14 @@ void GBGLPerspective(GBGL gl, double fovy, double znear, double zfar) { matrix[4 * 3 + 2] = ((double)2 * zfar * znear) / (znear - zfar); matrix[4 * 2 + 3] = -1; - glLoadIdentity(); - glLoadMatrixd(matrix); + glMultMatrixd(matrix); } void GBGLSetCamera(GBGL gl) { + GBGLLookAt(gl, gl->engine->client->camera, gl->engine->client->look_at); +} + +void GBGLLookAt(GBGL gl, GBVector3 camera, GBVector3 look_at) { GLdouble matrix[16]; GBVector3 f; GBVector3 up; @@ -33,7 +36,7 @@ void GBGLSetCamera(GBGL gl) { GBVector3 u; int i; - GBMathSubtract3(f, gl->engine->client->look_at, gl->engine->client->camera); + GBMathSubtract3(f, look_at, camera); GBMathNormalize3(f); up[0] = 0; @@ -58,7 +61,6 @@ void GBGLSetCamera(GBGL gl) { matrix[4 * 2 + 2] = -f[2]; matrix[4 * 3 + 3] = 1; - glLoadIdentity(); - glLoadMatrixd(matrix); - glTranslated(-gl->engine->client->camera[0], -gl->engine->client->camera[1], -gl->engine->client->camera[2]); + glMultMatrixd(matrix); + glTranslated(-camera[0], -camera[1], -camera[2]); } diff --git a/engine/src/gl_shadow.c b/engine/src/gl_shadow.c index ca1ec0a..5e3372a 100644 --- a/engine/src/gl_shadow.c +++ b/engine/src/gl_shadow.c @@ -24,7 +24,87 @@ void GBGLShadowInit(GBGL gl) { if(GBGLShaderPrepare(gl, &gl->shadow_shader, "base:/shader/shadow.vs", "base:/shader/shadow.fs")) { glUseProgram(gl->shadow_shader); - glUniform1i(glGetUniformLocation(gl->shadow_shader, "shadow_texture"), 1); + glUniform1i(glGetUniformLocation(gl->shadow_shader, "depth_texture"), 1); glUniform1i(glGetUniformLocation(gl->shadow_shader, "current_texture"), 0); } } + +void GBGLShadowBeforeMapping(GBGL gl) { + GBVector3 zero = {0, 0, 0}; + + glClear(GL_DEPTH_BUFFER_BIT); + + glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); + + glMatrixMode(GL_PROJECTION); + glGetDoublev(GL_PROJECTION_MATRIX, gl->shadow_old_projection); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); + glGetDoublev(GL_MODELVIEW_MATRIX, gl->shadow_old_modelview); + glLoadIdentity(); + GBGLPerspective(gl, SHADOW_WIDTH, SHADOW_HEIGHT); + GBGLLookAt(gl, gl->engine->client->light0, zero); + + glGetDoublev(GL_MODELVIEW_MATRIX, gl->shadow_modelview); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + glDisable(GL_LIGHTING); + + glCullFace(GL_FRONT); +} + +void GBGLShadowAfterMapping(GBGL gl) { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gl->shadow_texture); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + + glViewport(0, 0, gl->engine->width, gl->engine->height); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glEnable(GL_LIGHTING); + glCullFace(GL_BACK); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMultMatrixd(gl->shadow_old_projection); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMultMatrixd(gl->shadow_old_modelview); + + glActiveTexture(GL_TEXTURE1); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + glTranslated(0.5, 0.5, 0.5); + glScaled(0.5, 0.5, 0.5); + glMultMatrixd(gl->shadow_modelview); + glMultMatrixd(gl->shadow_old_modelview); + glActiveTexture(GL_TEXTURE0); + + glMatrixMode(GL_MODELVIEW); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gl->shadow_texture); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void GBGLShadowEnd(GBGL gl) { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + + glActiveTexture(GL_TEXTURE1); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glActiveTexture(GL_TEXTURE0); + + glMatrixMode(GL_MODELVIEW); +}