| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- //========================================================================
- // 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<m_sides; i++)
- {
- // Triangle #1 ACB
- *(current) = GLuint(i*4);
- *(current + 1) = GLuint(i*4 + 2);
- *(current + 2) = GLuint(i*4 + 1);
- // Triangle #1 BCD
- *(current + 3) = GLuint(i*4 + 1);
- *(current + 4) = GLuint(i*4 + 2);
- *(current + 5) = GLuint(i*4 + 3);
- current += 6;
- }
- glCreateBuffers(1, &m_ebo);
- glNamedBufferStorage(m_ebo, sizeof(GLuint) * m_numIndices, pIndices, 0);
- glVertexArrayElementBuffer(m_vao, m_ebo);
- delete[] pIndices;
- return 0;
- }
- int OpenGLSkyNode46::VRender(Scene *pScene)
- {
- // TODO(munnellg) - implement
- m_ShaderProgram.SetupRender(pScene, this);
- // draw the skybox
- glBindVertexArray(m_vao);
- for (int side = 0; side < m_sides; side++)
- {
- // FUTURE WORK: A good optimization would be to transform the camera's
- // world look vector into local space, and do a dot product. If the
- // result is positive, we shouldn't draw the side since it has to be
- // behind the camera!
- // Sky boxes aren't culled by the normal mechanism
- /***
- // [mrmike] - This was slightly changed post press, look at the lines below this commented out code
- const char *suffix[] = { "_n.jpg", "_e.jpg", "_s.jpg", "_w.jpg", "_u.jpg" };
- name += suffix[side];
- ****/
- std::string name = GetTextureName(side);
- m_ShaderProgram.SetTexture(name.c_str());
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *)(6 * side * sizeof(GLuint)));
- }
- glBindVertexArray(0);
- return 0;
- }
- std::string SkyNode::GetTextureName(const int side)
- {
- std::string name = m_textureBaseName;
- char *letters[] = { "n", "e", "s", "w", "u" };
- unsigned int index = name.find_first_of("_");
- GCC_ASSERT(index >=0 && index < name.length() - 1);
- if (index >= 0 && index < name.length() - 1)
- {
- name[index+1] = *letters[side];
- }
- return name;
- }
|