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 }
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 }
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; }