//======================================================================== // File: Sky.cpp - implements a sky box in D3D9 or D3D11 // // Part of the GameCode4 Application // // GameCode4 is the sample application that encapsulates much of the source code // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David // "Rez" Graham, published by Charles River Media. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574 // // If this source code has found it's way to you, and you think it has helped you // in any way, do the authors a favor and buy a new copy of the book - there are // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com // by clicking here: // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller= // // There's a companion web site at http://www.mcshaffry.com/GameCode/ // // The source code is managed and maintained through Google Code: // http://code.google.com/p/gamecode4/ // // (c) Copyright 2012 Michael L. McShaffry and David Graham // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser GPL v3 // as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // http://www.gnu.org/licenses/lgpl-3.0.txt for more details. // // You should have received a copy of the GNU Lesser GPL v3 // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //======================================================================== #include "../Unix/GameCodeStd.h" #include "Sky.h" #include "Scene.h" //////////////////////////////////////////////////// // SkyNode Implementation //////////////////////////////////////////////////// // // SkyNode::SkyNode - Chapter 16, page 554 // SkyNode::SkyNode(const char *pTextureBaseName) : SceneNode(INVALID_ACTOR_ID, WeakBaseRenderComponentPtr(), RenderPass_Sky, glm::mat4(1.0f)), m_bActive(true) { m_textureBaseName = pTextureBaseName; } SkyNode::~SkyNode() { } // // SkyNode::VPreRender - Chapter 14, page 502 // int SkyNode::VPreRender(Scene *pScene) { glm::vec3 cameraPos = geometry::GetPosition(m_camera->VGet()->ToWorld()); glm::mat4 mat = m_Props.ToWorld(); geometry::SetPosition(mat, cameraPos); VSetTransform(mat); return SceneNode::VPreRender(pScene); } OpenGLSkyNode46::OpenGLSkyNode46(const char* pTextureBaseName) : SkyNode(pTextureBaseName), m_vao(0), m_vbo(0), m_ebo(0), m_numIndices(0) { m_ShaderProgram.EnableLights(false); } OpenGLSkyNode46::~OpenGLSkyNode46() { glDeleteVertexArrays(1, &m_vao); glDeleteBuffers(1, &m_vbo); glDeleteBuffers(1, &m_ebo); } int OpenGLSkyNode46::VOnRestore(Scene *pScene) { // TODO(munnellg) - implement // TODO(munnellg) - these VOnRestore calls need to have their results checked SceneNode::VOnRestore(pScene); m_camera = pScene->GetCamera(); // TODO(munnellg) - release shaders if allocating before creating shader so we don't leak memory m_ShaderProgram.OnRestore(pScene); // clear out any existing buffers glDeleteVertexArrays(1, &m_vao); glDeleteBuffers(1, &m_vbo); glDeleteBuffers(1, &m_ebo); glCreateVertexArrays(1, &m_vao); m_numVerts = 20; VertexUnlitTextured* pVertices = GCC_NEW VertexUnlitTextured[m_numVerts]; GCC_ASSERT(pVertices && "Out of memory in OpenGLSkyNode46::VOnRestore"); if (!pVertices) return 1; // Loop through the grid squares and calc the values // of each index. Each grid square has two triangles: // // A - B // | / | // C - D VertexUnlitTextured skyVerts[4]; Color skyVertColor = g_White; float dim = 50.0f; skyVerts[0].Pos = glm::vec3( dim, dim, dim ); skyVerts[0].Uv = glm::vec2(1.0f, 0.0f); skyVerts[1].Pos = glm::vec3(-dim, dim, dim ); skyVerts[1].Uv = glm::vec2(0.0f, 0.0f); skyVerts[2].Pos = glm::vec3( dim,-dim, dim ); skyVerts[2].Uv = glm::vec2(1.0f, 1.0f); skyVerts[3].Pos = glm::vec3(-dim,-dim, dim ); skyVerts[3].Uv = glm::vec2(0.0f, 1.0f); glm::vec3 triangle[3]; triangle[0] = glm::vec3(0.f,0.f,0.f); triangle[1] = glm::vec3(5.f,0.f,0.f); triangle[2] = glm::vec3(5.f,5.f,0.f); glm::vec3 edge1 = triangle[1]-triangle[0]; glm::vec3 edge2 = triangle[2]-triangle[0]; glm::vec3 normal; normal = glm::cross(edge1, edge2); normal = glm::normalize(normal); glm::mat4 rotY = geometry::BuildRotationY(GCC_PI/2.0f); glm::mat4 rotX = geometry::BuildRotationX(-GCC_PI/2.0f); m_sides = 5; for (int side = 0; side < m_sides; side++) { for (int v = 0; v < 4; v++) { glm::vec4 temp; if (side < m_sides-1) { temp = rotY * glm::vec4(skyVerts[v].Pos, 0.0f); } else { skyVerts[0].Uv = glm::vec2(1.0f, 1.0f); skyVerts[1].Uv = glm::vec2(1.0f, 1.0f); skyVerts[2].Uv = glm::vec2(1.0f, 1.0f); skyVerts[3].Uv = glm::vec2(1.0f, 1.0f); } skyVerts[v].Pos = glm::vec3(temp.x, temp.y, temp.z); } memcpy(&pVertices[side*4], skyVerts, sizeof(skyVerts)); } glCreateBuffers(1, &m_vbo); glNamedBufferStorage(m_vbo, sizeof(VertexUnlitTextured) * m_numVerts, pVertices, 0); glVertexArrayVertexBuffer(m_vao, 0, m_vbo, 0, sizeof(VertexUnlitTextured)); glEnableVertexArrayAttrib(m_vao, 0); glVertexArrayAttribFormat(m_vao, 0, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(m_vao, 0, 0); glEnableVertexArrayAttrib(m_vao, 1); glVertexArrayAttribFormat(m_vao, 1, 3, GL_FLOAT, GL_FALSE, offsetof(VertexUnlitTextured, Normal)); glVertexArrayAttribBinding(m_vao, 1, 0); glEnableVertexArrayAttrib(m_vao, 2); glVertexArrayAttribFormat(m_vao, 2, 2, GL_FLOAT, GL_FALSE, offsetof(VertexUnlitTextured, Uv)); glVertexArrayAttribBinding(m_vao, 2, 0); delete[] pVertices; m_numIndices = m_sides * 2 * 3; GLuint *pIndices = GCC_NEW GLuint[m_numIndices]; GLuint *current = pIndices; for (int i=0; i=0 && index < name.length() - 1); if (index >= 0 && index < name.length() - 1) { name[index+1] = *letters[side]; } return name; }