Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "IndirectRend.hpp"
- #include "MtlImporter.hpp"
- #include "InputManager.hpp"
- #include "Cubemap.hpp"
- #include "Shader.hpp"
- namespace game_core {
- void GenerateTexArray(GLuint &tex) {
- glActiveTexture(GL_TEXTURE7);
- glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
- glTexStorage3D(GL_TEXTURE_2D_ARRAY,
- 1, //No mipmaps as textures are 1x1
- GL_RGB8, //Internal format
- 1, 1, //width,height
- NUM_DEBUG_COLORS //Number of layers
- );
- for (unsigned int i(0); i < NUM_DEBUG_COLORS; i++)
- {
- //Choose a random color for the i-essim image
- GLubyte color[3] = { GLubyte(rand() % 255),GLubyte(rand() % 255),GLubyte(rand() % 255) };
- //Specify i-essim image
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0, //Mipmap number
- 0, 0, i, //xoffset, yoffset, zoffset
- 1, 1, 1, //width, height, depth
- GL_RGB, //format
- GL_UNSIGNED_BYTE, //type
- color); //pointer to data
- }
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
- std::unique_ptr<IndirectRend> IndirectRend::_instance(nullptr);
- void IndirectRend::Init() {
- _instance.reset(new IndirectRend());
- glGenVertexArrays(1, &_instance->BindInfoComplete.VAO);
- glGenBuffers(1, &_instance->BindInfoComplete.EBO);
- glGenBuffers(1, &_instance->_indirectBuffer);
- glGenTextures(1, &_instance->_colorArrayTex);
- GenerateTexArray(_instance->_colorArrayTex);
- }
- IndirectRend::IndirectRend() : _indirectBuffer(0), _vertexOffset(0) { }
- IndirectRend::~IndirectRend() = default;
- idxVal IndirectRend::GenerateDrawCommands(const Mesh &mesh)
- {
- int baseVertex = 0;
- for (const auto &m : mesh.subMeshes) {
- DrawElementsCommand command{};
- command.vertexCount = m.indices.size(); //Number of indices for this submesh
- command.instanceCount = 1; //One instance
- command.firstIndex = _instance->_commandHeadIndex; //The highest index consumed by the draw command
- command.baseVertex = _instance->_vertexOffset; //The first index of the parent mesh
- command.baseInstance = _instance->_cmdIndex; //Instance ID
- _instance->_drawCommands.push_back(command);
- _instance->_cmdIndex++;
- _instance->_commandHeadIndex += m.indices.size();
- }
- //For some reason, Intel hardware seriously does not like this particular buffer being re-filled without being re created first.
- //Failure to do so results in the draw command chucking invalid ops
- glDeleteBuffers(1, &_instance->_indirectBuffer);
- glCreateBuffers(1, &_instance->_indirectBuffer);
- glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _instance->_indirectBuffer);
- glBufferData(GL_DRAW_INDIRECT_BUFFER, _instance->_drawCommands.size() * sizeof(_drawCommands[0]), &_instance->_drawCommands[0], GL_DYNAMIC_DRAW);
- glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
- return _instance->_drawCommands.size();
- }
- void IndirectRend::AddMesh(std::shared_ptr<Mesh> manager) {
- for (auto mesh : manager->subMeshes)
- _instance->_indices.insert(_instance->_indices.end(), mesh.indices.begin(), mesh.indices.end());
- _instance->_verts.insert(_instance->_verts.end(), manager->vertices.begin(), manager->vertices.end());
- _instance->_uvs.insert(_instance->_uvs.end(), manager->uvs.begin(), manager->uvs.end());
- _instance->_normals.insert(_instance->_normals.end(), manager->normals.begin(), manager->normals.end());
- _instance->_tangents.insert(_instance->_tangents.end(), manager->tangents.begin(), manager->tangents.end());
- _instance->_binormals.insert(_instance->_binormals.end(), manager->binormals.begin(), manager->binormals.end());
- BindVertexInfo(_instance->BindInfoComplete, _instance->_verts,
- _instance->_uvs, _instance->_normals, _instance->_tangents, _instance->_binormals, "Indirect Renderer");
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _instance->BindInfoComplete.EBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, _instance->_indices.size() * sizeof(idxVal), &_instance->_indices[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- GenerateDrawCommands(*manager);
- _instance->_vertexOffset += manager->vertices.size();
- }
- void IndirectRend::Render() {
- //Content aquisition is happening at the head of this method solely for testing purposes, as is the unnecessary rebinding
- const auto shader = Shader::get_resource("sparky");
- glUseProgram(shader->shaderProgram);
- GLuint skybox = Cubemap::get_resource("Yokohama_HighRes", false)->texture;
- glBindVertexArray(_instance->BindInfoComplete.VAO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _instance->BindInfoComplete.EBO);
- glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _instance->_indirectBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, _instance->_indirectBuffer);
- glEnableVertexAttribArray(5);
- glVertexAttribIPointer(5, 1, GL_UNSIGNED_INT, sizeof(DrawElementsCommand), reinterpret_cast<void*>(offsetof(DrawElementsCommand, baseInstance)));
- glVertexAttribDivisor(5, 1);
- glm::mat4 proj = InputManager::projMatrix();
- glm::mat4 view = InputManager::viewMatrix;
- glm::mat4 model = glm::mat4(1); //Model matrix is going to be un a uniform buffer later
- glm::mat4 MV = view * model;
- glm::mat4 PV = proj * view;
- glm::mat4 MVP = proj * view * model;
- glUniformMatrix4fv(shader->GetUniform("M"), 1, GL_FALSE, &model[0][0]);
- glUniformMatrix4fv(shader->GetUniform("V"), 1, GL_FALSE, &view[0][0]);
- glUniformMatrix4fv(shader->GetUniform("P"), 1, GL_FALSE, &proj[0][0]);
- glUniformMatrix4fv(shader->GetUniform("PV"), 1, GL_FALSE, &PV[0][0]);
- glUniformMatrix4fv(shader->GetUniform("MV"), 1, GL_FALSE, &MV[0][0]);
- glUniformMatrix4fv(shader->GetUniform("MVP"), 1, GL_FALSE, &MVP[0][0]);
- glShadeModel(GL_FLAT);
- glEnable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glUniform1f(shader->GetUniform("u_UsingAlbedoMap"), 1);
- glUniform1i(shader->GetUniform("u_AlbedoMap"), 1);
- glUniform1i(shader->GetUniform("u_EnvironmentMap"), 4);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D_ARRAY, _instance->_colorArrayTex);
- glActiveTexture(GL_TEXTURE4);
- glBindTexture(GL_TEXTURE_CUBE_MAP, skybox);
- glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, _instance->_drawCommands.size(), 0);//Here be dragons
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement