view3d
changeset 1:7650e941805c
forgot two files
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 19 Jan 2012 00:17:49 +0200 |
parents | 182bfd9f55c7 |
children | 9b10c8183d4e |
files | src/scene.c src/scene.h |
diffstat | 2 files changed, 270 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/scene.c Thu Jan 19 00:17:49 2012 +0200 1.3 @@ -0,0 +1,224 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <float.h> 1.7 + 1.8 +#include <GL/glew.h> 1.9 + 1.10 +#include <assimp/assimp.h> 1.11 +#include <assimp/aiScene.h> 1.12 +#include <assimp/aiPostProcess.h> 1.13 + 1.14 +#include <imago2.h> 1.15 + 1.16 +#include "scene.h" 1.17 + 1.18 +static void color(float *dest, float r, float g, float b); 1.19 +static struct mesh *create_mesh(const struct aiScene *aiscn, struct aiMesh *aim); 1.20 +static unsigned int create_buffer(unsigned int type, void *data, size_t sz); 1.21 +static unsigned int load_texture(const char *fname); 1.22 + 1.23 + 1.24 +int load_scene(struct scene *scn, const char *fname) 1.25 +{ 1.26 + int i, j; 1.27 + const struct aiScene *aiscn; 1.28 + unsigned int proc_flags = aiProcess_JoinIdenticalVertices | 1.29 + aiProcess_PreTransformVertices | aiProcess_Triangulate | 1.30 + aiProcess_GenNormals | aiProcess_SortByPType; 1.31 + 1.32 + if(!(aiscn = aiImportFile(fname, proc_flags))) { 1.33 + fprintf(stderr, "failed to load: %s\n", fname); 1.34 + return -1; 1.35 + } 1.36 + 1.37 + scn->meshes = 0; 1.38 + scn->lights = 0; 1.39 + 1.40 + scn->bbox.min[0] = scn->bbox.min[1] = scn->bbox.min[2] = FLT_MAX; 1.41 + scn->bbox.max[0] = scn->bbox.max[1] = scn->bbox.max[2] = -FLT_MAX; 1.42 + 1.43 + for(i=0; i<aiscn->mNumMeshes; i++) { 1.44 + struct mesh *m; 1.45 + 1.46 + if(!(m = create_mesh(aiscn, aiscn->mMeshes[i]))) { 1.47 + return -1; 1.48 + } 1.49 + 1.50 + for(j=0; j<3; j++) { 1.51 + if(m->bbox.min[j] < scn->bbox.min[j]) { 1.52 + scn->bbox.min[j] = m->bbox.min[j]; 1.53 + } 1.54 + if(m->bbox.max[j] > scn->bbox.max[j]) { 1.55 + scn->bbox.max[j] = m->bbox.max[j]; 1.56 + } 1.57 + } 1.58 + 1.59 + m->next = scn->meshes; 1.60 + scn->meshes = m; 1.61 + } 1.62 + 1.63 + printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1], 1.64 + scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]); 1.65 + 1.66 + aiReleaseImport(aiscn); 1.67 + return 0; 1.68 +} 1.69 + 1.70 +static void color(float *dest, float r, float g, float b) 1.71 +{ 1.72 + dest[0] = r; 1.73 + dest[1] = g; 1.74 + dest[2] = b; 1.75 + dest[3] = 1.0; 1.76 +} 1.77 + 1.78 +static struct mesh *create_mesh(const struct aiScene *aiscn, struct aiMesh *aim) 1.79 +{ 1.80 + int i, j; 1.81 + struct mesh *m; 1.82 + struct aiMaterial *mat = aiscn->mMaterials[aim->mMaterialIndex]; 1.83 + float sstr = 1.0; 1.84 + unsigned int sz, *idxarr, *dptr; 1.85 + struct aiVector3D *vptr; 1.86 + struct aiString tex_name; 1.87 + 1.88 + if(!(m = calloc(1, sizeof *m))) { 1.89 + perror("failed to allocate mesh"); 1.90 + return 0; 1.91 + } 1.92 + 1.93 + /* default material */ 1.94 + color(m->mat.kd, 1, 1, 1); 1.95 + color(m->mat.ks, 0, 0, 0); 1.96 + m->mat.shin = 60.0; 1.97 + 1.98 + aiGetMaterialColor(mat, AI_MATKEY_COLOR_DIFFUSE, (void*)m->mat.kd); 1.99 + aiGetMaterialColor(mat, AI_MATKEY_COLOR_SPECULAR, (void*)m->mat.ks); 1.100 + sz = 1; 1.101 + aiGetMaterialFloatArray(mat, AI_MATKEY_SHININESS, &m->mat.shin, &sz); 1.102 + sz = 1; 1.103 + aiGetMaterialFloatArray(mat, AI_MATKEY_SHININESS_STRENGTH, &sstr, &sz); 1.104 + color(m->mat.ks, m->mat.ks[0] * sstr, m->mat.ks[1] * sstr, m->mat.ks[2] * sstr); 1.105 + 1.106 + if(aiGetMaterialString(mat, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0), &tex_name) == 0) { 1.107 + m->mat.tex = load_texture(tex_name.data); 1.108 + } 1.109 + 1.110 + m->num_verts = aim->mNumVertices; 1.111 + m->num_faces = aim->mNumFaces; 1.112 + 1.113 + m->bbox.min[0] = m->bbox.min[1] = m->bbox.min[2] = FLT_MAX; 1.114 + m->bbox.max[0] = m->bbox.max[1] = m->bbox.max[2] = -FLT_MAX; 1.115 + 1.116 + vptr = aim->mVertices; 1.117 + for(i=0; i<m->num_verts; i++) { 1.118 + if(vptr->x < m->bbox.min[0]) m->bbox.min[0] = vptr->x; 1.119 + if(vptr->y < m->bbox.min[1]) m->bbox.min[1] = vptr->y; 1.120 + if(vptr->z < m->bbox.min[2]) m->bbox.min[2] = vptr->z; 1.121 + if(vptr->x > m->bbox.max[0]) m->bbox.max[0] = vptr->x; 1.122 + if(vptr->y > m->bbox.max[1]) m->bbox.max[1] = vptr->y; 1.123 + if(vptr->z > m->bbox.max[2]) m->bbox.max[2] = vptr->z; 1.124 + vptr++; 1.125 + } 1.126 + 1.127 + m->vert_buf = create_buffer(GL_ARRAY_BUFFER, aim->mVertices, m->num_verts * sizeof *aim->mVertices); 1.128 + if(aim->mNormals) { 1.129 + m->norm_buf = create_buffer(GL_ARRAY_BUFFER, aim->mNormals, m->num_verts * sizeof *aim->mNormals); 1.130 + } 1.131 + if(aim->mTextureCoords) { 1.132 + m->tex_buf = create_buffer(GL_ARRAY_BUFFER, aim->mTextureCoords, m->num_verts * sizeof *aim->mTextureCoords); 1.133 + } 1.134 + 1.135 + /* indices are scattered all over the fucking place... map the buffer and collect them there directly */ 1.136 + m->idx_buf = create_buffer(GL_ELEMENT_ARRAY_BUFFER, 0, m->num_faces * 3 * sizeof *aim->mFaces[0].mIndices); 1.137 + dptr = idxarr = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); 1.138 + 1.139 + for(i=0; i<m->num_faces; i++) { 1.140 + for(j=0; j<3; j++) { 1.141 + *dptr++ = aim->mFaces[i].mIndices[j]; 1.142 + } 1.143 + } 1.144 + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); 1.145 + return m; 1.146 +} 1.147 + 1.148 +static unsigned int create_buffer(unsigned int type, void *data, size_t sz) 1.149 +{ 1.150 + unsigned int vbo; 1.151 + glGenBuffers(1, &vbo); 1.152 + glBindBuffer(type, vbo); 1.153 + glBufferData(type, sz, data, GL_STATIC_DRAW); 1.154 + return vbo; 1.155 +} 1.156 + 1.157 +static unsigned int load_texture(const char *fname) 1.158 +{ 1.159 + unsigned int tex; 1.160 + void *pixels; 1.161 + int xsz, ysz; 1.162 + 1.163 + if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) { 1.164 + fprintf(stderr, "failed to load image: %s\n", fname); 1.165 + return 0; 1.166 + } 1.167 + 1.168 + glGenTextures(1, &tex); 1.169 + glBindTexture(GL_TEXTURE_2D, tex); 1.170 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.171 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.172 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 1.173 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 1.174 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 1.175 + 1.176 + img_free_pixels(pixels); 1.177 + return tex; 1.178 +} 1.179 + 1.180 +void render_scene(struct scene *scn) 1.181 +{ 1.182 + struct mesh *m = scn->meshes; 1.183 + while(m) { 1.184 + render_mesh(m); 1.185 + m = m->next; 1.186 + } 1.187 +} 1.188 + 1.189 +void render_mesh(struct mesh *m) 1.190 +{ 1.191 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, m->mat.kd); 1.192 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m->mat.ks); 1.193 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->mat.shin); 1.194 + 1.195 + if(m->mat.tex) { 1.196 + glEnable(GL_TEXTURE_2D); 1.197 + glBindTexture(GL_TEXTURE_2D, m->mat.tex); 1.198 + } 1.199 + 1.200 + /* TODO texture */ 1.201 + 1.202 + glBindBuffer(GL_ARRAY_BUFFER, m->vert_buf); 1.203 + glVertexPointer(3, GL_FLOAT, 0, 0); 1.204 + glEnableClientState(GL_VERTEX_ARRAY); 1.205 + 1.206 + if(m->norm_buf) { 1.207 + glBindBuffer(GL_ARRAY_BUFFER, m->norm_buf); 1.208 + glNormalPointer(GL_FLOAT, 0, 0); 1.209 + glEnableClientState(GL_NORMAL_ARRAY); 1.210 + } 1.211 + if(m->tex_buf) { 1.212 + glBindBuffer(GL_ARRAY_BUFFER, m->tex_buf); 1.213 + glTexCoordPointer(3, GL_FLOAT, 0, 0); 1.214 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1.215 + } 1.216 + 1.217 + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->idx_buf); 1.218 + glDrawElements(GL_TRIANGLES, m->num_faces * 3, GL_UNSIGNED_INT, 0); 1.219 + 1.220 + glDisableClientState(GL_VERTEX_ARRAY); 1.221 + glDisableClientState(GL_NORMAL_ARRAY); 1.222 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1.223 + 1.224 + if(m->mat.tex) { 1.225 + glDisable(GL_TEXTURE_2D); 1.226 + } 1.227 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/scene.h Thu Jan 19 00:17:49 2012 +0200 2.3 @@ -0,0 +1,46 @@ 2.4 +#ifndef SCENE_H_ 2.5 +#define SCENE_H_ 2.6 + 2.7 +struct aabb { 2.8 + float min[3], max[3]; 2.9 +}; 2.10 + 2.11 +struct material { 2.12 + float kd[4]; 2.13 + float ks[4]; 2.14 + float shin; 2.15 + unsigned int tex; 2.16 +}; 2.17 + 2.18 +struct mesh { 2.19 + unsigned int vert_buf, norm_buf, tex_buf, idx_buf; 2.20 + int num_verts, num_faces; 2.21 + 2.22 + struct material mat; 2.23 + 2.24 + struct aabb bbox; 2.25 + 2.26 + struct mesh *next; 2.27 +}; 2.28 + 2.29 +struct light { 2.30 + float pos[4]; 2.31 + float color[4]; 2.32 + 2.33 + struct light *next; 2.34 +}; 2.35 + 2.36 +struct scene { 2.37 + struct mesh *meshes; 2.38 + struct light *lights; 2.39 + 2.40 + struct aabb bbox; 2.41 +}; 2.42 + 2.43 + 2.44 +int load_scene(struct scene *scn, const char *fname); 2.45 + 2.46 +void render_scene(struct scene *scn); 2.47 +void render_mesh(struct mesh *m); 2.48 + 2.49 +#endif /* SCENE_H_ */