kit::Texture::Texture(glm::uvec2 resolution, kit::Texture::InternalFormat format, uint8_t levels) : kit::Texture(Type::Texture2D) { m_internalFormat = format; m_resolution = glm::uvec3(resolution, 0); uint8_t mipLevels = levels > 0 ? levels : calculateMipLevels(); #ifndef KIT_SHITTY_INTEL glTextureStorage2D(m_glHandle, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); #else bind(); glTexStorage2D(m_type, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); #endif setEdgeSamplingMode(EdgeSamplingMode::Repeat); setMinFilteringMode(m_minFilteringMode); setMagFilteringMode(m_magFilteringMode); setAnisotropicLevel(1.0f); }
kit::Texture::Texture(const std::string & filename, kit::Texture::InternalFormat format, uint8_t levels, Type t) : kit::Texture(t) { std::cout << "Loading texture from file \"" << filename.c_str() << "\"" << std::endl; m_filename = filename; if(t == Type::Texture2D) { m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(1); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_THROW(stbi_failure_reason()); } // Set resolution m_resolution = glm::uvec3(x, y, 0); uint8_t mipLevels = levels > 0 ? levels : calculateMipLevels(); // Specify storage and upload data to GPU #ifndef KIT_SHITTY_INTEL glTextureStorage2D(m_glHandle, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); glTextureSubImage2D(m_glHandle, 0, 0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #else bind(); glTexStorage2D(m_type, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); glTexSubImage2D(m_type, 0, 0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #endif // Free loaded data stbi_image_free(bufferdata); // Set parameters setEdgeSamplingMode(EdgeSamplingMode::Repeat); setMinFilteringMode(m_minFilteringMode); setMagFilteringMode(m_magFilteringMode); setAnisotropicLevel(1.0f); } if(t == Type::Texture3D) { m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(0); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_THROW(stbi_failure_reason()); } if (y != x*x || y%y != 0) { KIT_THROW("Failed to load 3d texture from file, not perfectly cubical"); } // Set resolution m_resolution = glm::uvec3(x, x, x); // Specify storage and upload data to GPU #ifndef KIT_SHITTY_INTEL glTextureStorage3D(m_glHandle, 1, m_internalFormat, x, x, x); glTextureSubImage3D(m_glHandle, 0, 0, 0, 0, x, x, x, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #else returner->bind(); glTexStorage3D(returner->m_type, 1, m_internalFormat, x, x, x); glTexSubImage3D(returner->m_type, 0, 0, 0, 0, x, x, x, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #endif // Free loaded data stbi_image_free(bufferdata); setEdgeSamplingMode(EdgeSamplingMode::Repeat); setMinFilteringMode(m_minFilteringMode); setMagFilteringMode(m_magFilteringMode); setAnisotropicLevel(1.0f); } }
bool TextureD3D11::update() { if (dirty) { std::vector<Data> localData; Size2 localSize; { std::lock_guard<std::mutex> lock(dataMutex); localData = data; localSize = size; } std::shared_ptr<RendererD3D11> rendererD3D11 = std::static_pointer_cast<RendererD3D11>(sharedEngine->getRenderer()); if (localSize.width > 0 && localSize.height > 0) { if (!texture || static_cast<UINT>(localSize.width) != width || static_cast<UINT>(localSize.height) != height) { if (texture) texture->Release(); width = static_cast<UINT>(localSize.width); height = static_cast<UINT>(localSize.height); D3D11_TEXTURE2D_DESC textureDesc; memset(&textureDesc, 0, sizeof(textureDesc)); textureDesc.Width = width; textureDesc.Height = height; textureDesc.MipLevels = 0; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; textureDesc.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | (renderTarget ? D3D11_BIND_RENDER_TARGET : 0); textureDesc.MiscFlags = 0; HRESULT hr = rendererD3D11->getDevice()->CreateTexture2D(&textureDesc, nullptr, &texture); if (FAILED(hr)) { log("Failed to create Direct3D 11 texture"); return false; } D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; memset(&srvDesc, 0, sizeof(srvDesc)); srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = mipmaps ? calculateMipLevels(width, height) : 1; hr = rendererD3D11->getDevice()->CreateShaderResourceView(texture, &srvDesc, &resourceView); if (FAILED(hr)) { log("Failed to create Direct3D 11 shader resource view"); return false; } } if (!localData.empty()) { for (size_t level = 0; level < localData.size(); ++level) { UINT rowPitch = localData[level].width * 4; rendererD3D11->getContext()->UpdateSubresource(texture, static_cast<UINT>(level), nullptr, localData[level].data.data(), rowPitch, 0); } } } ready = (texture != nullptr); dirty = false; } return true; }