# HG changeset patch # User John Tsiombikas # Date 1326946510 -7200 # Node ID 7e982a61852a388d5b4257c56703872bd10792e0 # Parent 9b10c8183d4ec5939bb217641d7eec964d271a06 lights and shit diff -r 9b10c8183d4e -r 7e982a61852a src/main.c --- a/src/main.c Thu Jan 19 01:51:05 2012 +0200 +++ b/src/main.c Thu Jan 19 06:15:10 2012 +0200 @@ -30,7 +30,7 @@ int win_width, win_height; int stereo; int flip_winding; -int auto_rot = 1; +int auto_rot; float cam_theta, cam_phi, cam_dist = 10; float near_clip = 0.5; float far_clip = 1000.0; @@ -38,11 +38,13 @@ float stereo_focus_dist = 1.0; float stereo_eye_sep = 1.0 / 30.0; +int verbose = 0; + struct scene scn; int main(int argc, char **argv) { - float ldir[] = {1, -1, -1, 0}; + float ldir[] = {-1, 1, 1, 0}; float dx, dy, dz, diag; glutInitWindowSize(800, 600); @@ -64,7 +66,9 @@ glutSpaceballMotionFunc(sball_motion); glutSpaceballRotateFunc(sball_rotate); glutSpaceballButtonFunc(sball_button); - glutIdleFunc(glutPostRedisplay); + if(auto_rot) { + glutIdleFunc(glutPostRedisplay); + } glewInit(); @@ -329,6 +333,10 @@ flip_winding = 1; break; + case 'v': + verbose = !verbose; + break; + default: goto inval; } diff -r 9b10c8183d4e -r 7e982a61852a src/scene.c --- a/src/scene.c Thu Jan 19 01:51:05 2012 +0200 +++ b/src/scene.c Thu Jan 19 06:15:10 2012 +0200 @@ -12,11 +12,13 @@ #include "scene.h" +static void setup_light(struct light *lt); static void color(float *dest, float r, float g, float b); static struct mesh *create_mesh(const struct aiScene *aiscn, struct aiMesh *aim); static unsigned int create_buffer(unsigned int type, void *data, size_t sz); static unsigned int load_texture(const char *fname); +extern int verbose; int load_scene(struct scene *scn, const char *fname) { @@ -24,7 +26,11 @@ const struct aiScene *aiscn; unsigned int proc_flags = aiProcess_JoinIdenticalVertices | aiProcess_PreTransformVertices | aiProcess_Triangulate | - aiProcess_GenNormals | aiProcess_SortByPType; + aiProcess_SortByPType; + + if(verbose) { + printf("scene: %s (%d meshes, %d lights)\n", fname, aiscn->mNumMeshes, aiscn->mNumLights); + } if(!(aiscn = aiImportFile(fname, proc_flags))) { fprintf(stderr, "failed to load: %s\n", fname); @@ -34,6 +40,63 @@ scn->meshes = 0; scn->lights = 0; + for(i=0; imNumLights; i++) { + struct light *lt; + struct aiLight *ailt = aiscn->mLights[i]; + + if(!(lt = malloc(sizeof *lt))) { + perror("failed to allocate light"); + return -1; + } + + if(verbose) { + printf("- light(%s) ", ailt->mName.data); + } + + switch(ailt->mType) { + case aiLightSource_POINT: + lt->pos[0] = ailt->mPosition.x; + lt->pos[1] = ailt->mPosition.y; + lt->pos[2] = ailt->mPosition.z; + lt->pos[3] = 1.0f; + if(verbose) { + printf("pos(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]); + } + break; + + case aiLightSource_DIRECTIONAL: + lt->pos[0] = ailt->mDirection.x; + lt->pos[1] = ailt->mDirection.y; + lt->pos[2] = ailt->mDirection.z; + lt->pos[3] = 0.0f; + if(verbose) { + printf("dir(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]); + } + break; + + default: + fprintf(stderr, "error loading light: %s, unsupported type\n", ailt->mName.data); + continue; + } + color(lt->color, ailt->mColorDiffuse.r, ailt->mColorDiffuse.g, ailt->mColorDiffuse.b); + if(verbose) { + printf("col(%.2f %.2f %.2f) ", lt->color[0], lt->color[1], lt->color[2]); + } + + lt->cone_inner = ailt->mAngleInnerCone; + lt->cone_outer = ailt->mAngleOuterCone; + + lt->att[0] = ailt->mAttenuationConstant; + lt->att[1] = ailt->mAttenuationLinear; + lt->att[2] = ailt->mAttenuationQuadratic; + if(verbose) { + printf("att(%.2f %.2f %.2f)\n", lt->att[0], lt->att[1], lt->att[2]); + } + + lt->next = scn->lights; + scn->lights = lt; + } + scn->bbox.min[0] = scn->bbox.min[1] = scn->bbox.min[2] = FLT_MAX; scn->bbox.max[0] = scn->bbox.max[1] = scn->bbox.max[2] = -FLT_MAX; @@ -57,8 +120,10 @@ scn->meshes = m; } - printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], - scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); + if(verbose) { + printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], + scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); + } aiReleaseImport(aiscn); return 0; @@ -87,6 +152,10 @@ return 0; } + if(verbose) { + printf("- mesh(%s) v:%d f:%d\n", aim->mName.data, aim->mNumVertices, aim->mNumFaces); + } + /* default material */ color(m->mat.kd, 1, 1, 1); color(m->mat.ks, 0, 0, 0); @@ -162,6 +231,10 @@ return 0; } + if(verbose) { + printf(" - texture: %s (%dx%d)\n", fname, xsz, ysz); + } + glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -176,16 +249,54 @@ void render_scene(struct scene *scn) { - struct mesh *m = scn->meshes; - while(m) { - render_mesh(m); - m = m->next; + struct light *lt = scn->lights; + int pass = 0; + + while(lt || pass == 0) { + struct mesh *m; + + setup_light(lt); + + glEnable(GL_BLEND); + + if(pass > 0) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDepthMask(0); + } else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(1); + } + + m = scn->meshes; + while(m) { + render_mesh(m, pass); + m = m->next; + } + pass++; } } -void render_mesh(struct mesh *m) +static void setup_light(struct light *lt) { - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, m->mat.kd); + if(!lt) + return; + glLightfv(GL_LIGHT0, GL_POSITION, lt->pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lt->color); + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, lt->att[0]); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, lt->att[1]); + glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, lt->att[2]); + glEnable(GL_LIGHT0); +} + +void render_mesh(struct mesh *m, int pass) +{ + if(pass > 0) { + float black[] = {0, 0, 0, 0}; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); + } else { + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m->mat.kd); + } + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m->mat.kd); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m->mat.ks); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->mat.shin); diff -r 9b10c8183d4e -r 7e982a61852a src/scene.h --- a/src/scene.h Thu Jan 19 01:51:05 2012 +0200 +++ b/src/scene.h Thu Jan 19 06:15:10 2012 +0200 @@ -27,6 +27,10 @@ float pos[4]; float color[4]; + float cone_inner, cone_outer; + + float att[3]; + struct light *next; }; @@ -41,6 +45,6 @@ int load_scene(struct scene *scn, const char *fname); void render_scene(struct scene *scn); -void render_mesh(struct mesh *m); +void render_mesh(struct mesh *m, int pass); #endif /* SCENE_H_ */