view3d
diff src/scene.c @ 3:7e982a61852a
lights and shit
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 19 Jan 2012 06:15:10 +0200 |
parents | 9b10c8183d4e |
children | 0aee5df08cfc |
line diff
1.1 --- a/src/scene.c Thu Jan 19 01:51:05 2012 +0200 1.2 +++ b/src/scene.c Thu Jan 19 06:15:10 2012 +0200 1.3 @@ -12,11 +12,13 @@ 1.4 1.5 #include "scene.h" 1.6 1.7 +static void setup_light(struct light *lt); 1.8 static void color(float *dest, float r, float g, float b); 1.9 static struct mesh *create_mesh(const struct aiScene *aiscn, struct aiMesh *aim); 1.10 static unsigned int create_buffer(unsigned int type, void *data, size_t sz); 1.11 static unsigned int load_texture(const char *fname); 1.12 1.13 +extern int verbose; 1.14 1.15 int load_scene(struct scene *scn, const char *fname) 1.16 { 1.17 @@ -24,7 +26,11 @@ 1.18 const struct aiScene *aiscn; 1.19 unsigned int proc_flags = aiProcess_JoinIdenticalVertices | 1.20 aiProcess_PreTransformVertices | aiProcess_Triangulate | 1.21 - aiProcess_GenNormals | aiProcess_SortByPType; 1.22 + aiProcess_SortByPType; 1.23 + 1.24 + if(verbose) { 1.25 + printf("scene: %s (%d meshes, %d lights)\n", fname, aiscn->mNumMeshes, aiscn->mNumLights); 1.26 + } 1.27 1.28 if(!(aiscn = aiImportFile(fname, proc_flags))) { 1.29 fprintf(stderr, "failed to load: %s\n", fname); 1.30 @@ -34,6 +40,63 @@ 1.31 scn->meshes = 0; 1.32 scn->lights = 0; 1.33 1.34 + for(i=0; i<aiscn->mNumLights; i++) { 1.35 + struct light *lt; 1.36 + struct aiLight *ailt = aiscn->mLights[i]; 1.37 + 1.38 + if(!(lt = malloc(sizeof *lt))) { 1.39 + perror("failed to allocate light"); 1.40 + return -1; 1.41 + } 1.42 + 1.43 + if(verbose) { 1.44 + printf("- light(%s) ", ailt->mName.data); 1.45 + } 1.46 + 1.47 + switch(ailt->mType) { 1.48 + case aiLightSource_POINT: 1.49 + lt->pos[0] = ailt->mPosition.x; 1.50 + lt->pos[1] = ailt->mPosition.y; 1.51 + lt->pos[2] = ailt->mPosition.z; 1.52 + lt->pos[3] = 1.0f; 1.53 + if(verbose) { 1.54 + printf("pos(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]); 1.55 + } 1.56 + break; 1.57 + 1.58 + case aiLightSource_DIRECTIONAL: 1.59 + lt->pos[0] = ailt->mDirection.x; 1.60 + lt->pos[1] = ailt->mDirection.y; 1.61 + lt->pos[2] = ailt->mDirection.z; 1.62 + lt->pos[3] = 0.0f; 1.63 + if(verbose) { 1.64 + printf("dir(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]); 1.65 + } 1.66 + break; 1.67 + 1.68 + default: 1.69 + fprintf(stderr, "error loading light: %s, unsupported type\n", ailt->mName.data); 1.70 + continue; 1.71 + } 1.72 + color(lt->color, ailt->mColorDiffuse.r, ailt->mColorDiffuse.g, ailt->mColorDiffuse.b); 1.73 + if(verbose) { 1.74 + printf("col(%.2f %.2f %.2f) ", lt->color[0], lt->color[1], lt->color[2]); 1.75 + } 1.76 + 1.77 + lt->cone_inner = ailt->mAngleInnerCone; 1.78 + lt->cone_outer = ailt->mAngleOuterCone; 1.79 + 1.80 + lt->att[0] = ailt->mAttenuationConstant; 1.81 + lt->att[1] = ailt->mAttenuationLinear; 1.82 + lt->att[2] = ailt->mAttenuationQuadratic; 1.83 + if(verbose) { 1.84 + printf("att(%.2f %.2f %.2f)\n", lt->att[0], lt->att[1], lt->att[2]); 1.85 + } 1.86 + 1.87 + lt->next = scn->lights; 1.88 + scn->lights = lt; 1.89 + } 1.90 + 1.91 scn->bbox.min[0] = scn->bbox.min[1] = scn->bbox.min[2] = FLT_MAX; 1.92 scn->bbox.max[0] = scn->bbox.max[1] = scn->bbox.max[2] = -FLT_MAX; 1.93 1.94 @@ -57,8 +120,10 @@ 1.95 scn->meshes = m; 1.96 } 1.97 1.98 - printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], 1.99 - scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); 1.100 + if(verbose) { 1.101 + printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], 1.102 + scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); 1.103 + } 1.104 1.105 aiReleaseImport(aiscn); 1.106 return 0; 1.107 @@ -87,6 +152,10 @@ 1.108 return 0; 1.109 } 1.110 1.111 + if(verbose) { 1.112 + printf("- mesh(%s) v:%d f:%d\n", aim->mName.data, aim->mNumVertices, aim->mNumFaces); 1.113 + } 1.114 + 1.115 /* default material */ 1.116 color(m->mat.kd, 1, 1, 1); 1.117 color(m->mat.ks, 0, 0, 0); 1.118 @@ -162,6 +231,10 @@ 1.119 return 0; 1.120 } 1.121 1.122 + if(verbose) { 1.123 + printf(" - texture: %s (%dx%d)\n", fname, xsz, ysz); 1.124 + } 1.125 + 1.126 glGenTextures(1, &tex); 1.127 glBindTexture(GL_TEXTURE_2D, tex); 1.128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.129 @@ -176,16 +249,54 @@ 1.130 1.131 void render_scene(struct scene *scn) 1.132 { 1.133 - struct mesh *m = scn->meshes; 1.134 - while(m) { 1.135 - render_mesh(m); 1.136 - m = m->next; 1.137 + struct light *lt = scn->lights; 1.138 + int pass = 0; 1.139 + 1.140 + while(lt || pass == 0) { 1.141 + struct mesh *m; 1.142 + 1.143 + setup_light(lt); 1.144 + 1.145 + glEnable(GL_BLEND); 1.146 + 1.147 + if(pass > 0) { 1.148 + glBlendFunc(GL_SRC_ALPHA, GL_ONE); 1.149 + glDepthMask(0); 1.150 + } else { 1.151 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.152 + glDepthMask(1); 1.153 + } 1.154 + 1.155 + m = scn->meshes; 1.156 + while(m) { 1.157 + render_mesh(m, pass); 1.158 + m = m->next; 1.159 + } 1.160 + pass++; 1.161 } 1.162 } 1.163 1.164 -void render_mesh(struct mesh *m) 1.165 +static void setup_light(struct light *lt) 1.166 { 1.167 - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, m->mat.kd); 1.168 + if(!lt) 1.169 + return; 1.170 + glLightfv(GL_LIGHT0, GL_POSITION, lt->pos); 1.171 + glLightfv(GL_LIGHT0, GL_DIFFUSE, lt->color); 1.172 + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, lt->att[0]); 1.173 + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, lt->att[1]); 1.174 + glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, lt->att[2]); 1.175 + glEnable(GL_LIGHT0); 1.176 +} 1.177 + 1.178 +void render_mesh(struct mesh *m, int pass) 1.179 +{ 1.180 + if(pass > 0) { 1.181 + float black[] = {0, 0, 0, 0}; 1.182 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); 1.183 + } else { 1.184 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m->mat.kd); 1.185 + } 1.186 + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m->mat.kd); 1.187 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m->mat.ks); 1.188 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->mat.shin); 1.189