view3d
changeset 3:7e982a61852a
lights and shit
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 19 Jan 2012 06:15:10 +0200 |
parents | 9b10c8183d4e |
children | 0aee5df08cfc |
files | src/main.c src/scene.c src/scene.h |
diffstat | 3 files changed, 136 insertions(+), 13 deletions(-) [+] |
line diff
1.1 --- a/src/main.c Thu Jan 19 01:51:05 2012 +0200 1.2 +++ b/src/main.c Thu Jan 19 06:15:10 2012 +0200 1.3 @@ -30,7 +30,7 @@ 1.4 int win_width, win_height; 1.5 int stereo; 1.6 int flip_winding; 1.7 -int auto_rot = 1; 1.8 +int auto_rot; 1.9 float cam_theta, cam_phi, cam_dist = 10; 1.10 float near_clip = 0.5; 1.11 float far_clip = 1000.0; 1.12 @@ -38,11 +38,13 @@ 1.13 float stereo_focus_dist = 1.0; 1.14 float stereo_eye_sep = 1.0 / 30.0; 1.15 1.16 +int verbose = 0; 1.17 + 1.18 struct scene scn; 1.19 1.20 int main(int argc, char **argv) 1.21 { 1.22 - float ldir[] = {1, -1, -1, 0}; 1.23 + float ldir[] = {-1, 1, 1, 0}; 1.24 float dx, dy, dz, diag; 1.25 1.26 glutInitWindowSize(800, 600); 1.27 @@ -64,7 +66,9 @@ 1.28 glutSpaceballMotionFunc(sball_motion); 1.29 glutSpaceballRotateFunc(sball_rotate); 1.30 glutSpaceballButtonFunc(sball_button); 1.31 - glutIdleFunc(glutPostRedisplay); 1.32 + if(auto_rot) { 1.33 + glutIdleFunc(glutPostRedisplay); 1.34 + } 1.35 1.36 glewInit(); 1.37 1.38 @@ -329,6 +333,10 @@ 1.39 flip_winding = 1; 1.40 break; 1.41 1.42 + case 'v': 1.43 + verbose = !verbose; 1.44 + break; 1.45 + 1.46 default: 1.47 goto inval; 1.48 }
2.1 --- a/src/scene.c Thu Jan 19 01:51:05 2012 +0200 2.2 +++ b/src/scene.c Thu Jan 19 06:15:10 2012 +0200 2.3 @@ -12,11 +12,13 @@ 2.4 2.5 #include "scene.h" 2.6 2.7 +static void setup_light(struct light *lt); 2.8 static void color(float *dest, float r, float g, float b); 2.9 static struct mesh *create_mesh(const struct aiScene *aiscn, struct aiMesh *aim); 2.10 static unsigned int create_buffer(unsigned int type, void *data, size_t sz); 2.11 static unsigned int load_texture(const char *fname); 2.12 2.13 +extern int verbose; 2.14 2.15 int load_scene(struct scene *scn, const char *fname) 2.16 { 2.17 @@ -24,7 +26,11 @@ 2.18 const struct aiScene *aiscn; 2.19 unsigned int proc_flags = aiProcess_JoinIdenticalVertices | 2.20 aiProcess_PreTransformVertices | aiProcess_Triangulate | 2.21 - aiProcess_GenNormals | aiProcess_SortByPType; 2.22 + aiProcess_SortByPType; 2.23 + 2.24 + if(verbose) { 2.25 + printf("scene: %s (%d meshes, %d lights)\n", fname, aiscn->mNumMeshes, aiscn->mNumLights); 2.26 + } 2.27 2.28 if(!(aiscn = aiImportFile(fname, proc_flags))) { 2.29 fprintf(stderr, "failed to load: %s\n", fname); 2.30 @@ -34,6 +40,63 @@ 2.31 scn->meshes = 0; 2.32 scn->lights = 0; 2.33 2.34 + for(i=0; i<aiscn->mNumLights; i++) { 2.35 + struct light *lt; 2.36 + struct aiLight *ailt = aiscn->mLights[i]; 2.37 + 2.38 + if(!(lt = malloc(sizeof *lt))) { 2.39 + perror("failed to allocate light"); 2.40 + return -1; 2.41 + } 2.42 + 2.43 + if(verbose) { 2.44 + printf("- light(%s) ", ailt->mName.data); 2.45 + } 2.46 + 2.47 + switch(ailt->mType) { 2.48 + case aiLightSource_POINT: 2.49 + lt->pos[0] = ailt->mPosition.x; 2.50 + lt->pos[1] = ailt->mPosition.y; 2.51 + lt->pos[2] = ailt->mPosition.z; 2.52 + lt->pos[3] = 1.0f; 2.53 + if(verbose) { 2.54 + printf("pos(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]); 2.55 + } 2.56 + break; 2.57 + 2.58 + case aiLightSource_DIRECTIONAL: 2.59 + lt->pos[0] = ailt->mDirection.x; 2.60 + lt->pos[1] = ailt->mDirection.y; 2.61 + lt->pos[2] = ailt->mDirection.z; 2.62 + lt->pos[3] = 0.0f; 2.63 + if(verbose) { 2.64 + printf("dir(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]); 2.65 + } 2.66 + break; 2.67 + 2.68 + default: 2.69 + fprintf(stderr, "error loading light: %s, unsupported type\n", ailt->mName.data); 2.70 + continue; 2.71 + } 2.72 + color(lt->color, ailt->mColorDiffuse.r, ailt->mColorDiffuse.g, ailt->mColorDiffuse.b); 2.73 + if(verbose) { 2.74 + printf("col(%.2f %.2f %.2f) ", lt->color[0], lt->color[1], lt->color[2]); 2.75 + } 2.76 + 2.77 + lt->cone_inner = ailt->mAngleInnerCone; 2.78 + lt->cone_outer = ailt->mAngleOuterCone; 2.79 + 2.80 + lt->att[0] = ailt->mAttenuationConstant; 2.81 + lt->att[1] = ailt->mAttenuationLinear; 2.82 + lt->att[2] = ailt->mAttenuationQuadratic; 2.83 + if(verbose) { 2.84 + printf("att(%.2f %.2f %.2f)\n", lt->att[0], lt->att[1], lt->att[2]); 2.85 + } 2.86 + 2.87 + lt->next = scn->lights; 2.88 + scn->lights = lt; 2.89 + } 2.90 + 2.91 scn->bbox.min[0] = scn->bbox.min[1] = scn->bbox.min[2] = FLT_MAX; 2.92 scn->bbox.max[0] = scn->bbox.max[1] = scn->bbox.max[2] = -FLT_MAX; 2.93 2.94 @@ -57,8 +120,10 @@ 2.95 scn->meshes = m; 2.96 } 2.97 2.98 - printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], 2.99 - scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); 2.100 + if(verbose) { 2.101 + printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], 2.102 + scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); 2.103 + } 2.104 2.105 aiReleaseImport(aiscn); 2.106 return 0; 2.107 @@ -87,6 +152,10 @@ 2.108 return 0; 2.109 } 2.110 2.111 + if(verbose) { 2.112 + printf("- mesh(%s) v:%d f:%d\n", aim->mName.data, aim->mNumVertices, aim->mNumFaces); 2.113 + } 2.114 + 2.115 /* default material */ 2.116 color(m->mat.kd, 1, 1, 1); 2.117 color(m->mat.ks, 0, 0, 0); 2.118 @@ -162,6 +231,10 @@ 2.119 return 0; 2.120 } 2.121 2.122 + if(verbose) { 2.123 + printf(" - texture: %s (%dx%d)\n", fname, xsz, ysz); 2.124 + } 2.125 + 2.126 glGenTextures(1, &tex); 2.127 glBindTexture(GL_TEXTURE_2D, tex); 2.128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2.129 @@ -176,16 +249,54 @@ 2.130 2.131 void render_scene(struct scene *scn) 2.132 { 2.133 - struct mesh *m = scn->meshes; 2.134 - while(m) { 2.135 - render_mesh(m); 2.136 - m = m->next; 2.137 + struct light *lt = scn->lights; 2.138 + int pass = 0; 2.139 + 2.140 + while(lt || pass == 0) { 2.141 + struct mesh *m; 2.142 + 2.143 + setup_light(lt); 2.144 + 2.145 + glEnable(GL_BLEND); 2.146 + 2.147 + if(pass > 0) { 2.148 + glBlendFunc(GL_SRC_ALPHA, GL_ONE); 2.149 + glDepthMask(0); 2.150 + } else { 2.151 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2.152 + glDepthMask(1); 2.153 + } 2.154 + 2.155 + m = scn->meshes; 2.156 + while(m) { 2.157 + render_mesh(m, pass); 2.158 + m = m->next; 2.159 + } 2.160 + pass++; 2.161 } 2.162 } 2.163 2.164 -void render_mesh(struct mesh *m) 2.165 +static void setup_light(struct light *lt) 2.166 { 2.167 - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, m->mat.kd); 2.168 + if(!lt) 2.169 + return; 2.170 + glLightfv(GL_LIGHT0, GL_POSITION, lt->pos); 2.171 + glLightfv(GL_LIGHT0, GL_DIFFUSE, lt->color); 2.172 + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, lt->att[0]); 2.173 + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, lt->att[1]); 2.174 + glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, lt->att[2]); 2.175 + glEnable(GL_LIGHT0); 2.176 +} 2.177 + 2.178 +void render_mesh(struct mesh *m, int pass) 2.179 +{ 2.180 + if(pass > 0) { 2.181 + float black[] = {0, 0, 0, 0}; 2.182 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); 2.183 + } else { 2.184 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m->mat.kd); 2.185 + } 2.186 + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m->mat.kd); 2.187 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m->mat.ks); 2.188 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->mat.shin); 2.189
3.1 --- a/src/scene.h Thu Jan 19 01:51:05 2012 +0200 3.2 +++ b/src/scene.h Thu Jan 19 06:15:10 2012 +0200 3.3 @@ -27,6 +27,10 @@ 3.4 float pos[4]; 3.5 float color[4]; 3.6 3.7 + float cone_inner, cone_outer; 3.8 + 3.9 + float att[3]; 3.10 + 3.11 struct light *next; 3.12 }; 3.13 3.14 @@ -41,6 +45,6 @@ 3.15 int load_scene(struct scene *scn, const char *fname); 3.16 3.17 void render_scene(struct scene *scn); 3.18 -void render_mesh(struct mesh *m); 3.19 +void render_mesh(struct mesh *m, int pass); 3.20 3.21 #endif /* SCENE_H_ */