mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-04 17:35:43 +00:00
Added a framebuffer class for drawing the presets into.
This commit is contained in:
@ -26,12 +26,6 @@
|
||||
#include "PresetFileParser.hpp"
|
||||
#include "PresetFrameIO.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "dirent.h"
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif /** _WIN32 */
|
||||
|
||||
#ifdef MILKDROP_PRESET_DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
@ -57,6 +51,10 @@ MilkdropPreset::MilkdropPreset(const std::string& absoluteFilePath)
|
||||
|
||||
void MilkdropPreset::InitializePreset(PresetFileParser& parsedFile)
|
||||
{
|
||||
// Create the offscreen rendering surfaces.
|
||||
m_framebuffer.CreateColorAttachment(0, 0);
|
||||
m_framebuffer.CreateColorAttachment(1, 0);
|
||||
|
||||
// Load global init variables into the state
|
||||
m_state.Initialize(parsedFile);
|
||||
|
||||
@ -142,11 +140,29 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio
|
||||
m_state.audioData = audioData;
|
||||
m_state.renderContext = renderContext;
|
||||
|
||||
// Update framebuffer size if needed
|
||||
m_framebuffer.SetSize(renderContext.viewportSizeX, renderContext.viewportSizeY);
|
||||
|
||||
// First evaluate per-frame code
|
||||
PerFrameUpdate();
|
||||
|
||||
// Motion vector field
|
||||
// ToDo: Draw motion vectors to separate texture
|
||||
// Motion vector field. Drawn to the previous frame texture before warping it.
|
||||
m_framebuffer.Bind(1);
|
||||
// ToDo: Move this to the draw call and pass in the per-frame context.
|
||||
m_motionVectors.r = static_cast<float>(*m_perFrameContext.mv_r);
|
||||
m_motionVectors.g = static_cast<float>(*m_perFrameContext.mv_g);
|
||||
m_motionVectors.b = static_cast<float>(*m_perFrameContext.mv_b);
|
||||
m_motionVectors.a = static_cast<float>(*m_perFrameContext.mv_a);
|
||||
m_motionVectors.length = static_cast<float>(*m_perFrameContext.mv_l);
|
||||
m_motionVectors.x_num = static_cast<float>(*m_perFrameContext.mv_x);
|
||||
m_motionVectors.y_num = static_cast<float>(*m_perFrameContext.mv_y);
|
||||
m_motionVectors.x_offset = static_cast<float>(*m_perFrameContext.mv_dx);
|
||||
m_motionVectors.y_offset = static_cast<float>(*m_perFrameContext.mv_dy);
|
||||
m_motionVectors.Draw(renderContext);
|
||||
|
||||
// We now draw to the first framebuffer, but read from the second one for warping.
|
||||
m_framebuffer.BindRead(1);
|
||||
m_framebuffer.BindDraw(0);
|
||||
|
||||
// Draw previous frame image warped via per-pixel mesh and warp shader
|
||||
// ToDo: ComputeGridAlphaValues
|
||||
@ -162,12 +178,20 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio
|
||||
wave->Draw(m_perFrameContext);
|
||||
}
|
||||
m_waveform.Draw();
|
||||
|
||||
// ToDo: Sprite drawing would go here.
|
||||
|
||||
// Todo: Song title anim would go here
|
||||
|
||||
// ToDo: Store main texture for next frame
|
||||
// Copy pixels from framebuffer index 0 to 1
|
||||
m_framebuffer.BindRead(0);
|
||||
m_framebuffer.BindDraw(1);
|
||||
glBlitFramebuffer(0, 0, renderContext.viewportSizeX, renderContext.viewportSizeY,
|
||||
0, 0, renderContext.viewportSizeX, renderContext.viewportSizeY,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// ToDo: Apply composite shader
|
||||
m_framebuffer.Bind(0);
|
||||
|
||||
// ToDo: Draw user sprites (can have evaluated code)
|
||||
}
|
||||
|
||||
@ -27,10 +27,13 @@
|
||||
#include "CustomWaveform.hpp"
|
||||
#include "PerFrameContext.hpp"
|
||||
#include "PerPixelContext.hpp"
|
||||
#include "PerPixelMesh.hpp"
|
||||
#include "Preset.hpp"
|
||||
#include "PresetFrameIO.hpp"
|
||||
#include "Waveform.hpp"
|
||||
|
||||
#include <Renderer/Framebuffer.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@ -91,10 +94,15 @@ private:
|
||||
std::string m_absoluteFilePath; //!< The absolute file path of the MilkdropPreset
|
||||
std::string m_absolutePath; //!< The absolute path of the MilkdropPreset
|
||||
|
||||
Framebuffer m_framebuffer{2}; //!< Preset rendering framebuffer with two surfaces (last frame and current frame).
|
||||
|
||||
PresetState m_state; //!< Preset state container.
|
||||
PerFrameContext m_perFrameContext; //!< Preset per-frame evaluation code context.
|
||||
PerPixelContext m_perPixelContext; //!< Preset per-pixel/per-vertex evaluation code context.
|
||||
|
||||
PerPixelMesh m_perPixelMesh; //!< The per-pixel/per-vertex mesh, responsible for most of the movement/warp effects in Milkdrop presets.
|
||||
|
||||
MotionVectors m_motionVectors; //!< Motion vector grid.
|
||||
Waveform m_waveform; //!< Preset default waveform.
|
||||
std::array<std::unique_ptr<CustomWaveform>, CustomWaveformCount> m_customWaveforms; //!< Custom waveforms in this preset.
|
||||
std::array<std::unique_ptr<CustomShape>, CustomShapeCount> m_customShapes; //!< Custom shapes in this preset.
|
||||
|
||||
@ -10,12 +10,13 @@ MotionVectors::MotionVectors()
|
||||
|
||||
void MotionVectors::InitVertexAttrib() {
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glDisableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
void MotionVectors::Draw(RenderContext &context)
|
||||
void MotionVectors::Draw(const RenderContext& context)
|
||||
{
|
||||
// ToDo: Implement the actual Milkdop behaviour here, including reverse propagation.
|
||||
float intervalx=1.0/x_num;
|
||||
float intervaly=1.0/y_num;
|
||||
|
||||
@ -42,7 +43,7 @@ void MotionVectors::Draw(RenderContext &context)
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair) * size, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair) * size, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair) * size, points, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
@ -66,6 +67,7 @@ void MotionVectors::Draw(RenderContext &context)
|
||||
|
||||
glBindVertexArray(m_vaoID);
|
||||
|
||||
// ToDo: Milkdrop draws lines in the direction of motion, not just points!
|
||||
glDrawArrays(GL_POINTS,0,size);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
@ -26,16 +26,16 @@ public:
|
||||
* Redners the motion vectors.
|
||||
* @param context The render context data.
|
||||
*/
|
||||
void Draw(RenderContext &context);
|
||||
void Draw(const RenderContext &context);
|
||||
|
||||
float r{ 0.0 }; //!< Red color channel of the motion vectors.
|
||||
float g{ 0.0 }; //!< Green color channel of the motion vectors.
|
||||
float b{ 0.0 }; //!< Blue color channel of the motion vectors.
|
||||
float a{ 0.0 }; //!< Alpha channel of the motion vectors.
|
||||
float length{ 0.0 }; //!< Line length of the motion vectors.
|
||||
float x_num{ 0.0 }; //!< Horizontal grid size.
|
||||
float y_num{ 0.0 }; //!< Vertical grid size.
|
||||
float x_offset{ 0.0 }; //!< Horizontal grid offset.
|
||||
float y_offset{ 0.0 }; //!< Vertical grid offset.
|
||||
float r{ 0.0 }; //!< Red color channel of the motion vectors (mv_r).
|
||||
float g{ 0.0 }; //!< Green color channel of the motion vectors (mv_g).
|
||||
float b{ 0.0 }; //!< Blue color channel of the motion vectors (mv_b).
|
||||
float a{ 0.0 }; //!< Alpha channel of the motion vectors (mv_a).
|
||||
float length{ 0.0 }; //!< Line length of the motion vectors (mv_l).
|
||||
float x_num{ 0.0 }; //!< Horizontal grid size (integer part of mv_x).
|
||||
float y_num{ 0.0 }; //!< Vertical grid size (integer part of mv_y).
|
||||
float x_offset{ 0.0 }; //!< Horizontal grid offset (mv_dx).
|
||||
float y_offset{ 0.0 }; //!< Vertical grid offset (mv_dy).
|
||||
|
||||
};
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
add_library(Renderer OBJECT
|
||||
FileScanner.cpp
|
||||
FileScanner.hpp
|
||||
Framebuffer.cpp
|
||||
Framebuffer.hpp
|
||||
RenderContext.hpp
|
||||
RenderItem.cpp
|
||||
RenderItem.hpp
|
||||
@ -15,6 +17,8 @@ add_library(Renderer OBJECT
|
||||
StaticGlShaders.cpp
|
||||
Texture.cpp
|
||||
Texture.hpp
|
||||
TextureAttachment.cpp
|
||||
TextureAttachment.hpp
|
||||
TextureManager.cpp
|
||||
TextureManager.hpp
|
||||
)
|
||||
|
||||
164
src/libprojectM/Renderer/Framebuffer.cpp
Normal file
164
src/libprojectM/Renderer/Framebuffer.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include "Framebuffer.hpp"
|
||||
|
||||
Framebuffer::Framebuffer()
|
||||
{
|
||||
m_framebufferIds.resize(1);
|
||||
glGenFramebuffers(1, m_framebufferIds.data());
|
||||
m_attachments.insert({0, {}});
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer(int framebufferCount)
|
||||
{
|
||||
m_framebufferIds.resize(framebufferCount);
|
||||
glGenFramebuffers(framebufferCount, m_framebufferIds.data());
|
||||
for (int index = 0; index < framebufferCount; index++)
|
||||
{
|
||||
m_attachments.insert({index, {}});
|
||||
}
|
||||
}
|
||||
|
||||
Framebuffer::~Framebuffer()
|
||||
{
|
||||
if (!m_framebufferIds.empty())
|
||||
{
|
||||
// Delete attached textures first
|
||||
m_attachments.clear();
|
||||
|
||||
glDeleteFramebuffers(static_cast<int>(m_framebufferIds.size()), m_framebufferIds.data());
|
||||
m_framebufferIds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
auto Framebuffer::Count() const -> int
|
||||
{
|
||||
return static_cast<int>(m_framebufferIds.size());
|
||||
}
|
||||
|
||||
void Framebuffer::Bind(int framebufferIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferIds.at(framebufferIndex));
|
||||
}
|
||||
|
||||
void Framebuffer::BindRead(int framebufferIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_framebufferIds.at(framebufferIndex));
|
||||
}
|
||||
|
||||
void Framebuffer::BindDraw(int framebufferIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebufferIds.at(framebufferIndex));
|
||||
}
|
||||
|
||||
void Framebuffer::SetSize(int width, int height)
|
||||
{
|
||||
if (width == 0 || height == 0 ||
|
||||
(width == m_width && height == m_height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
for (auto& attachments : m_attachments)
|
||||
{
|
||||
Bind(attachments.first);
|
||||
for (auto& texture : attachments.second)
|
||||
{
|
||||
texture.second.SetSize(width, height);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, texture.first, GL_TEXTURE_2D, texture.second.TextureId(), 0);
|
||||
}
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void Framebuffer::CreateColorAttachment(int framebufferIndex, int attachmentIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::Color, m_width, m_height};
|
||||
auto textureId = textureAttachment.TextureId();
|
||||
m_attachments.at(framebufferIndex).insert({GL_COLOR_ATTACHMENT0 + attachmentIndex, std::move(textureAttachment)});
|
||||
|
||||
if (m_width > 0 && m_height > 0)
|
||||
{
|
||||
Bind(framebufferIndex);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachmentIndex, GL_TEXTURE_2D, textureId, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::CreateDepthAttachment(int framebufferIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::Depth, m_width, m_height};
|
||||
auto textureId = textureAttachment.TextureId();
|
||||
m_attachments.at(framebufferIndex).insert({GL_DEPTH_ATTACHMENT, std::move(textureAttachment)});
|
||||
|
||||
if (m_width > 0 && m_height > 0)
|
||||
{
|
||||
Bind(framebufferIndex);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureId, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::CreateStencilAttachment(int framebufferIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::Stencil, m_width, m_height};
|
||||
auto textureId = textureAttachment.TextureId();
|
||||
m_attachments.at(framebufferIndex).insert({GL_STENCIL_ATTACHMENT, std::move(textureAttachment)});
|
||||
|
||||
if (m_width > 0 && m_height > 0)
|
||||
{
|
||||
Bind(framebufferIndex);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textureId, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::CreateDepthStencilAttachment(int framebufferIndex)
|
||||
{
|
||||
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::DepthStencil, m_width, m_height};
|
||||
auto textureId = textureAttachment.TextureId();
|
||||
m_attachments.at(framebufferIndex).insert({GL_DEPTH_STENCIL_ATTACHMENT, std::move(textureAttachment)});
|
||||
|
||||
if (m_width > 0 && m_height > 0)
|
||||
{
|
||||
Bind(framebufferIndex);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textureId, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
105
src/libprojectM/Renderer/Framebuffer.hpp
Normal file
105
src/libprojectM/Renderer/Framebuffer.hpp
Normal file
@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include "TextureAttachment.hpp"
|
||||
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief A framebuffer class holding one or more framebuffer objects.
|
||||
*
|
||||
* Framebuffers act as both render targets and sampling sources. This class holds one or more of those
|
||||
* objects, either used to store current and previous frame images or sub images for multi-stage
|
||||
* rendering.
|
||||
*
|
||||
* Each framebuffer can have multiple color attachments (at least up to 8), one depth buffer,
|
||||
* one stencil buffer and one depth stencil buffer.
|
||||
*
|
||||
* All framebuffers and their attachments will share the same size.
|
||||
*/
|
||||
class Framebuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a new framebuffer object with one framebuffer.
|
||||
*/
|
||||
Framebuffer();
|
||||
|
||||
/**
|
||||
* @brief Creates a new framebuffer object with a given number of framebuffers.
|
||||
* @param framebufferCount The number of framebuffers to create. Must be at least 1.
|
||||
*/
|
||||
explicit Framebuffer(int framebufferCount);
|
||||
|
||||
/**
|
||||
* @brief Destroys the framebuffer object and all attachments.
|
||||
*/
|
||||
~Framebuffer();
|
||||
|
||||
/**
|
||||
* @brief Returns the number of framebuffers in this object.
|
||||
* @return The number of framebuffers in this object.
|
||||
*/
|
||||
int Count() const;
|
||||
|
||||
/**
|
||||
* @brief Binds the given index as the current read/write framebuffer.
|
||||
* @param framebufferIndex The framebuffer index.
|
||||
*/
|
||||
void Bind(int framebufferIndex);
|
||||
|
||||
/**
|
||||
* @brief Binds the given index as the current read framebuffer.
|
||||
* @param framebufferIndex The framebuffer index.
|
||||
*/
|
||||
void BindRead(int framebufferIndex);
|
||||
|
||||
/**
|
||||
* @brief Binds the given index as the current write/draw framebuffer.
|
||||
* @param framebufferIndex The framebuffer index.
|
||||
*/
|
||||
void BindDraw(int framebufferIndex);
|
||||
|
||||
/**
|
||||
* @brief Sets the framebuffer texture size.
|
||||
*
|
||||
* This will bind the framebuffers and reallocate all attachment textures, creating new
|
||||
* textures with the given size. The default framebuffer is bound after the call is finished.
|
||||
* If either width or height is zero or both equal the the current size, the framebuffer contents
|
||||
* won't be changed.
|
||||
* @param width The width of the framebuffer.
|
||||
* @param height The height of the framebuffer.
|
||||
*/
|
||||
void SetSize(int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Adds a new color attachment to the framebuffer.
|
||||
* The texture is always created in RGBA format.
|
||||
* @param index The index of the attachment, at least indices 0-7 are guaranteed to be available.
|
||||
*/
|
||||
void CreateColorAttachment(int framebufferIndex, int attachmentIndex);
|
||||
|
||||
/**
|
||||
* @brief Adds a depth attachment to the framebuffer.
|
||||
*/
|
||||
void CreateDepthAttachment(int framebufferIndex);
|
||||
|
||||
/**
|
||||
* @brief Adds a stencil buffer attachment to the framebuffer.
|
||||
*/
|
||||
void CreateStencilAttachment(int framebufferIndex);
|
||||
|
||||
/**
|
||||
* @brief Adds a depth stencil buffer attachment to the framebuffer.
|
||||
*/
|
||||
void CreateDepthStencilAttachment(int framebufferIndex);
|
||||
|
||||
private:
|
||||
std::vector<unsigned int> m_framebufferIds{}; //!< The framebuffer IDs returned by OpenGL
|
||||
std::map<int, std::map<GLenum, TextureAttachment>> m_attachments; //!< Framebuffer texture attachments.
|
||||
|
||||
int m_width{}; //!< Framebuffers texture width
|
||||
int m_height{}; //!< Framebuffers texture height.
|
||||
};
|
||||
92
src/libprojectM/Renderer/TextureAttachment.cpp
Normal file
92
src/libprojectM/Renderer/TextureAttachment.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "TextureAttachment.hpp"
|
||||
|
||||
TextureAttachment::TextureAttachment(AttachmentType attachment, int width, int height)
|
||||
: m_attachmentType(attachment)
|
||||
{
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
ReplaceTexture(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
TextureAttachment::~TextureAttachment()
|
||||
{
|
||||
if (m_textureId > 0)
|
||||
{
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
m_textureId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto TextureAttachment::Type() const -> TextureAttachment::AttachmentType
|
||||
{
|
||||
return m_attachmentType;
|
||||
}
|
||||
|
||||
auto TextureAttachment::TextureId() const -> GLuint
|
||||
{
|
||||
return m_textureId;
|
||||
}
|
||||
|
||||
void TextureAttachment::SetSize(int width, int height)
|
||||
{
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
ReplaceTexture(width, height);
|
||||
}
|
||||
else if (m_textureId > 0)
|
||||
{
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
m_textureId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureAttachment::ReplaceTexture(int width, int height)
|
||||
{
|
||||
if (m_textureId > 0)
|
||||
{
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
}
|
||||
|
||||
GLint internalFormat;
|
||||
GLint textureFormat;
|
||||
GLenum pixelFormat;
|
||||
|
||||
switch(m_attachmentType)
|
||||
{
|
||||
case AttachmentType::Color:
|
||||
internalFormat = GL_RGBA;
|
||||
textureFormat = GL_RGBA;
|
||||
pixelFormat = GL_TEXTURE_2D;
|
||||
break;
|
||||
case AttachmentType::Depth:
|
||||
internalFormat = GL_DEPTH_COMPONENT;
|
||||
textureFormat = GL_DEPTH_COMPONENT;
|
||||
pixelFormat = GL_FLOAT;
|
||||
break;
|
||||
case AttachmentType::Stencil:
|
||||
internalFormat = GL_STENCIL_INDEX8;
|
||||
textureFormat = GL_STENCIL_INDEX;
|
||||
pixelFormat = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case AttachmentType::DepthStencil:
|
||||
internalFormat = GL_DEPTH24_STENCIL8;
|
||||
textureFormat = GL_DEPTH_STENCIL;
|
||||
pixelFormat = GL_UNSIGNED_INT_24_8;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
glGenTextures(1, &m_textureId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, textureFormat, pixelFormat, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
44
src/libprojectM/Renderer/TextureAttachment.hpp
Normal file
44
src/libprojectM/Renderer/TextureAttachment.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @brief Framebuffer texture attachment. Stores the texture and attachment type.
|
||||
*/
|
||||
class TextureAttachment
|
||||
{
|
||||
public:
|
||||
enum class AttachmentType
|
||||
{
|
||||
Color,
|
||||
Depth,
|
||||
Stencil,
|
||||
DepthStencil
|
||||
};
|
||||
|
||||
TextureAttachment() = delete;
|
||||
|
||||
explicit TextureAttachment(AttachmentType attachmentType, int width, int height);
|
||||
|
||||
~TextureAttachment();
|
||||
|
||||
auto Type() const -> AttachmentType;
|
||||
|
||||
auto TextureId() const -> GLuint;
|
||||
|
||||
/**
|
||||
* @brief Sets a new texture size.
|
||||
* Effectively reallocates the texture.
|
||||
* @param width The new width.
|
||||
* @param height The new height.
|
||||
*/
|
||||
void SetSize(int width, int height);
|
||||
|
||||
private:
|
||||
void ReplaceTexture(int width, int height);
|
||||
|
||||
AttachmentType m_attachmentType{AttachmentType::Color}; //!< Attachment type of this texture.
|
||||
GLuint m_textureId{}; //!< The Texture ID.
|
||||
};
|
||||
Reference in New Issue
Block a user