Shaders.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. //========================================================================
  2. // Shaders.cpp - helper classes to call GameCode4_VS.hlsl and GameCode4_PS.hlsl
  3. //
  4. // Part of the GameCode4 Application
  5. //
  6. // GameCode4 is the sample application that encapsulates much of the source code
  7. // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
  8. // "Rez" Graham, published by Charles River Media.
  9. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574
  10. //
  11. // If this source code has found it's way to you, and you think it has helped you
  12. // in any way, do the authors a favor and buy a new copy of the book - there are
  13. // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
  14. // by clicking here:
  15. // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
  16. //
  17. // There's a companion web site at http://www.mcshaffry.com/GameCode/
  18. //
  19. // The source code is managed and maintained through Google Code:
  20. // http://code.google.com/p/gamecode4/
  21. //
  22. // (c) Copyright 2012 Michael L. McShaffry and David Graham
  23. //
  24. // This program is free software; you can redistribute it and/or
  25. // modify it under the terms of the GNU Lesser GPL v3
  26. // as published by the Free Software Foundation.
  27. //
  28. // This program is distributed in the hope that it will be useful,
  29. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  31. // http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
  32. //
  33. // You should have received a copy of the GNU Lesser GPL v3
  34. // along with this program; if not, write to the Free Software
  35. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  36. //
  37. //========================================================================
  38. #include "../Unix/GameCodeStd.h"
  39. #include "../GameCode4/GameCode.h"
  40. #include "Shaders.h"
  41. #include "OpenGLRenderer.h"
  42. #include "Geometry.h"
  43. #include "Lights.h"
  44. // #include "Mesh.h"
  45. #include "Scene.h"
  46. #include "SceneNodes.h"
  47. #include "../ResourceCache/ResCache.h"
  48. #include <glm/gtx/string_cast.hpp>
  49. // #include <xnamath.h>
  50. // #pragma comment(lib, "effects11.lib") // [mrmike] Note you can remove this if you don't want the D3DX11CreateEffectFromMemory API.
  51. // #include "d3dx11effect.h"
  52. OpenGLShader::OpenGLShader() :
  53. m_shaderId(0)
  54. {
  55. }
  56. OpenGLShader::~OpenGLShader()
  57. {
  58. }
  59. OpenGLShaderProgram::OpenGLShaderProgram() :
  60. m_enableLights(true),
  61. m_programId(0),
  62. m_textureResource("")
  63. {
  64. }
  65. OpenGLShaderProgram::~OpenGLShaderProgram()
  66. {
  67. glDeleteProgram(m_programId);
  68. }
  69. int OpenGLShaderProgram::OnRestore(Scene *pScene)
  70. {
  71. GLuint vShaderId;
  72. GLuint fShaderId;
  73. glDeleteBuffers(1, &m_matrixUbo);
  74. glDeleteBuffers(1, &m_lightsUbo);
  75. glDeleteBuffers(1, &m_materialsUbo);
  76. glDeleteProgram(m_programId); // in case we have an existing program that we need to get rid of
  77. m_programId = glCreateProgram();
  78. {
  79. std::string vertFileName = "Effects/GameCode4_vert.glsl";
  80. Resource resource(vertFileName.c_str());
  81. std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
  82. GLint status;
  83. vShaderId = glCreateShader(GL_VERTEX_SHADER);
  84. const GLchar *source = pResourceHandle->Buffer();
  85. glShaderSource(vShaderId, 1, &source, NULL);
  86. glCompileShader(vShaderId);
  87. glGetShaderiv(vShaderId, GL_COMPILE_STATUS, &status);
  88. if (status == GL_FALSE)
  89. {
  90. GLint lsize = 0;
  91. glGetShaderiv(vShaderId, GL_INFO_LOG_LENGTH, &lsize);
  92. GLchar *log = new GLchar[lsize];
  93. glGetShaderInfoLog(vShaderId, lsize, nullptr, log);
  94. GCC_ERROR(source);
  95. GCC_ERROR(log);
  96. delete[] log;
  97. return 1;
  98. }
  99. glAttachShader(m_programId, vShaderId);
  100. }
  101. {
  102. std::string fragFileName = "Effects/GameCode4_frag.glsl";
  103. Resource resource(fragFileName.c_str());
  104. std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
  105. GLint status;
  106. fShaderId = glCreateShader(GL_FRAGMENT_SHADER);
  107. const GLchar *source = pResourceHandle->Buffer();
  108. glShaderSource(fShaderId, 1, &source, NULL);
  109. glCompileShader(fShaderId);
  110. glGetShaderiv(fShaderId, GL_COMPILE_STATUS, &status);
  111. if (status == GL_FALSE)
  112. {
  113. GLint lsize = 0;
  114. glGetShaderiv(fShaderId, GL_INFO_LOG_LENGTH, &lsize);
  115. GLchar *log = new GLchar[lsize];
  116. glGetShaderInfoLog(fShaderId, lsize, nullptr, log);
  117. GCC_ERROR(source);
  118. GCC_ERROR(log);
  119. delete[] log;
  120. return 1;
  121. }
  122. glAttachShader(m_programId, fShaderId);
  123. }
  124. glLinkProgram(m_programId);
  125. glDetachShader(m_programId, vShaderId);
  126. glDeleteShader(vShaderId);
  127. glDetachShader(m_programId, fShaderId);
  128. glDeleteShader(fShaderId);
  129. glGenBuffers(1, &m_matrixUbo);
  130. glBindBuffer(GL_UNIFORM_BUFFER, m_matrixUbo);
  131. glBufferStorage(GL_UNIFORM_BUFFER, sizeof(ConstantBuffer_Matrices), nullptr, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
  132. glGenBuffers(1, &m_lightsUbo);
  133. glBindBuffer(GL_UNIFORM_BUFFER, m_lightsUbo);
  134. glBufferStorage(GL_UNIFORM_BUFFER, sizeof(ConstantBuffer_Lighting), nullptr, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
  135. glGenBuffers(1, &m_materialsUbo);
  136. glBindBuffer(GL_UNIFORM_BUFFER, m_materialsUbo);
  137. glBufferStorage(GL_UNIFORM_BUFFER, sizeof(ConstantBuffer_Material), nullptr, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
  138. return 0;
  139. }
  140. int OpenGLShaderProgram::SetupRender(Scene *pScene, SceneNode *pNode)
  141. {
  142. glUseProgram(m_programId);
  143. // Get the projection & view matrix from the camera class
  144. glm::mat4 mWorldViewProjection = pScene->GetCamera()->GetWorldViewProjection(pScene);
  145. glm::mat4 mWorld = pScene->GetTopMatrix();
  146. // ----- Transform Matricies ------
  147. glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_matrixUbo);
  148. ConstantBuffer_Matrices* pVSMatrices = (ConstantBuffer_Matrices*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(ConstantBuffer_Matrices), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  149. pVSMatrices->m_WorldViewProj = mWorldViewProjection;
  150. pVSMatrices->m_World = mWorld;
  151. glUnmapBuffer(GL_UNIFORM_BUFFER);
  152. // ----- Lighting ------
  153. glBindBufferBase(GL_UNIFORM_BUFFER, 1, m_lightsUbo);
  154. ConstantBuffer_Lighting* pLighting = (ConstantBuffer_Lighting*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(ConstantBuffer_Lighting), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  155. if (m_enableLights)
  156. {
  157. pScene->GetLightManager()->CalcLighting(pLighting, pNode);
  158. }
  159. else
  160. {
  161. pLighting->m_nNumLights = 0;
  162. pLighting->m_vLightAmbient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
  163. }
  164. glUnmapBuffer(GL_UNIFORM_BUFFER);
  165. // ----- Material ------
  166. glBindBufferBase(GL_UNIFORM_BUFFER, 2, m_materialsUbo);
  167. ConstantBuffer_Material* pPSMaterial = ( ConstantBuffer_Material* )glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(ConstantBuffer_Material), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  168. Color color = pNode->VGet()->GetMaterial().GetDiffuse();
  169. pPSMaterial->m_vDiffuseObjectColor = glm::vec4(color.r, color.g, color.b, color.a);
  170. color = (m_enableLights) ? pNode->VGet()->GetMaterial().GetAmbient() : Color(1.0f, 1.0f, 1.0f, 1.0f);
  171. pPSMaterial->m_vAmbientObjectColor = glm::vec4(color.r, color.g, color.b, color.a);
  172. // Note - the vertex shader doesn't care about the texture one way or another so we'll just set it to false
  173. if (m_textureResource.length() > 0)
  174. {
  175. pPSMaterial->m_bHasTexture = true;
  176. }
  177. else
  178. {
  179. pPSMaterial->m_bHasTexture = false;
  180. }
  181. glUnmapBuffer(GL_UNIFORM_BUFFER);
  182. // Set up the texture
  183. SetTexture(m_textureResource);
  184. return 0;
  185. }
  186. int OpenGLShaderProgram::SetTexture(const std::string& textureName)
  187. {
  188. m_textureResource = textureName;
  189. if (m_textureResource.length() > 0)
  190. {
  191. Resource resource(m_textureResource);
  192. std::shared_ptr<ResHandle> texture = g_pApp->m_ResCache->GetHandle(&resource);
  193. if (texture)
  194. {
  195. std::shared_ptr<OpenGLTextureResourceExtraData> extra = static_pointer_cast<OpenGLTextureResourceExtraData>(texture->GetExtra());
  196. glBindTexture(GL_TEXTURE_2D, extra->GetTextureId());
  197. }
  198. }
  199. }