| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- //========================================================================
- // Shaders.cpp - helper classes to call GameCode4_VS.hlsl and GameCode4_PS.hlsl
- //
- // 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 "../GameCode4/GameCode.h"
- #include "Shaders.h"
- #include "OpenGLRenderer.h"
- #include "Geometry.h"
- #include "Lights.h"
- // #include "Mesh.h"
- #include "Scene.h"
- #include "SceneNodes.h"
- #include "../ResourceCache/ResCache.h"
- #include <glm/gtx/string_cast.hpp>
- // #include <xnamath.h>
- // #pragma comment(lib, "effects11.lib") // [mrmike] Note you can remove this if you don't want the D3DX11CreateEffectFromMemory API.
- // #include "d3dx11effect.h"
- OpenGLShader::OpenGLShader() :
- m_shaderId(0)
- {
- }
- OpenGLShader::~OpenGLShader()
- {
- }
- OpenGLShaderProgram::OpenGLShaderProgram() :
- m_enableLights(true),
- m_programId(0),
- m_textureResource("")
- {
- }
- OpenGLShaderProgram::~OpenGLShaderProgram()
- {
- glDeleteProgram(m_programId);
- }
- int OpenGLShaderProgram::OnRestore(Scene *pScene)
- {
- GLuint vShaderId;
- GLuint fShaderId;
- glDeleteBuffers(1, &m_matrixUbo);
- glDeleteBuffers(1, &m_lightsUbo);
- glDeleteBuffers(1, &m_materialsUbo);
- glDeleteProgram(m_programId); // in case we have an existing program that we need to get rid of
- m_programId = glCreateProgram();
- {
- std::string vertFileName = "Effects/GameCode4_vert.glsl";
- Resource resource(vertFileName.c_str());
- std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
- GLint status;
- vShaderId = glCreateShader(GL_VERTEX_SHADER);
- const GLchar *source = pResourceHandle->Buffer();
- glShaderSource(vShaderId, 1, &source, NULL);
- glCompileShader(vShaderId);
- glGetShaderiv(vShaderId, GL_COMPILE_STATUS, &status);
- if (status == GL_FALSE)
- {
- GLint lsize = 0;
- glGetShaderiv(vShaderId, GL_INFO_LOG_LENGTH, &lsize);
- GLchar *log = new GLchar[lsize];
- glGetShaderInfoLog(vShaderId, lsize, nullptr, log);
- GCC_ERROR(source);
- GCC_ERROR(log);
- delete[] log;
- return 1;
- }
- glAttachShader(m_programId, vShaderId);
- }
- {
- std::string fragFileName = "Effects/GameCode4_frag.glsl";
- Resource resource(fragFileName.c_str());
- std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
- GLint status;
- fShaderId = glCreateShader(GL_FRAGMENT_SHADER);
- const GLchar *source = pResourceHandle->Buffer();
- glShaderSource(fShaderId, 1, &source, NULL);
- glCompileShader(fShaderId);
- glGetShaderiv(fShaderId, GL_COMPILE_STATUS, &status);
- if (status == GL_FALSE)
- {
- GLint lsize = 0;
- glGetShaderiv(fShaderId, GL_INFO_LOG_LENGTH, &lsize);
- GLchar *log = new GLchar[lsize];
- glGetShaderInfoLog(fShaderId, lsize, nullptr, log);
- GCC_ERROR(source);
- GCC_ERROR(log);
- delete[] log;
- return 1;
- }
- glAttachShader(m_programId, fShaderId);
- }
-
- glLinkProgram(m_programId);
- glDetachShader(m_programId, vShaderId);
- glDeleteShader(vShaderId);
- glDetachShader(m_programId, fShaderId);
- glDeleteShader(fShaderId);
-
- glGenBuffers(1, &m_matrixUbo);
- glBindBuffer(GL_UNIFORM_BUFFER, m_matrixUbo);
- glBufferStorage(GL_UNIFORM_BUFFER, sizeof(ConstantBuffer_Matrices), nullptr, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
- glGenBuffers(1, &m_lightsUbo);
- glBindBuffer(GL_UNIFORM_BUFFER, m_lightsUbo);
- glBufferStorage(GL_UNIFORM_BUFFER, sizeof(ConstantBuffer_Lighting), nullptr, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
- glGenBuffers(1, &m_materialsUbo);
- glBindBuffer(GL_UNIFORM_BUFFER, m_materialsUbo);
- glBufferStorage(GL_UNIFORM_BUFFER, sizeof(ConstantBuffer_Material), nullptr, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
- return 0;
- }
- int OpenGLShaderProgram::SetupRender(Scene *pScene, SceneNode *pNode)
- {
- glUseProgram(m_programId);
-
- // Get the projection & view matrix from the camera class
- glm::mat4 mWorldViewProjection = pScene->GetCamera()->GetWorldViewProjection(pScene);
- glm::mat4 mWorld = pScene->GetTopMatrix();
- // ----- Transform Matricies ------
- glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_matrixUbo);
- ConstantBuffer_Matrices* pVSMatrices = (ConstantBuffer_Matrices*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(ConstantBuffer_Matrices), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
- pVSMatrices->m_WorldViewProj = mWorldViewProjection;
- pVSMatrices->m_World = mWorld;
- glUnmapBuffer(GL_UNIFORM_BUFFER);
-
- // ----- Lighting ------
- glBindBufferBase(GL_UNIFORM_BUFFER, 1, m_lightsUbo);
- ConstantBuffer_Lighting* pLighting = (ConstantBuffer_Lighting*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(ConstantBuffer_Lighting), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
-
- if (m_enableLights)
- {
- pScene->GetLightManager()->CalcLighting(pLighting, pNode);
- }
- else
- {
- pLighting->m_nNumLights = 0;
- pLighting->m_vLightAmbient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
- }
- glUnmapBuffer(GL_UNIFORM_BUFFER);
- // ----- Material ------
- glBindBufferBase(GL_UNIFORM_BUFFER, 2, m_materialsUbo);
- ConstantBuffer_Material* pPSMaterial = ( ConstantBuffer_Material* )glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(ConstantBuffer_Material), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
- Color color = pNode->VGet()->GetMaterial().GetDiffuse();
- pPSMaterial->m_vDiffuseObjectColor = glm::vec4(color.r, color.g, color.b, color.a);
- color = (m_enableLights) ? pNode->VGet()->GetMaterial().GetAmbient() : Color(1.0f, 1.0f, 1.0f, 1.0f);
- pPSMaterial->m_vAmbientObjectColor = glm::vec4(color.r, color.g, color.b, color.a);
- // Note - the vertex shader doesn't care about the texture one way or another so we'll just set it to false
-
- if (m_textureResource.length() > 0)
- {
- pPSMaterial->m_bHasTexture = true;
- }
- else
- {
- pPSMaterial->m_bHasTexture = false;
- }
- glUnmapBuffer(GL_UNIFORM_BUFFER);
- // Set up the texture
- SetTexture(m_textureResource);
- return 0;
- }
- int OpenGLShaderProgram::SetTexture(const std::string& textureName)
- {
- m_textureResource = textureName;
- if (m_textureResource.length() > 0)
- {
- Resource resource(m_textureResource);
- std::shared_ptr<ResHandle> texture = g_pApp->m_ResCache->GetHandle(&resource);
- if (texture)
- {
- std::shared_ptr<OpenGLTextureResourceExtraData> extra = static_pointer_cast<OpenGLTextureResourceExtraData>(texture->GetExtra());
- glBindTexture(GL_TEXTURE_2D, extra->GetTextureId());
- }
- }
- }
|