/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2006 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: hdavid, amaechler co-programmer: ... */ #include "skydome.h" #include "util/loading/load_param.h" #include "util/loading/factory.h" #include "static_model.h" #include "shader.h" #include "network_game_manager.h" #include "converter.h" #include "util/loading/resource_manager.h" #include "debug.h" #define DTOR (PI/180.0f) #define SQR(x) (x*x) ObjectListDefinition(Skydome); /** * initializes a skybox from a XmlElement */ Skydome::Skydome() { this->init(); } void Skydome::init() { PRINTF(0)("Skydome init\n"); this->registerObject(this, Skydome::_objectList); this->toList(OM_BACKGROUND); this->toReflectionList(); this->indices = NULL; this->vertices = NULL; this->planeVertices = NULL; this->shader = NULL; activateDome = false; } /** * default destructor */ Skydome::~Skydome() { PRINTF(0)("Deleting Skydome\n"); if (glIsTexture(texture)) glDeleteTextures(1, &texture); } void Skydome::setShader(Shader* shader) { this->shader = shader; } void Skydome::setTexture(GLuint texture) { this->texture = texture; } void Skydome::activate() { this->activateDome = true; } void Skydome::deactivate() { this->activateDome = false; } void Skydome::draw() const { if(!activateDome) return; glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glDisable(GL_BLEND); glDisable(GL_FOG); glEnable(GL_TEXTURE_3D); glBindTexture(GL_TEXTURE_3D, texture); this->shader->activateShader(); glPushMatrix(); glTranslatef(0.0f,pRadius,0.0f); glBegin(GL_TRIANGLES); for (int i=0; i < numIndices; i++) { glColor3f(1.0f, 1.0f, 1.0f); glTexCoord2f(planeVertices[indices[i]].u, planeVertices[indices[i]].v); glVertex3f(planeVertices[indices[i]].x, planeVertices[indices[i]].y, planeVertices[indices[i]].z); } glEnd(); WorldEntity::draw(); glPopMatrix(); this->shader->deactivateShader(); glPopAttrib(); } void Skydome::generateSkyPlane(int divisions, float planetRadius, float atmosphereRadius, float hTile, float vTile) { PRINTF(0)("Generating a sky plane\n"); // Make sure our vertex array is clear if (planeVertices) { delete planeVertices; planeVertices = NULL; } // Make sure our index array is clear if (indices) { delete indices; indices = NULL; } // Set the number of divisions into a valid range int divs = divisions; if (divisions < 1) divs = 1; if (divisions > 256) divs = 256; pRadius = planetRadius; // Initialize the Vertex and indices arrays numPlaneVertices = (divs + 1) * (divs + 1); // 1 division would give 4 verts numIndices = divs * divs * 2 * 3; // 1 division would give 6 indices for 2 tris planeVertices = new VertexInfo[numPlaneVertices]; memset(planeVertices, 0, sizeof(VertexInfo)); indices = new int[numIndices]; memset(indices, 0, sizeof(int)*numIndices); // Calculate some values we will need float plane_size = 2.0f * (float)sqrt((SQR(atmosphereRadius)-SQR(planetRadius))); float delta = plane_size/(float)divs; float tex_delta = 2.0f/(float)divs; // Variables we'll use during the dome's generation float x_dist = 0.0f; float z_dist = 0.0f; float x_height = 0.0f; float z_height = 0.0f; float height = 0.0f; VertexInfo SV; // temporary vertex for (int i=0;i <= divs;i++) { for (int j=0; j <= divs; j++) { x_dist = (-0.5f * plane_size) + ((float)j*delta); z_dist = (-0.5f * plane_size) + ((float)i*delta); x_height = (x_dist*x_dist) / atmosphereRadius; z_height = (z_dist*z_dist) / atmosphereRadius; height = x_height + z_height; SV.x = x_dist; SV.y = 0.0f - height; SV.z = z_dist; // Calculate the texture coordinates SV.u = hTile*((float)j * tex_delta*0.5f); SV.v = vTile*(1.0f - (float)i * tex_delta*0.5f); planeVertices[i*(divs+1)+j] = SV; } } // Calculate the indices int index = 0; for (int i=0; i < divs;i++) { for (int j=0; j < divs; j++) { int startvert = (i*(divs+1) + j); // tri 1 indices[index++] = startvert; indices[index++] = startvert+1; indices[index++] = startvert+divs+1; // tri 2 indices[index++] = startvert+1; indices[index++] = startvert+divs+2; indices[index++] = startvert+divs+1; } } }