#include "../Unix/GameCodeStd.h" #include "../GameCode4/GameCode.h" #include "../ResourceCache/ResCache.h" #include "OpenGLRenderer.h" #include "Lights.h" #include "Mesh.h" // #include "Raycast.h" #include "SceneNodes.h" std::shared_ptr CreateGlbMeshResourceLoader() { return std::shared_ptr(GCC_NEW GlbMeshResourceLoader()); } unsigned int GlbMeshResourceLoader::VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize) { // The raw data of the SDK Mesh file is needed by the CDXUTMesh class, so we're going to keep it around. return rawSize; } // // SdkMeshResourceLoader::VLoadResource - Chapter 16, page 561 // bool GlbMeshResourceLoader::VLoadResource(char *rawBuffer, unsigned int rawSize, std::shared_ptr handle) { std::shared_ptr extra = std::shared_ptr(GCC_NEW OpenGLGlbMeshResourceExtraData()); // load the mesh extra->m_pScene = aiImportFileFromMemory(rawBuffer, rawSize, 0, "glb"); if (!extra->m_pScene || extra->m_pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !extra->m_pScene->mRootNode) { GCC_ERROR(std::string("Failed to open scene file: ") + aiGetErrorString()); return false; } handle->SetExtra(std::shared_ptr(extra)); return true; } OpenGLShaderMeshNode::OpenGLShaderMeshNode(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, std::string meshFileName, RenderPass renderPass, const glm::mat4 t) : SceneNode(actorId, renderComponent, renderPass, t), m_vao(0), m_vbo(0), m_ebo(0), m_numIndices(0), m_numMeshes(0) { m_meshFileName = meshFileName; } int OpenGLShaderMeshNode::VOnRestore(Scene *pScene) { m_ShaderProgram.OnRestore(pScene); // Force the Mesh to reload Resource resource(m_meshFileName); std::shared_ptr pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource); std::shared_ptr extra = static_pointer_cast(pResourceHandle->GetExtra()); for (int i = 0; i < m_numMeshes; i++) { glDeleteVertexArrays(1, &m_vao[i]); glDeleteBuffers(1, &m_vbo[i]); glDeleteBuffers(1, &m_ebo[i]); } if (m_vao) { delete[] m_vao; } if (m_vbo) { delete[] m_vbo; } if (m_ebo) { delete[] m_ebo; } if (m_numIndices) { delete[] m_numIndices; } if (m_numVerts) { delete[] m_numVerts; } m_numMeshes = extra->m_pScene->mNumMeshes; m_vao = GCC_NEW GLuint[m_numMeshes]; m_vbo = GCC_NEW GLuint[m_numMeshes]; m_ebo = GCC_NEW GLuint[m_numMeshes]; m_numIndices = GCC_NEW size_t[m_numMeshes]; m_numVerts = GCC_NEW size_t[m_numMeshes]; for (int i = 0; i < extra->m_pScene->mNumMeshes; i++) { const aiMesh* p_AIMesh = extra->m_pScene->mMeshes[i]; m_numVerts[i] = p_AIMesh->mNumVertices; VertexUnlitTextured *pVerts = GCC_NEW VertexUnlitTextured[m_numVerts[i]]; GCC_ASSERT(pVerts && "Out of memory in OpenGLShaderMeshNode::VOnRestore"); if (!pVerts) return 1; for (int j = 0; j < m_numVerts[i]; j++) { pVerts[j].Pos = glm::vec3( p_AIMesh->mVertices[j].x, p_AIMesh->mVertices[j].y, p_AIMesh->mVertices[j].z ); pVerts[j].Normal = glm::vec3( p_AIMesh->mNormals[j].x, p_AIMesh->mNormals[j].y, p_AIMesh->mNormals[j].z ); pVerts[j].Uv = glm::vec2( p_AIMesh->mTextureCoords[0][j].x, p_AIMesh->mTextureCoords[0][j].y ); } m_numIndices[i] = p_AIMesh->mNumFaces * 3; GLuint *pIndices = GCC_NEW GLuint[m_numIndices[i]]; GCC_ASSERT(pIndices && "Out of memory in OpenGLShaderMeshNode::VOnRestore"); if (!pIndices) { delete[] pVerts; return 1; } GLuint *current = pIndices; for (int j = 0; j < p_AIMesh->mNumFaces; j++) { *(current + 0) = p_AIMesh->mFaces[j].mIndices[0]; *(current + 1) = p_AIMesh->mFaces[j].mIndices[1]; *(current + 2) = p_AIMesh->mFaces[j].mIndices[2]; current += 3; } glCreateVertexArrays(1, &m_vao[i]); glCreateBuffers(1, &m_vbo[i]); glNamedBufferStorage(m_vbo[i], sizeof(VertexUnlitTextured) * m_numVerts[i], pVerts, 0); glVertexArrayVertexBuffer(m_vao[i], 0, m_vbo[i], 0, sizeof(VertexUnlitTextured)); glEnableVertexArrayAttrib(m_vao[i], 0); glVertexArrayAttribFormat(m_vao[i], 0, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(m_vao[i], 0, 0); glEnableVertexArrayAttrib(m_vao[i], 1); glVertexArrayAttribFormat(m_vao[i], 1, 3, GL_FLOAT, GL_FALSE, offsetof(VertexUnlitTextured, Normal)); glVertexArrayAttribBinding(m_vao[i], 1, 0); glEnableVertexArrayAttrib(m_vao[i], 2); glVertexArrayAttribFormat(m_vao[i], 2, 2, GL_FLOAT, GL_FALSE, offsetof(VertexUnlitTextured, Uv)); glVertexArrayAttribBinding(m_vao[i], 2, 0); delete[] pVerts; glCreateBuffers(1, &m_ebo[i]); glNamedBufferStorage(m_ebo[i], sizeof(GLuint) * m_numIndices[i], pIndices, 0); glVertexArrayElementBuffer(m_vao[i], m_ebo[i]); delete[] pIndices; } // TODO (munnellg) - calcualte the bounding sphere here return 1; } int OpenGLShaderMeshNode::VRender(Scene *pScene) { // GridRenderComponent* grc = static_cast(m_RenderComponent); // m_ShaderProgram.SetTexture(grc->GetTextureResource()); m_ShaderProgram.SetupRender(pScene, this); for (int i = 0; i < m_numMeshes; i++) { glBindVertexArray(m_vao[i]); glDrawElements(GL_TRIANGLES, m_numIndices[i], GL_UNSIGNED_INT, 0); } glBindVertexArray(0); return 0; }