#include "Cubemap.h" #include #include "GL/glew.h" #include "stb_image.h" #include "Application.h" #include "Shader.h" #include "Assets.h" namespace nf { Cubemap::Cubemap() : m_constructed(false), m_id(0) { } void Cubemap::create(Asset* cubemapAsset) { if (m_constructed) Error("Cubemap already created!"); m_constructed = true; ACubemap& cm = *(ACubemap*)cubemapAsset; glGenTextures(1, &m_id); glActiveTexture(GL_TEXTURE12); glBindTexture(GL_TEXTURE_CUBE_MAP, m_id); struct CMFace { CMFace(unsigned char* d, unsigned int w, unsigned int h, unsigned int nc) : data(d), width(w), height(h), nChannels(nc) { } unsigned char* data; unsigned int width; unsigned int height; unsigned int nChannels; }; std::vector faces; int tempWidth, tempHeight, tempNChannels; unsigned char* tempData; stbi_set_flip_vertically_on_load(false); tempData = stbi_load_from_memory((unsigned char*)cm.leftData, cm.leftSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); tempData = stbi_load_from_memory((unsigned char*)cm.rightData, cm.rightSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); stbi_set_flip_vertically_on_load(true); tempData = stbi_load_from_memory((unsigned char*)cm.topData, cm.topSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); tempData = stbi_load_from_memory((unsigned char*)cm.bottomData, cm.bottomSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); stbi_set_flip_vertically_on_load(false); tempData = stbi_load_from_memory((unsigned char*)cm.backData, cm.backSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); tempData = stbi_load_from_memory((unsigned char*)cm.frontData, cm.frontSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); for (unsigned int i = 0; i < faces.size(); i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, faces[i].width, faces[i].height, 0, faces[i].nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, faces[i].data); stbi_image_free(faces[i].data); } glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glActiveTexture(GL_TEXTURE0); float vb[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; m_vao = new VertexArray; m_vao->addBuffer(vb, sizeof(vb)); m_vao->push(3); m_vao->finishBufferLayout(); if (!Application::getApp()->getCurrentState()->isRunning()) Application::getApp()->getCurrentState()->m_nfObjects.push_back(this); } bool Cubemap::isConstructed() { return m_constructed; } void Cubemap::render(Shader* shader) { m_vao->bind(); glActiveTexture(GL_TEXTURE12); shader->setUniform("cm", 12); glBindTexture(GL_TEXTURE_CUBE_MAP, m_id); glDepthFunc(GL_LEQUAL); glDrawArrays(GL_TRIANGLES, 0, 36); glDepthFunc(GL_LESS); } void Cubemap::destroy() { if (m_constructed) glDeleteTextures(1, &m_id); m_constructed = false; m_id = 0; delete m_vao; } Cubemap::~Cubemap() { destroy(); } }