mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-05 03:15:35 +00:00
Fix upside-down and vertical effect misalignment issues.
If anyone else can come up with a solution that doesn't involve up to three vertical flips, please implement.
This commit is contained in:
@ -56,6 +56,8 @@ add_library(MilkdropPreset OBJECT
|
||||
Filters.hpp
|
||||
FinalComposite.cpp
|
||||
FinalComposite.hpp
|
||||
FlipTexture.cpp
|
||||
FlipTexture.hpp
|
||||
IdlePreset.cpp
|
||||
IdlePreset.hpp
|
||||
MilkdropNoise.cpp
|
||||
|
||||
@ -210,7 +210,7 @@ void CustomShape::Draw()
|
||||
const float angle = cornerProgress * pi * 2.0f + static_cast<float>(*m_perFrameContext.tex_ang) + pi * 0.25f;
|
||||
|
||||
vertexData[i].u = 0.5f + 0.5f * cosf(angle) / static_cast<float>(*m_perFrameContext.tex_zoom) * textureAspectY;
|
||||
vertexData[i].v = 0.5f - 0.5f * sinf(angle) / static_cast<float>(*m_perFrameContext.tex_zoom);
|
||||
vertexData[i].v = 1.0f - (0.5f - 0.5f * sinf(angle) / static_cast<float>(*m_perFrameContext.tex_zoom)); // Vertical flip required!
|
||||
}
|
||||
|
||||
vertexData[sides + 1] = vertexData[1];
|
||||
|
||||
@ -183,7 +183,7 @@ void CustomWaveform::Draw(const PerFrameContext& presetPerFrameContext)
|
||||
}
|
||||
|
||||
m_presetState.untexturedShader.Bind();
|
||||
m_presetState.untexturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped);
|
||||
m_presetState.untexturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection);
|
||||
|
||||
auto iterations = (m_drawThick && !m_useDots) ? 4 : 1;
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ void Filters::Draw()
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
m_presetState.untexturedShader.Bind();
|
||||
m_presetState.untexturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped);
|
||||
m_presetState.untexturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection);
|
||||
|
||||
glBindVertexArray(m_vaoID);
|
||||
glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0);
|
||||
@ -88,6 +88,7 @@ void Filters::Invert()
|
||||
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void Filters::UpdateMesh()
|
||||
{
|
||||
if (m_viewportWidth == m_presetState.renderContext.viewportSizeX &&
|
||||
|
||||
@ -131,6 +131,11 @@ void FinalComposite::Draw(const PresetState& presetState, const PerFrameContext&
|
||||
Shader::Unbind();
|
||||
}
|
||||
|
||||
auto FinalComposite::HasCompositeShader() const -> bool
|
||||
{
|
||||
return m_compositeShader != nullptr;
|
||||
}
|
||||
|
||||
void FinalComposite::InitializeMesh(const PresetState& presetState)
|
||||
{
|
||||
if (m_viewportWidth == presetState.renderContext.viewportSizeX &&
|
||||
|
||||
@ -39,6 +39,12 @@ public:
|
||||
void Draw(const PresetState& presetState,
|
||||
const PerFrameContext& perFrameContext);
|
||||
|
||||
/**
|
||||
* @brief Returns if the final composite is using a shader or classic filters.
|
||||
* @return true if the final composite is done via a shader, false if not.
|
||||
*/
|
||||
auto HasCompositeShader() const -> bool;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Composite mesh vertex with all required attributes.
|
||||
|
||||
148
src/libprojectM/MilkdropPreset/FlipTexture.cpp
Normal file
148
src/libprojectM/MilkdropPreset/FlipTexture.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "FlipTexture.hpp"
|
||||
|
||||
FlipTexture::FlipTexture(const PresetState& presetState)
|
||||
: RenderItem()
|
||||
, m_presetState(presetState)
|
||||
{
|
||||
RenderItem::Init();
|
||||
|
||||
m_framebuffer.CreateColorAttachment(0, 0);
|
||||
}
|
||||
|
||||
void FlipTexture::InitVertexAttrib()
|
||||
{
|
||||
glEnableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedPoint), reinterpret_cast<void*>(offsetof(TexturedPoint, x))); // Position
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedPoint), reinterpret_cast<void*>(offsetof(TexturedPoint, u))); // Texture coordinate
|
||||
|
||||
std::array<RenderItem::TexturedPoint, 4> points;
|
||||
|
||||
points[0].x = -1.0;
|
||||
points[0].y = 1.0;
|
||||
points[1].x = 1.0;
|
||||
points[1].y = 1.0;
|
||||
points[2].x = -1.0;
|
||||
points[2].y = -1.0;
|
||||
points[3].x = 1.0;
|
||||
points[3].y = -1.0;
|
||||
|
||||
points[0].u = 0.0;
|
||||
points[0].v = 1.0;
|
||||
points[1].u = 1.0;
|
||||
points[1].v = 1.0;
|
||||
points[2].u = 0.0;
|
||||
points[2].v = 0.0;
|
||||
points[3].u = 1.0;
|
||||
points[3].v = 0.0;
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points.data(), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
void FlipTexture::Draw(const std::shared_ptr<Texture>& originalTexture, const std::shared_ptr<Texture>& targetTexture)
|
||||
{
|
||||
if (originalTexture == nullptr || originalTexture == targetTexture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTextureSize();
|
||||
|
||||
if (m_viewportWidth == 0 || m_viewportHeight == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> internalTexture;
|
||||
|
||||
m_framebuffer.Bind(0);
|
||||
|
||||
// Draw from unflipped texture
|
||||
originalTexture->Bind(0);
|
||||
|
||||
if (targetTexture)
|
||||
{
|
||||
internalTexture = m_framebuffer.GetColorAttachmentTexture(0, 0);
|
||||
m_framebuffer.GetAttachment(0, TextureAttachment::AttachmentType::Color, 0)->Texture(targetTexture);
|
||||
}
|
||||
|
||||
Flip();
|
||||
|
||||
// Rebind our internal texture.
|
||||
if (targetTexture)
|
||||
{
|
||||
m_framebuffer.GetAttachment(0, TextureAttachment::AttachmentType::Color, 0)->Texture(internalTexture);
|
||||
}
|
||||
|
||||
Framebuffer::Unbind();
|
||||
}
|
||||
|
||||
void FlipTexture::Draw(const std::shared_ptr<Texture>& originalTexture, Framebuffer& framebuffer, int framebufferIndex)
|
||||
{
|
||||
if (originalTexture == nullptr || framebuffer.GetColorAttachmentTexture(framebufferIndex, 0) == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTextureSize();
|
||||
|
||||
if (m_viewportWidth == 0 || m_viewportHeight == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_framebuffer.Bind(0);
|
||||
|
||||
// Draw from unflipped texture
|
||||
originalTexture->Bind(0);
|
||||
|
||||
Flip();
|
||||
|
||||
// Swap texture attachments
|
||||
auto tempAttachment = framebuffer.GetAttachment(framebufferIndex, TextureAttachment::AttachmentType::Color, 0);
|
||||
framebuffer.RemoveColorAttachment(framebufferIndex, 0);
|
||||
framebuffer.SetAttachment(framebufferIndex, 0, m_framebuffer.GetAttachment(0, TextureAttachment::AttachmentType::Color, 0));
|
||||
m_framebuffer.RemoveColorAttachment(0, 0);
|
||||
m_framebuffer.SetAttachment(0, 0, tempAttachment);
|
||||
|
||||
Framebuffer::Unbind();
|
||||
}
|
||||
|
||||
auto FlipTexture::FlippedTexture() -> std::shared_ptr<Texture>
|
||||
{
|
||||
return m_framebuffer.GetColorAttachmentTexture(0, 0);
|
||||
}
|
||||
|
||||
void FlipTexture::UpdateTextureSize()
|
||||
{
|
||||
if (m_viewportWidth == m_presetState.renderContext.viewportSizeX &&
|
||||
m_viewportHeight == m_presetState.renderContext.viewportSizeY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_viewportWidth = m_presetState.renderContext.viewportSizeX;
|
||||
m_viewportHeight = m_presetState.renderContext.viewportSizeY;
|
||||
|
||||
m_framebuffer.SetSize(m_viewportWidth, m_viewportHeight);
|
||||
}
|
||||
|
||||
void FlipTexture::Flip() const
|
||||
{
|
||||
m_presetState.texturedShader.Bind();
|
||||
m_presetState.texturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection);
|
||||
m_presetState.texturedShader.SetUniformInt("texture_sampler", 0);
|
||||
|
||||
m_sampler.Bind(0);
|
||||
|
||||
glBindVertexArray(m_vaoID);
|
||||
glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); // Color
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
Sampler::Unbind(0);
|
||||
Shader::Unbind();
|
||||
}
|
||||
67
src/libprojectM/MilkdropPreset/FlipTexture.hpp
Normal file
67
src/libprojectM/MilkdropPreset/FlipTexture.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "PresetState.hpp"
|
||||
|
||||
#include <Renderer/Framebuffer.hpp>
|
||||
#include <Renderer/RenderItem.hpp>
|
||||
|
||||
/**
|
||||
* @class FlipTexture
|
||||
* @brief Flips the given input texture upside-down.
|
||||
*
|
||||
* Milkdrop uses HLSL, so the input and output UV coordinates in the draw call are upside-down because
|
||||
* DirectX has the origin at the top-left while OpenGL/Vulkan use the bottom-left.
|
||||
*
|
||||
* Some presets need the input, the calculated UVs and the output to be properly aligned, so at some
|
||||
* point, input textures must be flipped for the next rendering step. This class uses a simple draw
|
||||
* call with a pass-through shader to draw the same image 1:1, but vertically flipped.
|
||||
*/
|
||||
class FlipTexture : public RenderItem
|
||||
{
|
||||
public:
|
||||
FlipTexture() = delete;
|
||||
explicit FlipTexture(const PresetState& presetState);
|
||||
|
||||
void InitVertexAttrib();
|
||||
|
||||
/**
|
||||
* @brief Flips the original texture either into the object's internal framebuffer or a given target texture.
|
||||
* The original and target textures must not be the same.
|
||||
* @param originalTexture The texture to be flipped.
|
||||
* @param targetTexture Optional target texture to draw onto.
|
||||
*/
|
||||
void Draw(const std::shared_ptr<Texture>& originalTexture, const std::shared_ptr<Texture>& targetTexture = {});
|
||||
|
||||
/**
|
||||
* @brief Flips the texture bound the given framebuffer's first color attachment.
|
||||
* This is done by drawing into a second framebuffer, then swapping the textures, so the original texture
|
||||
* can be the current color attachment of targetFramebuffer.
|
||||
* @param originalTexture The texture to be flipped.
|
||||
* @param targetFramebuffer Optional target texture to draw onto.
|
||||
* @param framebufferIndex The index of the framebuffer to use.
|
||||
*/
|
||||
void Draw(const std::shared_ptr<Texture>& originalTexture, Framebuffer& framebuffer, int framebufferIndex);
|
||||
|
||||
/**
|
||||
* @brief Returns the flipped texture.
|
||||
*
|
||||
* @return The flipped texture.
|
||||
*/
|
||||
auto FlippedTexture() -> std::shared_ptr<Texture>;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Updates the mesh
|
||||
*/
|
||||
void UpdateTextureSize();
|
||||
|
||||
void Flip() const;
|
||||
|
||||
const PresetState& m_presetState; //!< The global preset state.
|
||||
|
||||
Framebuffer m_framebuffer{1}; //!< Framebuffer for drawing the flipped texture
|
||||
Sampler m_sampler{GL_CLAMP_TO_EDGE, GL_NEAREST}; //!< Texture sampler settings
|
||||
|
||||
int m_viewportWidth{}; //!< Last known viewport width
|
||||
int m_viewportHeight{}; //!< Last known viewport height
|
||||
};
|
||||
@ -99,9 +99,12 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio
|
||||
m_motionVectors.Draw(m_perFrameContext, m_motionVectorUVMap->Texture());
|
||||
}
|
||||
|
||||
// We now draw to the first framebuffer, but read from the second one for warping and textured shapes.
|
||||
m_framebuffer.BindRead(m_previousFrameBuffer);
|
||||
m_framebuffer.BindDraw(m_currentFrameBuffer);
|
||||
// y-flip the previous frame and assign the flipped texture as "main"
|
||||
m_flipTexture.Draw(m_framebuffer.GetColorAttachmentTexture(m_previousFrameBuffer, 0));
|
||||
m_state.mainTexture = m_flipTexture.FlippedTexture();
|
||||
|
||||
// We now draw to the current framebuffer.
|
||||
m_framebuffer.Bind(m_currentFrameBuffer);
|
||||
|
||||
// Add motion vector u/v texture for the warp mesh draw and clean both buffers.
|
||||
m_framebuffer.SetAttachment(m_currentFrameBuffer, 1, m_motionVectorUVMap);
|
||||
@ -135,15 +138,24 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio
|
||||
|
||||
// Todo: Song title anim would go here
|
||||
|
||||
// y-flip the image for final compositing again
|
||||
m_flipTexture.Draw(m_framebuffer.GetColorAttachmentTexture(m_currentFrameBuffer, 0));
|
||||
m_state.mainTexture = m_flipTexture.FlippedTexture();
|
||||
|
||||
// We no longer need the previous frame image, use it to render the final composite.
|
||||
m_framebuffer.BindRead(m_currentFrameBuffer);
|
||||
m_framebuffer.BindDraw(m_previousFrameBuffer);
|
||||
m_state.mainTexture = m_framebuffer.GetColorAttachmentTexture(m_currentFrameBuffer, 0);
|
||||
|
||||
m_finalComposite.Draw(m_state, m_perFrameContext);
|
||||
|
||||
// ToDo: Draw user sprites (can have evaluated code)
|
||||
|
||||
if (!m_finalComposite.HasCompositeShader())
|
||||
{
|
||||
// Flip texture again in "previous" framebuffer as old-school effects are still upside down.
|
||||
m_flipTexture.Draw(m_framebuffer.GetColorAttachmentTexture(m_previousFrameBuffer, 0), m_framebuffer, m_previousFrameBuffer);
|
||||
}
|
||||
|
||||
// TEST: Copy result to default framebuffer
|
||||
m_framebuffer.BindRead(m_previousFrameBuffer);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "DarkenCenter.hpp"
|
||||
#include "Filters.hpp"
|
||||
#include "FinalComposite.hpp"
|
||||
#include "FlipTexture.hpp"
|
||||
#include "MotionVectors.hpp"
|
||||
#include "PerFrameContext.hpp"
|
||||
#include "PerPixelContext.hpp"
|
||||
@ -116,6 +117,7 @@ private:
|
||||
std::array<std::unique_ptr<CustomShape>, CustomShapeCount> m_customShapes; //!< Custom shapes in this preset.
|
||||
DarkenCenter m_darkenCenter; //!< Center darkening effect.
|
||||
Border m_border; //!< Inner/outer borders.
|
||||
FlipTexture m_flipTexture{ m_state }; //!< Texture flip filter
|
||||
|
||||
FinalComposite m_finalComposite; //!< Final composite shader or filters.
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ void MilkdropShader::LoadVariables(const PresetState& presetState, const PerFram
|
||||
|
||||
m_shader.Bind();
|
||||
|
||||
m_shader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped);
|
||||
m_shader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection);
|
||||
|
||||
m_shader.SetUniformFloat4("rand_frame", {floatRand(),
|
||||
floatRand(),
|
||||
|
||||
@ -306,7 +306,7 @@ void PerPixelMesh::WarpedBlit(const PresetState& presetState,
|
||||
if (!m_warpShader)
|
||||
{
|
||||
m_perPixelMeshShader.Bind();
|
||||
m_perPixelMeshShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped);
|
||||
m_perPixelMeshShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection);
|
||||
m_perPixelMeshShader.SetUniformInt("texture_sampler", 0);
|
||||
m_perPixelMeshShader.SetUniformFloat4("aspect", {presetState.renderContext.aspectX,
|
||||
presetState.renderContext.aspectY,
|
||||
|
||||
@ -6,17 +6,17 @@
|
||||
|
||||
#include <random>
|
||||
|
||||
const glm::mat4 PresetState::orthogonalProjection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -40.0f, 40.0f);
|
||||
const glm::mat4 PresetState::orthogonalProjectionFlipped = glm::ortho(-1.0f, 1.0f, 1.0f, -1.0f, -40.0f, 40.0f);
|
||||
const glm::mat4 PresetState::orthogonalProjection = glm::ortho(-1.0f, 1.0f, 1.0f, -1.0f, -40.0f, 40.0f);
|
||||
const glm::mat4 PresetState::orthogonalProjectionFlipped = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -40.0f, 40.0f);
|
||||
|
||||
PresetState::PresetState()
|
||||
: globalMemory(projectm_eval_memory_buffer_create())
|
||||
{
|
||||
auto staticShaders = libprojectM::MilkdropPreset::MilkdropStaticShaders::Get();
|
||||
untexturedShader.CompileProgram(staticShaders->GetUntexturedDrawVertexShader(),
|
||||
staticShaders->GetUntexturedDrawFragmentShader());
|
||||
staticShaders->GetUntexturedDrawFragmentShader());
|
||||
texturedShader.CompileProgram(staticShaders->GetTexturedDrawVertexShader(),
|
||||
staticShaders->GetTexturedDrawFragmentShader());
|
||||
staticShaders->GetTexturedDrawFragmentShader());
|
||||
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 randomGenerator(randomDevice());
|
||||
|
||||
@ -23,7 +23,8 @@ void main() {
|
||||
// Milkdrop's original code did a simple bilinear interpolation, but here it was already
|
||||
// done by the fragment shader during the warp mesh drawing. We just need to look up the
|
||||
// motion vector coordinate.
|
||||
vec2 oldUV = texture(warp_coordinates, pos.xy).xy;
|
||||
// We simply invert the y coordinate because it's easier than flipping the u/v texture.
|
||||
vec2 oldUV = texture(warp_coordinates, vec2(pos.x, 1.0 - pos.y)).xy;
|
||||
|
||||
// Enforce minimum trail length
|
||||
vec2 dist = oldUV - pos;
|
||||
|
||||
@ -40,11 +40,11 @@ void main() {
|
||||
|
||||
// Initial texture coordinates, with built-in zoom factor
|
||||
float u = pos.x * aspectX * 0.5 * zoom2Inverse + 0.5;
|
||||
float v = -pos.y * aspectY * 0.5 * zoom2Inverse + 0.5;
|
||||
float v = pos.y * aspectY * 0.5 * zoom2Inverse + 0.5;
|
||||
|
||||
// original UV coordinates
|
||||
vec2 uv_original = vec2(pos.x * 0.5 + 0.5 + texelOffset.x,
|
||||
-pos.y * 0.5 + 0.5 + texelOffset.y);
|
||||
pos.y * 0.5 + 0.5 + texelOffset.y);
|
||||
|
||||
// Stretch on X, Y
|
||||
u = (u - center.x) / stretch.x + center.x;
|
||||
|
||||
@ -68,7 +68,7 @@ void VideoEcho::Draw()
|
||||
}
|
||||
|
||||
m_presetState.texturedShader.Bind();
|
||||
m_presetState.texturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjectionFlipped);
|
||||
m_presetState.texturedShader.SetUniformMat4x4("vertex_transformation", PresetState::orthogonalProjection);
|
||||
m_presetState.texturedShader.SetUniformInt("texture_sampler", 0);
|
||||
|
||||
auto mainTexture = m_presetState.mainTexture.lock();
|
||||
|
||||
@ -102,6 +102,39 @@ bool Framebuffer::SetSize(int width, int height)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto Framebuffer::GetAttachment(int framebufferIndex, TextureAttachment::AttachmentType type, int attachmentIndex) const -> std::shared_ptr<TextureAttachment>
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto& framebufferAttachments = m_attachments.at(framebufferIndex);
|
||||
GLenum textureType;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TextureAttachment::AttachmentType::Color:
|
||||
textureType = GL_COLOR_ATTACHMENT0 + attachmentIndex;
|
||||
break;
|
||||
case TextureAttachment::AttachmentType::Depth:
|
||||
textureType = GL_DEPTH_ATTACHMENT;
|
||||
break;
|
||||
case TextureAttachment::AttachmentType::Stencil:
|
||||
textureType = GL_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
case TextureAttachment::AttachmentType::DepthStencil:
|
||||
textureType = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (framebufferAttachments.find(textureType) == framebufferAttachments.end()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return framebufferAttachments.at(textureType);
|
||||
}
|
||||
|
||||
void Framebuffer::SetAttachment(int framebufferIndex, int attachmentIndex, const std::shared_ptr<TextureAttachment>& attachment)
|
||||
{
|
||||
if (!attachment)
|
||||
|
||||
@ -93,6 +93,16 @@ public:
|
||||
*/
|
||||
bool SetSize(int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Returns a texture attachment object.
|
||||
* @param framebufferIndex The framebuffer index.
|
||||
* @param type The attachment type to retrieve.
|
||||
* @param attachmentIndex The index of the color attachment, at least indices 0-7 are guaranteed
|
||||
* to be available. Ignored for non-color attachments.
|
||||
* @return The requested attachment or nullptr if there is no attachment in the requested slot.
|
||||
*/
|
||||
auto GetAttachment(int framebufferIndex, TextureAttachment::AttachmentType type, int attachmentIndex = 0) const -> std::shared_ptr<TextureAttachment>;
|
||||
|
||||
/**
|
||||
* @brief Sets a texture attachment slot to the given object.
|
||||
* Sets the read/write FBOs to the previously used ones in this instance. If a different
|
||||
|
||||
@ -36,6 +36,11 @@ auto TextureAttachment::Texture() const -> std::shared_ptr<class Texture>
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
void TextureAttachment::Texture(const std::shared_ptr<struct Texture>& texture)
|
||||
{
|
||||
m_texture = texture;
|
||||
}
|
||||
|
||||
void TextureAttachment::SetSize(int width, int height)
|
||||
{
|
||||
if (width > 0 && height > 0)
|
||||
@ -54,6 +59,12 @@ void TextureAttachment::ReplaceTexture(int width, int height)
|
||||
GLint textureFormat;
|
||||
GLenum pixelFormat;
|
||||
|
||||
// Don't replace if size hasn't changed
|
||||
if (m_texture->Width() == width && m_texture->Height() == height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch(m_attachmentType)
|
||||
{
|
||||
case AttachmentType::Color:
|
||||
|
||||
@ -67,6 +67,13 @@ public:
|
||||
*/
|
||||
auto Texture() const -> std::shared_ptr<class Texture>;
|
||||
|
||||
/**
|
||||
* @brief Replaces the current internal texture with the given one.
|
||||
* Texture size is not changed.
|
||||
* @param texture
|
||||
*/
|
||||
void Texture(const std::shared_ptr<class Texture>& texture);
|
||||
|
||||
/**
|
||||
* @brief Sets a new texture size.
|
||||
* Effectively reallocates the texture.
|
||||
|
||||
Reference in New Issue
Block a user