Skip to content

Commit

Permalink
allow textures, geometries and materials to outlive GLRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
markaren committed Mar 4, 2024
1 parent af89db5 commit ba82e94
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 45 deletions.
2 changes: 2 additions & 0 deletions include/threepp/core/EventDispatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ namespace threepp {

void removeEventListener(const std::string& type, const EventListener* listener);

void removeAllEventListeners(const std::string& type);

void dispatchEvent(const std::string& type, void* target = nullptr);

virtual ~EventDispatcher() = default;
Expand Down
2 changes: 1 addition & 1 deletion include/threepp/renderers/GLRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ namespace threepp {

[[nodiscard]] const gl::GLInfo& info() const;

[[nodiscard]] std::optional<unsigned int> getGlTextureId(const Texture& texture) const;
[[nodiscard]] std::optional<unsigned int> getGlTextureId(Texture& texture) const;

~GLRenderer();

Expand Down
4 changes: 4 additions & 0 deletions src/threepp/core/EventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ void EventDispatcher::dispatchEvent(const std::string& type, void* target) {
}
}
}
void EventDispatcher::removeAllEventListeners(const std::string& type) {

listeners_.erase(type);
}
18 changes: 9 additions & 9 deletions src/threepp/renderers/GLRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ struct GLRenderer::Impl {
this->setScissor(0, 0, _size.width, _size.height);
}

[[nodiscard]] std::optional<unsigned int> getGlTextureId(const Texture& texture) const {
[[nodiscard]] std::optional<unsigned int> getGlTextureId(Texture& texture) const {

return textures.getGlTexture(texture);
}
Expand All @@ -170,12 +170,12 @@ struct GLRenderer::Impl {

releaseMaterialProgramReferences(material);

properties.materialProperties.remove(material->uuid());
properties.materialProperties.remove(material);
}

void releaseMaterialProgramReferences(Material* material) {

auto& programs = properties.materialProperties.get(material->uuid())->programs;
auto& programs = properties.materialProperties.get(material)->programs;

if (!programs.empty()) {

Expand Down Expand Up @@ -580,7 +580,7 @@ struct GLRenderer::Impl {
auto* scene = _scene->as<Scene>();
if (!scene) scene = _emptyScene.get();// scene could be a Mesh, Line, Points, ...

auto materialProperties = properties.materialProperties.get(material->uuid());
auto materialProperties = properties.materialProperties.get(material);

auto& lights = currentRenderState->getLights();
auto& shadowsArray = currentRenderState->getShadowsArray();
Expand Down Expand Up @@ -686,7 +686,7 @@ struct GLRenderer::Impl {

void updateCommonMaterialProperties(Material* material, gl::ProgramParameters& parameters) {

auto materialProperties = properties.materialProperties.get(material->uuid());
auto materialProperties = properties.materialProperties.get(material);

materialProperties->outputEncoding = parameters.outputEncoding;
materialProperties->instancing = parameters.instancing;
Expand Down Expand Up @@ -730,7 +730,7 @@ struct GLRenderer::Impl {
object->geometry()->hasAttribute("color") &&
object->geometry()->getAttribute<float>("color")->itemSize() == 4;

auto materialProperties = properties.materialProperties.get(material->uuid());
auto materialProperties = properties.materialProperties.get(material);
auto& lights = currentRenderState->getLights();

if (_clippingEnabled) {
Expand Down Expand Up @@ -1029,7 +1029,7 @@ struct GLRenderer::Impl {
_currentActiveCubeFace = activeCubeFace;
_currentActiveMipmapLevel = activeMipmapLevel;

if (renderTarget && !properties.renderTargetProperties.get(renderTarget->uuid)->glFramebuffer) {
if (renderTarget && !properties.renderTargetProperties.get(renderTarget)->glFramebuffer) {

textures.setupRenderTarget(renderTarget);
}
Expand All @@ -1040,7 +1040,7 @@ struct GLRenderer::Impl {

const auto& texture = renderTarget->texture;

framebuffer = *properties.renderTargetProperties.get(renderTarget->uuid)->glFramebuffer;
framebuffer = *properties.renderTargetProperties.get(renderTarget)->glFramebuffer;

_currentViewport.copy(renderTarget->viewport);
_currentScissor.copy(renderTarget->scissor);
Expand Down Expand Up @@ -1356,7 +1356,7 @@ GLRenderTarget* threepp::GLRenderer::getRenderTarget() {
return pimpl_->_currentRenderTarget;
}

std::optional<unsigned int> GLRenderer::getGlTextureId(const Texture& texture) const {
std::optional<unsigned int> GLRenderer::getGlTextureId(Texture& texture) const {

return pimpl_->getGlTextureId(texture);
}
Expand Down
2 changes: 1 addition & 1 deletion src/threepp/renderers/gl/GLClipping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct GLClipping::Impl {
auto clipIntersection = material->clipIntersection;
auto clipShadows = material->clipShadows;

auto materialProperties = properties.materialProperties.get(material->uuid());
auto materialProperties = properties.materialProperties.get(material);

if (!scope.localClippingEnabled || planes.empty() || scope.renderingShadows && !clipShadows) {

Expand Down
7 changes: 7 additions & 0 deletions src/threepp/renderers/gl/GLGeometries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ struct GLGeometries::Impl {

return wireframeAttributes_.at(geometry).get();
}

~Impl() {

for (auto& [geom, _] : geometries_) {
geom->removeAllEventListeners("dispose");
}
}
};


Expand Down
6 changes: 3 additions & 3 deletions src/threepp/renderers/gl/GLMaterials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct GLMaterials::Impl {
uniforms.at("specularMap").setValue(specularMaterial->specularMap.get());
}

auto envMap = properties.materialProperties.get(material->uuid())->envMap;
auto envMap = properties.materialProperties.get(material)->envMap;
if (envMap) {

auto cubeTexture = dynamic_cast<CubeTexture*>(envMap);
Expand All @@ -79,7 +79,7 @@ struct GLMaterials::Impl {
uniforms.at("refractionRatio").value<float>() = reflectiveMaterial->refractionRatio;
}

const auto maxMipMapLevel = properties.textureProperties.get(envMap->uuid)->maxMipLevel;
const auto maxMipMapLevel = properties.textureProperties.get(envMap)->maxMipLevel;
if (maxMipMapLevel) {
uniforms["maxMipLevel"].value<int>() = *maxMipMapLevel;
}
Expand Down Expand Up @@ -258,7 +258,7 @@ struct GLMaterials::Impl {
uniforms.at("displacementBias").value<float>() = material->displacementBias;
}

auto envMap = properties.materialProperties.get(material->uuid());
auto envMap = properties.materialProperties.get(material);
if (envMap) {

uniforms["envMapIntensity"].value<float>() = material->envMapIntensity;
Expand Down
25 changes: 18 additions & 7 deletions src/threepp/renderers/gl/GLProperties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#include "GLUniforms.hpp"
#include "threepp/core/Uniform.hpp"
#include "threepp/materials/Material.hpp"
#include "threepp/renderers/GLRenderer.hpp"
#include "threepp/textures/Texture.hpp"

#include <optional>
#include <unordered_map>
Expand Down Expand Up @@ -60,15 +63,15 @@ namespace threepp::gl {
unsigned int version{};
};

template<class T>
template<class E, class T>
struct GLTypeProperties {

T* get(const std::string& key) {
T* get(E* key) {

return &properties_[key];
}

void remove(const std::string& key) {
void remove(E* key) {

properties_.erase(key);
}
Expand All @@ -79,17 +82,25 @@ namespace threepp::gl {
}

private:
std::unordered_map<std::string, T> properties_;
friend struct GLProperties;
std::unordered_map<E*, T> properties_;
};

struct GLProperties {

GLTypeProperties<TextureProperties> textureProperties;
GLTypeProperties<MaterialProperties> materialProperties;
GLTypeProperties<RenderTargetProperties> renderTargetProperties;
GLTypeProperties<Texture, TextureProperties> textureProperties;
GLTypeProperties<Material, MaterialProperties> materialProperties;
GLTypeProperties<GLRenderTarget, RenderTargetProperties> renderTargetProperties;

void dispose() {

for (auto& [tex, _] : textureProperties.properties_) {
tex->removeAllEventListeners("dispose");
}
for (auto& [mat, _] : materialProperties.properties_) {
mat->removeAllEventListeners("dispose");
}

textureProperties.dispose();
materialProperties.dispose();
renderTargetProperties.dispose();
Expand Down
2 changes: 1 addition & 1 deletion src/threepp/renderers/gl/GLRenderLists.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ gl::RenderItem* gl::GLRenderList::getNextRenderItem(
unsigned int groupOrder, float z, std::optional<GeometryGroup> group) {

gl::RenderItem* renderItem = nullptr;
auto materialProperties = properties.materialProperties.get(material->uuid());
auto materialProperties = properties.materialProperties.get(material);

if (renderItemsIndex >= renderItems.size()) {
auto r = std::make_unique<RenderItem>(RenderItem{object->id,
Expand Down
42 changes: 21 additions & 21 deletions src/threepp/renderers/gl/GLTextures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ gl::GLTextures::GLTextures(gl::GLState& state, gl::GLProperties& properties, gl:
onTextureDispose_(this),
onRenderTargetDispose_(this) {}

void gl::GLTextures::generateMipmap(GLuint target, const Texture& texture, GLuint width, GLuint height) {
void gl::GLTextures::generateMipmap(GLuint target, Texture& texture, GLuint width, GLuint height) {

glGenerateMipmap(target);

auto textureProperties = properties->textureProperties.get(texture.uuid);
auto textureProperties = properties->textureProperties.get(&texture);

textureProperties->maxMipLevel = static_cast<int>(std::log2(std::max(width, height)));
}
Expand Down Expand Up @@ -220,13 +220,13 @@ void gl::GLTextures::deallocateTexture(Texture* texture) {

if (!properties) return;

auto textureProperties = properties->textureProperties.get(texture->uuid);
auto textureProperties = properties->textureProperties.get(texture);

if (!textureProperties->glInit) return;

glDeleteTextures(1, &textureProperties->glTexture.value());

properties->textureProperties.remove(texture->uuid);
properties->textureProperties.remove(texture);
}

void gl::GLTextures::deallocateRenderTarget(GLRenderTarget* renderTarget) {
Expand All @@ -235,8 +235,8 @@ void gl::GLTextures::deallocateRenderTarget(GLRenderTarget* renderTarget) {

const auto& texture = renderTarget->texture;

auto renderTargetProperties = properties->renderTargetProperties.get(renderTarget->uuid);
const auto& textureProperties = properties->textureProperties.get(texture->uuid);
auto renderTargetProperties = properties->renderTargetProperties.get(renderTarget);
const auto& textureProperties = properties->textureProperties.get(texture.get());

if (textureProperties->glTexture) {

Expand All @@ -253,8 +253,8 @@ void gl::GLTextures::deallocateRenderTarget(GLRenderTarget* renderTarget) {
glDeleteFramebuffers(1, &renderTargetProperties->glFramebuffer.value());
if (renderTargetProperties->glDepthbuffer) glDeleteRenderbuffers(1, &renderTargetProperties->glDepthbuffer.value());

properties->textureProperties.remove(texture->uuid);
properties->renderTargetProperties.remove(renderTarget->uuid);
properties->textureProperties.remove(texture.get());
properties->renderTargetProperties.remove(renderTarget);
}

void gl::GLTextures::resetTextureUnits() {
Expand All @@ -278,7 +278,7 @@ int gl::GLTextures::allocateTextureUnit() {

void gl::GLTextures::setTexture2D(Texture& texture, GLuint slot) {

auto textureProperties = properties->textureProperties.get(texture.uuid);
auto textureProperties = properties->textureProperties.get(&texture);

if (texture.version() > 0 && textureProperties->version != texture.version()) {

Expand All @@ -301,7 +301,7 @@ void gl::GLTextures::setTexture2D(Texture& texture, GLuint slot) {

void gl::GLTextures::setTexture2DArray(Texture& texture, GLuint slot) {

auto textureProperties = properties->textureProperties.get(texture.uuid);
auto textureProperties = properties->textureProperties.get(&texture);

if (texture.version() > 0 && textureProperties->version != texture.version()) {

Expand All @@ -315,7 +315,7 @@ void gl::GLTextures::setTexture2DArray(Texture& texture, GLuint slot) {

void gl::GLTextures::setTexture3D(Texture& texture, GLuint slot) {

auto textureProperties = properties->textureProperties.get(texture.uuid);
auto textureProperties = properties->textureProperties.get(&texture);

if (texture.version() > 0 && textureProperties->version != texture.version()) {

Expand All @@ -329,7 +329,7 @@ void gl::GLTextures::setTexture3D(Texture& texture, GLuint slot) {

void gl::GLTextures::setTextureCube(Texture& texture, GLuint slot) {

auto textureProperties = properties->textureProperties.get(texture.uuid);
auto textureProperties = properties->textureProperties.get(&texture);

if (texture.version() > 0 && textureProperties->version != texture.version()) {

Expand Down Expand Up @@ -397,7 +397,7 @@ void gl::GLTextures::setupFrameBufferTexture(
}

state->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textureTarget, *properties->textureProperties.get(texture.uuid)->glTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textureTarget, *properties->textureProperties.get(&texture)->glTexture, 0);
state->bindFramebuffer(GL_FRAMEBUFFER, 0);
}

Expand Down Expand Up @@ -447,7 +447,7 @@ void gl::GLTextures::setupDepthTexture(unsigned int framebuffer, GLRenderTarget*
}

// upload an empty depth texture with framebuffer size
if (!properties->textureProperties.get(renderTarget->depthTexture->uuid)->glTexture ||
if (!properties->textureProperties.get(renderTarget->depthTexture.get())->glTexture ||
renderTarget->depthTexture->image.front().width != renderTarget->width ||
renderTarget->depthTexture->image.front().height != renderTarget->height) {

Expand All @@ -458,7 +458,7 @@ void gl::GLTextures::setupDepthTexture(unsigned int framebuffer, GLRenderTarget*

setTexture2D(*renderTarget->depthTexture, 0);

const auto glDepthTexture = properties->textureProperties.get(renderTarget->depthTexture->uuid)->glTexture;
const auto glDepthTexture = properties->textureProperties.get(renderTarget->depthTexture.get())->glTexture;

if (renderTarget->depthTexture->format == Format::Depth) {

Expand All @@ -476,7 +476,7 @@ void gl::GLTextures::setupDepthTexture(unsigned int framebuffer, GLRenderTarget*

void gl::GLTextures::setupDepthRenderbuffer(GLRenderTarget* renderTarget) {

auto renderTargetProperties = properties->renderTargetProperties.get(renderTarget->uuid);
auto renderTargetProperties = properties->renderTargetProperties.get(renderTarget);

if (renderTarget->depthTexture) {

Expand All @@ -498,8 +498,8 @@ void gl::GLTextures::setupRenderTarget(GLRenderTarget* renderTarget) {

const auto& texture = renderTarget->texture;

auto renderTargetProperties = properties->renderTargetProperties.get(renderTarget->uuid);
auto textureProperties = properties->textureProperties.get(texture->uuid);
auto renderTargetProperties = properties->renderTargetProperties.get(renderTarget);
auto textureProperties = properties->textureProperties.get(texture.get());

renderTarget->addEventListener("dispose", &onRenderTargetDispose_);

Expand Down Expand Up @@ -555,17 +555,17 @@ void gl::GLTextures::updateRenderTargetMipmap(GLRenderTarget* renderTarget) {
if (textureNeedsGenerateMipmaps(*texture)) {

const auto target = GL_TEXTURE_2D;
const auto glTexture = properties->textureProperties.get(texture->uuid)->glTexture;
const auto glTexture = properties->textureProperties.get(texture.get())->glTexture;

state->bindTexture(target, *glTexture);
generateMipmap(target, *texture, renderTarget->width, renderTarget->height);
state->bindTexture(target, 0);
}
}

std::optional<unsigned int> gl::GLTextures::getGlTexture(const Texture& texture) const {
std::optional<unsigned int> gl::GLTextures::getGlTexture(Texture& texture) const {

const auto textureProperties = properties->textureProperties.get(texture.uuid);
const auto textureProperties = properties->textureProperties.get(&texture);

return textureProperties->glTexture;
}
Expand Down
4 changes: 2 additions & 2 deletions src/threepp/renderers/gl/GLTextures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace threepp::gl {

GLTextures(GLState& state, GLProperties& properties, GLInfo& info);

void generateMipmap(unsigned int target, const Texture& texture, unsigned int width, unsigned int height);
void generateMipmap(unsigned int target, Texture& texture, unsigned int width, unsigned int height);

void setTextureParameters(unsigned int textureType, Texture& texture);

Expand Down Expand Up @@ -67,7 +67,7 @@ namespace threepp::gl {

void updateRenderTargetMipmap(GLRenderTarget* renderTarget);

[[nodiscard]] std::optional<unsigned int> getGlTexture(const Texture& texture) const;
[[nodiscard]] std::optional<unsigned int> getGlTexture(Texture& texture) const;

private:
struct TextureEventListener: EventListener {
Expand Down

0 comments on commit ba82e94

Please sign in to comment.