279 lines
6.9 KiB
C
279 lines
6.9 KiB
C
#include <af_common.h>
|
|
|
|
#define SHADOW_WIDTH 1024
|
|
#define SHADOW_HEIGHT 1024
|
|
|
|
double gl_cam_lr = 0;
|
|
double gl_cam_ud = 0;
|
|
double gl_cam_x;
|
|
double gl_cam_y;
|
|
double gl_cam_z;
|
|
|
|
int gl_scene = AF_SCENE_MAIN;
|
|
|
|
static GLuint shadow_texture, shadow;
|
|
|
|
gl_scene_t gl_scenes[] = {
|
|
{gl_main_changed, gl_main_init, gl_main_draw, gl_main_after}, /**/
|
|
{NULL, NULL, NULL, NULL} /**/
|
|
};
|
|
|
|
static char gl_status[256];
|
|
|
|
void gl_resize(int width, int height) {
|
|
glViewport(0, 0, width, height);
|
|
}
|
|
|
|
void gl_init(void) {
|
|
GLfloat lightamb[] = {0.1, 0.1, 0.1, 1.0};
|
|
GLfloat lightcol[] = {1.0, 1.0, 1.0, 1.0};
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_NORMALIZE);
|
|
glEnable(GL_BLEND);
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glEnable(GL_LIGHT0);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb);
|
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol);
|
|
glLightfv(GL_LIGHT0, GL_SPECULAR, lightcol);
|
|
|
|
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
|
|
|
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
gl_font_init();
|
|
|
|
gl_status[0] = 0;
|
|
|
|
glGenTextures(1, &shadow_texture);
|
|
glBindTexture(GL_TEXTURE_2D, shadow_texture);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 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_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
if(gl_shader(&shadow, DATAROOTDIR "/assaultfish/shadow.vs", DATAROOTDIR "/assaultfish/shadow.fs")) {
|
|
glUseProgram(shadow);
|
|
glUniform1i(glGetUniformLocation(shadow, "texture"), 1);
|
|
}
|
|
}
|
|
|
|
void gl_cube(double x, double y, double z, double xs, double ys, double zs, double xr, double yr, double zr) {
|
|
int i;
|
|
glPushMatrix();
|
|
glTranslatef(x, y, z);
|
|
glScalef(xs, ys, zs);
|
|
glRotatef(xr, 1, 0, 0);
|
|
glRotatef(yr, 0, 1, 0);
|
|
glRotatef(zr, 0, 0, 1);
|
|
for(i = 0; i < 6; i++) {
|
|
glBegin(GL_QUADS);
|
|
glNormal3f(0, 0, 1);
|
|
glTexCoord2f(0, 0);
|
|
glVertex3f(-0.5, 0.5, 0.5);
|
|
glTexCoord2f(0, 1);
|
|
glVertex3f(-0.5, -0.5, 0.5);
|
|
glTexCoord2f(1, 1);
|
|
glVertex3f(0.5, -0.5, 0.5);
|
|
glTexCoord2f(1, 0);
|
|
glVertex3f(0.5, 0.5, 0.5);
|
|
glEnd();
|
|
|
|
if(i == 3) {
|
|
glRotatef(90, 1, 0, 0);
|
|
} else if(i == 4) {
|
|
glRotatef(180, 1, 0, 0);
|
|
} else {
|
|
glRotatef(90, 0, 1, 0);
|
|
}
|
|
}
|
|
glPopMatrix();
|
|
}
|
|
|
|
static void gl_common(void) {
|
|
char buf[128];
|
|
glColor3f(1, 1, 1);
|
|
|
|
sprintf(buf, "AssaultFish %s", AF_VERSION);
|
|
gl_font_text(buf, MwGetInteger(opengl, MwNwidth) - gl_font_width(buf), MwGetInteger(opengl, MwNheight) - gl_font_height(buf) * 2, 1);
|
|
|
|
sprintf(buf, "%s", AF_COPYRIGHT);
|
|
gl_font_text(buf, MwGetInteger(opengl, MwNwidth) - gl_font_width(buf), MwGetInteger(opengl, MwNheight) - gl_font_height(buf), 1);
|
|
|
|
gl_font_text(gl_status, 0, 0, 1);
|
|
}
|
|
|
|
static void scene(void) {
|
|
if(gl_scenes[gl_scene].draw != NULL) gl_scenes[gl_scene].draw();
|
|
}
|
|
|
|
void gl_render(void) {
|
|
GLfloat lightpos[4] = {2.5, 5, -2.5, 1};
|
|
GLint viewport[4];
|
|
GLdouble modelview[16];
|
|
GLdouble modelview2[16];
|
|
|
|
if(gl_scenes[gl_scene].init != NULL) gl_scenes[gl_scene].init();
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
|
|
|
|
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
gluPerspective(60, (double)SHADOW_WIDTH / SHADOW_HEIGHT, 0.01, 100.0);
|
|
gluLookAt(lightpos[0], lightpos[1], lightpos[2], 0, 0, 0, 0, 1, 0);
|
|
|
|
glGetDoublev(GL_MODELVIEW_MATRIX, &modelview[0]);
|
|
|
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
scene();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, shadow_texture);
|
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
glEnable(GL_LIGHTING);
|
|
glCullFace(GL_BACK);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluPerspective(60, (double)MwGetInteger(opengl, MwNwidth) / MwGetInteger(opengl, MwNheight), 0.01, 100.0);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
gluLookAt(gl_cam_x, gl_cam_y, gl_cam_z, gl_cam_x + cos(gl_cam_lr / 180.0 * M_PI), gl_cam_y + sin(gl_cam_ud / 180.0 * M_PI), gl_cam_z + sin(gl_cam_lr / 180.0 * M_PI), 0, 1, 0);
|
|
glGetDoublev(GL_MODELVIEW_MATRIX, &modelview2[0]);
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glLoadIdentity();
|
|
|
|
glTranslated(0.5, 0.5, 0.5);
|
|
glScaled(0.5, 0.5, 0.5);
|
|
glMultMatrixd(modelview);
|
|
glMultMatrixd(modelview2);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glActiveTexture(GL_TEXTURE1);
|
|
glBindTexture(GL_TEXTURE_2D, shadow_texture);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
|
|
|
|
scene();
|
|
|
|
glActiveTexture(GL_TEXTURE1);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glUseProgram(0);
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
gl_common();
|
|
|
|
glUseProgram(shadow);
|
|
|
|
if(gl_scenes[gl_scene].after != NULL) gl_scenes[gl_scene].after();
|
|
}
|
|
|
|
void gl_scene_change(void) {
|
|
if(gl_scenes[gl_scene].changed != NULL) gl_scenes[gl_scene].changed();
|
|
|
|
gl_status[0] = 0;
|
|
}
|
|
|
|
void gl_set_status(const char* status) {
|
|
strcpy(gl_status, status);
|
|
}
|
|
|
|
static void cross(double* out, double v00, double v01, double v02, double v10, double v11, double v12) {
|
|
out[0] = v01 * v12 - v02 * v11;
|
|
out[1] = v02 * v10 - v00 * v12;
|
|
out[2] = v00 * v11 - v01 * v10;
|
|
}
|
|
|
|
/*
|
|
* v0-v2
|
|
* | /
|
|
* v1/
|
|
*/
|
|
void gl_calc_normal3(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22) {
|
|
double v[3];
|
|
double l = 0;
|
|
int i;
|
|
|
|
cross(&v[0], /**/
|
|
v10 - v00, v11 - v01, v12 - v02, /**/
|
|
v20 - v00, v21 - v01, v22 - v02 /**/
|
|
);
|
|
|
|
l = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
|
|
for(i = 0; i < 3; i++) {
|
|
out[i] = v[i] / l;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* v0-v3
|
|
* | |
|
|
* v1-v2
|
|
*/
|
|
void gl_calc_normal4(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22, double v30, double v31, double v32) {
|
|
double v0[3];
|
|
double v1[3];
|
|
int i;
|
|
double l = 0;
|
|
|
|
gl_calc_normal3(&v0[0], v00, v01, v02, v10, v11, v12, v30, v31, v32);
|
|
gl_calc_normal3(&v1[0], v10, v11, v12, v20, v21, v22, v30, v31, v32);
|
|
|
|
for(i = 0; i < 3; i++) {
|
|
out[i] = v0[i] + v1[i];
|
|
}
|
|
|
|
l = sqrt(out[0] * out[0] + out[1] * out[1] + out[2] * out[2]);
|
|
|
|
for(i = 0; i < 3; i++) {
|
|
out[i] = out[i] / l;
|
|
}
|
|
}
|