void Framebuffer::buildColorAttachment() { Texture::Pointer target = buildTexture(_description.size, _description.target, _description.colorInternalformat, _description.colorFormat, _description.colorType); target->setWrap(_rc, TextureWrap::ClampToEdge, TextureWrap::ClampToEdge); addRenderTarget(target); }
void RenderState::bindTexture(uint32_t unit, const Texture::Pointer& texture, bool force) { #if !defined(ET_CONSOLE_APPLICATION) if (texture.valid()) bindTexture(unit, static_cast<uint32_t>(texture->apiHandle()), texture->target(), force); else bindTexture(unit, 0, TextureTarget::Texture_2D, force); #endif }
void Framebuffer::buildDepthAttachment() { Texture::Pointer target = buildTexture(_description.size, _description.target, _description.depthInternalformat, _description.depthFormat, _description.depthType); target->setWrap(_rc, TextureWrap::ClampToEdge, TextureWrap::ClampToEdge); setDepthTarget(target); }
void Renderer::renderTexture(const Texture::Pointer& texture, const vec2i& position, const vec2i& size, const vec4& tint) { #if !defined(ET_CONSOLE_APPLICATION) if (texture.invalid()) return; vec2i sz; sz.x = (size.x == -1) ? texture->width() : size.x; sz.y = (size.y == -1) ? texture->height() : size.y; renderTexture(texture, currentViewportCoordinatesToScene(position + vec2i(0, sz.y)), currentViewportSizeToScene(sz), tint); #endif }
void Renderer::renderFullscreenTexture(const Texture::Pointer& texture, const vec4& tint) { #if !defined(ET_CONSOLE_APPLICATION) auto prog = _fullscreenProgram[static_cast<int>(texture->target())]; _rc->renderState().bindTexture(_defaultTextureBindingUnit, texture); _rc->renderState().bindProgram(prog); prog->setUniform("color_texture_size", texture->sizeFloat()); prog->setUniform("tint", tint); fullscreenPass(); #endif }
void Material::textureDidLoad(Texture::Pointer t) { ET_ASSERT(t.valid()); uint32_t invalidParameter = static_cast<uint32_t>(-1); uint32_t param = invalidParameter; for (uint32_t i = 0; i < MaterialParameter_max; ++i) { if ((_defaultTextureParameters[i].value == t) && (_texturesToLoad.count(i) > 0)) { param = i; break; } } if (param == invalidParameter) { for (const auto& p : _customTextureParameters) { if ((p.second == t) && (_texturesToLoad.count(p.first) > 0)) { param = p.first; break; } } } ET_ASSERT(param != invalidParameter); _texturesToLoad.erase(param); if (_texturesToLoad.size() == 0) loaded.invokeInMainRunLoop(this); }
void Material::textureDidStartLoading(Texture::Pointer t) { ET_ASSERT(t.valid()); #if (ET_DEBUG) bool pendingTextureFound = false; for (uint32_t i = 0; i < MaterialParameter_max; ++i) { if ((_defaultTextureParameters[i].value == t) && (_texturesToLoad.count(i) > 0)) { pendingTextureFound = true; break; } } for (const auto& p : _customTextureParameters) { if ((p.second == t) && (_texturesToLoad.count(p.first) > 0)) { pendingTextureFound = true; break; } } ET_ASSERT(pendingTextureFound); #endif }
void Framebuffer::addSameRendertarget() { if (_description.colorIsRenderbuffer) { ET_ASSERT(!_colorRenderBuffers.empty()); uint32_t newRenderTarget = buildColorRenderbuffer(0); _colorRenderBuffers.push_back(newRenderTarget); setColorRenderbuffer(newRenderTarget, 1); } else { ET_ASSERT(!_renderTargets.empty()); const Texture::Pointer& basic = _renderTargets.front(); Texture::Pointer target = buildTexture(vec3i(basic->size(), basic->description()->layersCount), basic->target(), basic->internalFormat(), basic->format(), basic->dataType()); target->setName(name() + "_color_" + intToStr(_renderTargets.size() + 1)); target->setWrap(_rc, TextureWrap::ClampToEdge, TextureWrap::ClampToEdge); addRenderTarget(target); } }
void Framebuffer::setCurrentRenderTarget(const Texture::Pointer& texture) { ET_ASSERT(texture.valid()); attachTexture(texture, GL_COLOR_ATTACHMENT0); }
void Framebuffer::attachTexture(Texture::Pointer rt, uint32_t target) { if (rt.invalid() || (rt->size() != _description.size.xy())) return; ET_ASSERT(glIsTexture(static_cast<uint32_t>(rt->apiHandle()))); _rc->renderState().bindFramebuffer(static_cast<uint32_t>(apiHandle())); if ((rt->target() == TextureTarget::Texture_2D) || (rt->target() == TextureTarget::Texture_Rectangle)) { glFramebufferTexture2D(GL_FRAMEBUFFER, target, textureTargetValue(rt->target()), static_cast<uint32_t>(rt->apiHandle()), 0); checkOpenGLError("glFramebufferTexture2D(...) - %s", name().c_str()); } else if (rt->target() == TextureTarget::Texture_Cube) { for (GLenum i = 0; i < 6; ++i) { glFramebufferTexture2D(GL_FRAMEBUFFER, target, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, static_cast<uint32_t>(rt->apiHandle()), 0); checkOpenGLError("glFramebufferTexture2D(...) - %s", name().c_str()); } } #if (!ET_OPENGLES) else if (rt->target() == TextureTarget::Texture_2D_Array) { glFramebufferTexture(GL_FRAMEBUFFER, target, static_cast<GLuint>(rt->apiHandle()), 0); checkOpenGLError("glFramebufferTexture(...) - %s", name().c_str()); } #endif }
Texture::Pointer TextureFactory::loadTexture(const std::string& fileName, ObjectsCache& cache, bool async, TextureLoaderDelegate* delegate) { if (fileName.length() == 0) return Texture::Pointer(); CriticalSectionScope lock(_csTextureLoading); auto file = resolveTextureName(fileName); if (!fileExists(file)) return Texture::Pointer(); uint64_t cachedFileProperty = 0; Texture::Pointer texture = cache.findAnyObject(file, &cachedFileProperty); if (texture.invalid()) { TextureDescription::Pointer desc = async ? et::loadTextureDescription(file, false) : et::loadTexture(file); int maxTextureSize = static_cast<int>(RenderingCapabilities::instance().maxTextureSize()); if ((desc->size.x > maxTextureSize) || (desc->size.y > maxTextureSize)) { log::warning("Attempt to load texture with dimensions (%d x %d) larger than max allowed (%d)", desc->size.x, desc->size.y, maxTextureSize); } if (desc.valid()) { bool calledFromAnotherThread = !threading::inMainThread(); texture = Texture::Pointer::create(renderContext(), desc, desc->origin(), async || calledFromAnotherThread); cache.manage(texture, _private->loader); if (async) { _loadingThread->addRequest(desc->origin(), texture, delegate); } else if (calledFromAnotherThread) { ET_FAIL("ERROR: Unable to load texture synchronously from non-rendering thread."); } } } else { auto newProperty = cache.getFileProperty(file); if (cachedFileProperty != newProperty) reloadObject(texture, cache); if (async) { textureDidStartLoading.invokeInMainRunLoop(texture); if (delegate != nullptr) { Invocation1 i; i.setTarget(delegate, &TextureLoaderDelegate::textureDidStartLoading, texture); i.invokeInMainRunLoop(); } textureDidLoad.invokeInMainRunLoop(texture); if (delegate != nullptr) { Invocation1 i; i.setTarget(delegate, &TextureLoaderDelegate::textureDidLoad, texture); i.invokeInMainRunLoop(); } } } return texture; }
Texture::Pointer TextureFactory::loadTexturesToCubemap(const std::string& posx, const std::string& negx, const std::string& posy, const std::string& negy, const std::string& posz, const std::string& negz, ObjectsCache& cache) { TextureDescription::Pointer layers[6] = { et::loadTexture(application().resolveFileName(posx)), et::loadTexture(application().resolveFileName(negx)), et::loadTexture(application().resolveFileName(negy)), et::loadTexture(application().resolveFileName(posy)), et::loadTexture(application().resolveFileName(posz)), et::loadTexture(application().resolveFileName(negz)) }; int maxCubemapSize = static_cast<int>(RenderingCapabilities::instance().maxCubemapTextureSize()); for (size_t l = 0; l < 6; ++l) { if (layers[l].valid()) { if ((layers[l]->size.x > maxCubemapSize) || (layers[l]->size.y > maxCubemapSize)) { log::error("Cubemap %s size of (%d x %d) is larger than allowed %dx%d", layers[l]->origin().c_str(), layers[l]->size.x, layers[l]->size.y, maxCubemapSize, maxCubemapSize); return Texture::Pointer(); } } else { log::error("Unable to load cubemap face."); return Texture::Pointer(); } } std::string texId = layers[0]->origin() + ";"; for (size_t l = 1; l < 6; ++l) { texId += (l < 5) ? layers[l]->origin() + ";" : layers[l]->origin(); if ((layers[l-1]->size != layers[l]->size) || (layers[l-1]->format != layers[l]->format) || (layers[l-1]->internalformat != layers[l]->internalformat) || (layers[l-1]->type != layers[l]->type) || (layers[l-1]->mipMapCount != layers[l]->mipMapCount) || (layers[l-1]->compressed != layers[l]->compressed) || (layers[l-1]->data.size() != layers[l]->data.size())) { log::error("Failed to load cubemap textures. Textures `%s` and `%s` aren't identical", layers[l-1]->origin().c_str(), layers[l]->origin().c_str()); return Texture::Pointer(); } } size_t layerSize = layers[0]->dataSizeForAllMipLevels(); TextureDescription::Pointer desc = TextureDescription::Pointer::create(); desc->target = TextureTarget::Texture_Cube; desc->layersCount = 6; desc->bitsPerPixel = layers[0]->bitsPerPixel; desc->channels = layers[0]->channels; desc->compressed = layers[0]->compressed; desc->format = layers[0]->format; desc->internalformat = layers[0]->internalformat; desc->mipMapCount= layers[0]->mipMapCount; desc->size = layers[0]->size; desc->type = layers[0]->type; desc->data.resize(desc->layersCount * layerSize); for (size_t l = 0; l < desc->layersCount; ++l) etCopyMemory(desc->data.element_ptr(l * layerSize), layers[l]->data.element_ptr(0), layerSize); Texture::Pointer result = Texture::Pointer::create(renderContext(), desc, texId, false); for (size_t i = 0; i < 6; ++i) result->addOrigin(layers[i]->origin()); cache.manage(result, _private->loader); return result; }