3 #include "transform.hpp"
6 #include "renderer.hpp" // for checkGl
18 class World::_Private
{
22 _Private() : trrn(512, 64, 9), dlist(GL_NONE
), vbo(GL_NONE
) {
27 glDeleteLists(dlist
, 1);
30 glDeleteBuffers(1, &vbo
);
36 // OpenGL display list containing the world
41 // Transformation from model space to light space.
46 World::World() : _p(new World::_Private()) {
54 static void drawNormals(const vec
* p
, int n
, const vec
& normal
) {
56 for(int i
= 0; i
< n
; i
++) {
58 glVertex3f(p
[i
].x
, p
[i
].y
, p
[i
].z
);
59 glVertex3f(p
[i
].x
+ nn
.x
, p
[i
].y
+ nn
.y
, p
[i
].z
+ nn
.z
);
64 #define drawNormals(p,n,normal)
67 static void drawTrinagle(const vec p
[3]) {
69 vec n
= calculateTriangleNormal(p
);
70 glNormal3f(n
.x
, n
.y
, n
.z
);
72 glBegin(GL_TRIANGLES
);
73 for(int i
= 0; i
< 3; i
++) {
74 glVertex3f(p
[i
].x
, p
[i
].y
, p
[i
].z
);
82 static void drawQuad(const vec p
[4]) {
84 vec n
= calculateNormal(p
, 4);
85 glNormal3f(n
.x
, n
.y
, n
.z
);
88 for(int i
= 0; i
< 4; i
++) {
89 glVertex3f(p
[i
].x
, p
[i
].y
, p
[i
].z
);
97 static void drawQuads(const vec p
[][4], int n
) {
98 for(int i
= 0; i
< n
; i
++) {
103 static void drawTrinagles(const vec p
[][3], int n
) {
104 for(int i
= 0; i
< n
; i
++) {
109 static const float w
= 0.1; // width of objects (height=1.0)
110 static float p
= sqrt(2 * w
* w
);
112 static void drawCuboid() {
157 static void drawSquarePyramid() {
159 vec triangles
[5][3] = {
181 drawTrinagles(triangles
, 4);
194 static void drawTrianglePyramid() {
196 vec triangles
[4][3] = {
221 drawTrinagles(triangles
, 3);
224 static void drawPrism() {
250 vec triangles
[2][3] = {
264 drawTrinagles(triangles
, 2);
270 GLUquadric
* quadr
= gluNewQuadric();
271 glTranslatef(0, 0.2, 0);
272 gluSphere(quadr
, 0.2, 20, 20);
273 glTranslatef(0, -0.2, 0);
274 gluDeleteQuadric(quadr
);
278 void World::render(vec pos
) const {
280 glBindBuffer(GL_ARRAY_BUFFER
, _p
->vbo
);
281 _p
->trrn
.drawVertices(pos
);
283 checkGl("rendering terrain");
285 glCallList(_p
->dlist
);
287 checkGl("rendering objects");
290 void World::generate() {
292 int trrnRandRes
= rand() % 2 ? 4 : 8; // 8 or 16
293 float trrnDiv
= 1.35 + 0.1*(float)(rand()%1024)/1024; // 1.35-1.45
294 float trrnExp
= 0.7 + 1.3*(float)(rand()%1024)/1024; //0.7-2
295 int trrnSeed
= rand();
296 _p
->trrn
.generate(trrnRandRes
,trrnDiv
,trrnExp
,trrnSeed
);
298 glBindBuffer(GL_ARRAY_BUFFER
, _p
->vbo
);
299 _p
->trrn
.generateVertices();
302 glNewList(_p
->dlist
, GL_COMPILE
);
304 static const float a
= 10.0; // width/height of area with objects
309 glColor3d(0.3, 0.3, 0.5);
310 glVertex3d(10 * a, 0.0, 10 * a);
311 glColor3d(0.3, 0.5, 0.3);
312 glVertex3d(10 * a, 0.0, 10 * -a);
313 glColor3d(0.3, 0.3, 0.3);
314 glVertex3d(10 * -a, 0.0, 10 * -a);
315 glColor3d(0.5, 0.3, 0.3);
316 glVertex3d(10 * -a, 0.0, 10 * a);
321 // Create some random objects.
322 int nitems
= (int)randVar(40.0, 5.0);
323 for(int i
= 0; i
< nitems
; ++i
) {
327 float x
= randVal(-a
, a
);
328 float y
= randVal(-a
, a
);
329 float z
= heightAt(x
, y
);
330 glTranslatef(x
, z
, y
);
332 float scale
= randVar(2.5, 1.0);
333 float scale2
= randVar(0.75 * scale
, 0.5);
334 glScalef(scale
, scale2
, scale
);
336 glRotatef(randVal(0.0, 360.0), 0.0, 1.0, 0.0);
338 glColor3f(randVal(0.0,1.0), randVal(0.0,1.0), randVal(0.0,1.0));
340 float type
= randVal();
344 } else if(type
>= 0.60) {
346 } else if(type
>= 0.4) {
348 } else if(type
>= 0.2) {
351 drawTrianglePyramid();
360 checkGl("generating new world");
362 float rx
= r(-135.0);
367 float tz
= 4.0 + heightAt(ty
, -tx
);
369 _p
->lightPos
= t_rotateZ(rz
) * t_rotateX(ry
) * t_rotateY(rx
) * t_translate(vec(-ty
, -tz
, tx
));
373 float World::heightAt(float x
, float y
) const {
374 return _p
->trrn
.heightAt(x
, y
);
378 _p
->dlist
= glGenLists(1);
380 GLenum error
= glGetError();
381 ERROR("generating world display list: %d: %s", error
, gluErrorString(error
));
384 glGenBuffers(1, &_p
->vbo
);
386 GLenum error
= glGetError();
387 ERROR("generating terrain VBO: %d: %s", error
, gluErrorString(error
));
393 const transform
& World::getLightPosition() const {