]> git.lizzy.rs Git - shadowclad.git/blob - render.c
Render the level's grid of blocks
[shadowclad.git] / render.c
1 #include <GL/glut.h>
2 #include <stdbool.h>
3
4 #include "level.h"
5 #include "performance.h"
6 #include "render.h"
7 #include "typedefs.h"
8
9 const float AXIS_RADIUS = 5.0f;
10
11 static void renderBlockGrid(const BlockGrid grid);
12 static void drawBlock(const Block* block);
13
14 void initRender() {
15         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
16         
17         GLfloat light0_ambient[] = {0.1f, 0.1f, 0.1f, 1.0f};
18         GLfloat light0_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
19         GLfloat light0_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
20         GLfloat light0_position[] = {5.0f, 10.0f, 5.0f, 1.0f};
21         
22         glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
23         glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
24         glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
25         glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
26         
27         glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
28         glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05f);
29         glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.005f);
30 }
31
32 void renderScene() {
33         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
34         glLoadIdentity();
35         
36         glEnable(GL_NORMALIZE);
37         glEnable(GL_CULL_FACE);
38         glEnable(GL_DEPTH_TEST);
39         
40         glDisable(GL_LIGHTING);
41         drawAxes();
42         glEnable(GL_LIGHTING);
43         
44         glEnable(GL_LIGHT0);
45         glEnable(GL_TEXTURE_2D);
46 //      drawSceneRecursive(levelScene, levelScene->mRootNode);
47         renderBlockGrid(levelGrid);
48         glDisable(GL_TEXTURE_2D);
49         glDisable(GL_LIGHT0);
50         
51         glFlush();
52         glutSwapBuffers();
53         frameRendered();
54         glutPostRedisplay();
55 }
56
57 void drawAxes() {
58         point3f xAxisStart = { 0.0f, 0.0f, 0.0f };
59         point3f xAxisEnd = { AXIS_RADIUS, 0.0f, 0.0f };
60         point3f yAxisStart = { 0.0f, 0.0f, 0.0f };
61         point3f yAxisEnd = { 0.0f, AXIS_RADIUS, 0.0f };
62         point3f zAxisStart = { 0.0f, 0.0f, 0.0f };
63         point3f zAxisEnd = { 0.0f, 0.0f, AXIS_RADIUS };
64         
65         glColor3f(1.0f, 0.0f, 0.0f);
66         glBegin(GL_LINES);
67         glVertex3fv(xAxisStart);
68         glVertex3fv(xAxisEnd);
69         glEnd();
70         
71         glColor3f(0.0f, 1.0f, 0.0f);
72         glBegin(GL_LINES);
73         glVertex3fv(yAxisStart);
74         glVertex3fv(yAxisEnd);
75         glEnd();
76         
77         glColor3f(0.0f, 0.0f, 1.0f);
78         glBegin(GL_LINES);
79         glVertex3fv(zAxisStart);
80         glVertex3fv(zAxisEnd);
81         glEnd();
82 }
83
84 static void renderBlockGrid(const BlockGrid grid) {
85         glMatrixMode(GL_MODELVIEW);
86         for (int z = 0; z < grid.depth; ++z) {
87                 glLoadIdentity();
88                 glTranslatef(0.0f, 0.0f, z * BLOCKGRID_CELL_SIZE);
89                 for (int x = 0; x < grid.width; ++x) {
90                         drawBlock(getBlockFromGrid(grid, x, z));
91                         glTranslatef(BLOCKGRID_CELL_SIZE, 0.0f, 0.0f);
92                 }
93         }
94         glLoadIdentity();
95 }
96
97 static void drawBlock(const Block* block) {
98         if (block->sceneData == NULL) {
99                 return;
100         }
101         
102         glColor3f(0.5f, 1.0f, 0.0f);
103         
104         for (int i = 0; i < block->sceneData->mNumMeshes; ++i) {
105                 glBindTexture(GL_TEXTURE_2D, block->textureIds[i]);
106                 const AiMesh* mesh = block->sceneData->mMeshes[i];
107                 bool hasNormals = mesh->mNormals != NULL;
108                 bool hasTextureCoords = mesh->mTextureCoords[0] != NULL;
109                 
110                 for (int k = 0; k < mesh->mNumFaces; ++k) {
111                         const AiFace face = mesh->mFaces[k];
112                         
113                         GLenum faceMode;
114                         switch (face.mNumIndices) {
115                                 case 1: faceMode = GL_POINTS; break;
116                                 case 2: faceMode = GL_LINES; break;
117                                 case 3: faceMode = GL_TRIANGLES; break;
118                                 default: faceMode = GL_POLYGON; break;
119                         }
120                         
121                         glBegin(faceMode);
122                         
123                         for (int l = 0; l < face.mNumIndices; ++l) {
124                                 unsigned int vertexIndex = face.mIndices[l];
125                                 if (hasNormals) {
126                                         if (hasTextureCoords) {
127                                                 AiVector3D coords = mesh->mTextureCoords[0][vertexIndex];
128                                                 glTexCoord2f(coords.x, coords.y);
129                                         }
130                                         glNormal3fv(&mesh->mNormals[vertexIndex].x);
131                                 }
132                                 glVertex3fv((const GLfloat*) &mesh->mVertices[vertexIndex]);
133                         }
134                         
135                         glEnd();
136                 }
137         }
138         glBindTexture(GL_TEXTURE_2D, 0);
139 }
140
141 void drawSceneRecursive(const AiScene* scene, const AiNode* node) {
142         if (((*scene).mFlags & AI_SCENE_FLAGS_INCOMPLETE) == AI_SCENE_FLAGS_INCOMPLETE) {
143                 return;
144         }
145         
146         for (int i = 0; i < (*node).mNumMeshes; ++i) {
147                 const AiMesh* mesh = (*scene).mMeshes[(*node).mMeshes[i]];
148                 
149                 for (int k = 0; k < (*mesh).mNumFaces; ++k) {
150                         const AiFace face = (*mesh).mFaces[k];
151                         
152                         GLenum faceMode;
153                         switch (face.mNumIndices) {
154                                 case 1: faceMode = GL_POINTS; break;
155                                 case 2: faceMode = GL_LINES; break;
156                                 case 3: faceMode = GL_TRIANGLES; break;
157                                 default: faceMode = GL_POLYGON; break;
158                         }
159                         
160                         glBegin(faceMode);
161                         
162                         glColor3f(1.0f, 1.0f, 1.0f);
163                         for (int l = 0; l < face.mNumIndices; ++l) {
164                                 glVertex3fv((const GLfloat*) &(*mesh).mVertices[face.mIndices[l]]);
165                         }
166                         
167                         glEnd();
168                 }
169         }
170         
171         for (int i = 0; i < (*node).mNumChildren; ++i) {
172                 drawSceneRecursive(scene, (*node).mChildren[i]);
173         }
174 }