Copy texture without readbacks.
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 2m5s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 2m5s
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
||||
#include <JGL/types/Texture.h>
|
||||
#include <Color4.hpp>
|
||||
#include <Colors.hpp>
|
||||
#include <JGL/types/Enums.h>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
|
||||
namespace JGL {
|
||||
class RenderTarget;
|
||||
class Texture; // Forward declare.
|
||||
}
|
||||
|
||||
//TODO copy constructor for this. Copying this as it is and then that copy going out of scope will crash the program as it sits.
|
||||
@@ -21,7 +22,7 @@ private:
|
||||
bool texture_created_by_us = false;
|
||||
GLuint framebuffer_object = 0;
|
||||
GLuint depth_buffer = 0;
|
||||
Texture* texture = nullptr;
|
||||
const Texture* texture = nullptr;
|
||||
MSAA_SAMPLE_RATE msaa_sample_rate = MSAA_SAMPLE_RATE::MSAA_NONE;
|
||||
GLuint msaa_framebuffer_object = 0;
|
||||
GLuint msaa_depth_buffer = 0;
|
||||
@@ -39,6 +40,9 @@ public:
|
||||
/// Blits the MSAA FBO onto the regular FBO if MSAA is enabled and or If you're rendering to a texture which uses mipmaps,
|
||||
/// It regenerates them so what you drew doesn't disappear at a distance. Otherwise it does nothing.
|
||||
void Blit() const;
|
||||
|
||||
/// Blit a render target onto another. Will break if they're not the same size.
|
||||
static void Blit(const RenderTarget& source, RenderTarget* destination);
|
||||
[[nodiscard]] bool TextureCreatedByRenderTarget() const;
|
||||
public:
|
||||
[[nodiscard]] Vector2 GetDimensions() const;
|
||||
@@ -47,7 +51,7 @@ public:
|
||||
/// You need to run "Blit()" after rendering to your FBO before you show it.
|
||||
/// @note Also, If the texture wasn't made by the RenderTarget you don't want this. It would destroy the texture.
|
||||
[[nodiscard]] bool MSAAEnabled() const;
|
||||
[[nodiscard]] Texture* GetJGLTexture() const;
|
||||
[[nodiscard]] const Texture* GetJGLTexture() const;
|
||||
[[nodiscard]] GLuint GetGLTextureHandle() const;
|
||||
[[nodiscard]] GLuint GetGLFramebufferObjectHandle() const;
|
||||
[[nodiscard]] GLuint GetGLDepthBufferHandle() const;
|
||||
@@ -56,7 +60,7 @@ public:
|
||||
[[nodiscard]] std::vector<GLfloat> GetData() const;
|
||||
public:
|
||||
/// Create a render target for a texture that already exists. For adding to an existing texture.
|
||||
explicit RenderTarget(Texture* texture, const Color4& clear_color = Colors::Black);
|
||||
explicit RenderTarget(const Texture* texture, const Color4& clear_color = Colors::Black);
|
||||
/// Create a Render Target with a brand new texture. Want to render JGL elements onto a texture and display it as a sprite?
|
||||
explicit RenderTarget(const Vector2& size, const Color4& clear_color = Colors::Black, bool use_depth = false, MSAA_SAMPLE_RATE sample_rate = MSAA_SAMPLE_RATE::MSAA_NONE);
|
||||
~RenderTarget();
|
||||
|
@@ -52,8 +52,6 @@ namespace JGL {
|
||||
[[nodiscard]] TextureFlag GetFlags() const;
|
||||
[[nodiscard]] TextureFormat GetFormat() const;
|
||||
[[nodiscard]] std::vector<Color4> GetPixelData() const;
|
||||
void SetTextureHandle(GLuint handle);
|
||||
void SetFlags(const TextureFlag& flags);
|
||||
};
|
||||
|
||||
}
|
2
main.cpp
2
main.cpp
@@ -118,7 +118,7 @@ public:
|
||||
glDepthMask(GL_TRUE);
|
||||
image = new Texture("assets/sprites/Re3D.png", TextureFilteringMode::BILINEAR);
|
||||
j2d_render_target = new RenderTarget({540, 540}, {0,0,0,0}, false, MSAA_SAMPLE_RATE::MSAA_8X);
|
||||
image2 = new Texture("assets/sprites/Re3D.png",TextureFilteringMode::BILINEAR);
|
||||
image2 = image;
|
||||
image2_render_target = new RenderTarget(image2);
|
||||
|
||||
J2D::Begin(image2_render_target);
|
||||
|
@@ -162,7 +162,8 @@ namespace JGL {
|
||||
float y = pos.y;
|
||||
float z = pos.z;
|
||||
|
||||
|
||||
// TODO: this is broken because it causes the text to be shifted downwards.
|
||||
/*
|
||||
bool round_text_coords_for_crisp_rendering = true;
|
||||
|
||||
// TODO: This currently does not account for non-integer scale factors.
|
||||
@@ -172,6 +173,7 @@ namespace JGL {
|
||||
y = J3ML::Math::Floor(y);
|
||||
z = J3ML::Math::Floor(z);
|
||||
}
|
||||
*/
|
||||
|
||||
CachedFont* cachedFont = fontCache.getFont(size, font.index);
|
||||
if (font.face == nullptr)
|
||||
|
@@ -1,8 +1,9 @@
|
||||
#include <JGL/types/RenderTarget.h>
|
||||
#include <JGL/types/Texture.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <stdexcept>
|
||||
|
||||
JGL::Texture* JGL::RenderTarget::GetJGLTexture() const {
|
||||
const JGL::Texture* JGL::RenderTarget::GetJGLTexture() const {
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ Color4 JGL::RenderTarget::GetClearColor() const {
|
||||
}
|
||||
|
||||
/// Idk why you'd ever want to clear it out if you're rendering onto a texture you passed in :shrug:.
|
||||
JGL::RenderTarget::RenderTarget(JGL::Texture* texture, const Color4& clear_color) {
|
||||
JGL::RenderTarget::RenderTarget(const JGL::Texture* texture, const Color4& clear_color) {
|
||||
GLuint current_fbo = GetActiveGLFramebufferHandle();
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
@@ -112,7 +113,6 @@ JGL::RenderTarget::RenderTarget(const Vector2& size, const Color4& clear_color,
|
||||
this->clear_color = clear_color;
|
||||
this->size = size;
|
||||
texture_created_by_us = true;
|
||||
this->texture->SetFlags(INVERT_Y);
|
||||
|
||||
if (sample_rate != MSAA_SAMPLE_RATE::MSAA_NONE)
|
||||
SetMSAAEnabled(sample_rate);
|
||||
@@ -301,3 +301,25 @@ void JGL::RenderTarget::Blit() const {
|
||||
glBindTexture(GL_TEXTURE_2D, current_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::RenderTarget::Blit(const JGL::RenderTarget& source, JGL::RenderTarget* destination) {
|
||||
if (source.size != destination->size)
|
||||
Logger::Warning("Blitting a render target but they're not the same size?");
|
||||
|
||||
// Save the GL state.
|
||||
GLuint current_fbo = GetActiveGLFramebufferHandle();
|
||||
GLint current_draw_fbo = 0;
|
||||
GLint current_read_fbo = 0;
|
||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, ¤t_read_fbo);
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_draw_fbo);
|
||||
|
||||
// Draw the contents of one into the other.
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.framebuffer_object);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destination->framebuffer_object);
|
||||
glBlitFramebuffer(0, 0, source.size.x, source.size.y, 0, 0, source.size.x, source.size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Put the GL state back.
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, current_read_fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_draw_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include <JGL/types/Texture.h>
|
||||
#include <iostream>
|
||||
#include <JGL/types/RenderTarget.h>
|
||||
|
||||
using namespace ReImage;
|
||||
|
||||
@@ -36,9 +37,11 @@ namespace JGL
|
||||
texture_size = size;
|
||||
texture_filtering_mode = TextureFilteringMode::NEAREST;
|
||||
texture_wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE;
|
||||
texture_flags = TextureFlag::NONE;
|
||||
// Because in vram it'll be right side up.
|
||||
texture_flags = TextureFlag::INVERT_Y;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, previous_texture);
|
||||
|
||||
}
|
||||
|
||||
void Texture::load(Image* software_texture, const Vector2& size, const TextureFormat& format,
|
||||
@@ -155,10 +158,6 @@ namespace JGL
|
||||
return texture_filtering_mode;
|
||||
}
|
||||
|
||||
void Texture::SetTextureHandle(GLuint handle) {
|
||||
texture_handle = handle;
|
||||
}
|
||||
|
||||
TextureWrappingMode Texture::GetWrappingMode() const {
|
||||
return texture_wrapping_mode;
|
||||
}
|
||||
@@ -173,13 +172,21 @@ namespace JGL
|
||||
}
|
||||
|
||||
Texture::Texture(const Texture& rhs) {
|
||||
auto pixels = rhs.GetPixelData();
|
||||
auto image = Image(pixels.data(), pixels.size(), rhs.GetDimensions().x, rhs.GetDimensions().y);
|
||||
this->load(&image, rhs.GetDimensions(), rhs.texture_format, rhs.texture_filtering_mode, rhs.texture_wrapping_mode);
|
||||
this->texture_flags = rhs.texture_flags;
|
||||
}
|
||||
auto* this_texture = new Texture(rhs.GetDimensions());
|
||||
auto this_render_target = RenderTarget(this);
|
||||
auto rhs_render_target = RenderTarget(&rhs);
|
||||
|
||||
void Texture::SetFlags(const TextureFlag &flags) {
|
||||
this->texture_flags = flags;
|
||||
RenderTarget::Blit(rhs_render_target, &this_render_target);
|
||||
|
||||
this->texture_handle = this_texture->texture_handle;
|
||||
this->texture_size = this_texture->texture_size;
|
||||
this->texture_flags = this_texture->texture_flags;
|
||||
this->texture_format = this_texture->texture_format;
|
||||
this->texture_filtering_mode = this_texture->texture_filtering_mode;
|
||||
this->texture_wrapping_mode = this_texture->texture_wrapping_mode;
|
||||
|
||||
// Free the memory of "this_texture" without calling the destructor.
|
||||
// In 99% of cases you wouldn't want this. But in this scenario we do.
|
||||
operator delete(this_texture);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user