Texture class
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m25s

This commit is contained in:
2024-08-02 20:03:32 -04:00
parent 0005c036b4
commit 9688854533
9 changed files with 128 additions and 36 deletions

View File

@@ -93,13 +93,13 @@ add_executable(JGL_Demo main.cpp)
if (UNIX AND NOT APPLE)
target_include_directories(JGL PRIVATE ${FREETYPE_INCLUDE_DIRS})
target_link_libraries(JGL PRIVATE ${FREETYPE_LIBRARIES})
target_link_libraries(JGL PUBLIC ${OPENGL_LIBRARIES} J3ML ReWindowLibrary glad jlog Event)
target_link_libraries(JGL PUBLIC ${OPENGL_LIBRARIES} J3ML ReWindowLibrary glad jlog Event ReTexture)
endif()
if (WIN32)
target_include_directories(JGL PRIVATE ${freetype_SOURCE_DIR}/include)
target_link_libraries(JGL PRIVATE freetype)
target_link_libraries(JGL PUBLIC ${OPENGL_LIBRARIES} J3ML ReWindowLibrary glad jlog Event)
target_link_libraries(JGL PUBLIC ${OPENGL_LIBRARIES} J3ML ReWindowLibrary glad jlog Event ReTexture)
endif()
target_link_libraries(JGL_Demo PUBLIC JGL ReTexture)
target_link_libraries(JGL_Demo PUBLIC JGL)

View File

@@ -17,6 +17,8 @@ namespace JGL
Color3(u8 R, u8 G, u8 B);
/// Returns a Color3 parsed from the given hexadecimal string.
static Color3 FromHex(const std::string& hexCode);
Color3() = default;
public:
/// Returns a Color3 that is somewhere in-between this and the given Color3, determined by the alpha [0-1].
Color3 Lerp(const Color3& rhs, float alpha) const;

View File

@@ -13,6 +13,7 @@ namespace JGL
u8 b;
u8 a;
public:
Color4() = default;
explicit Color4(const Color3& color3, u8 alpha = 255);
Color4(u8 red, u8 green, u8 blue, u8 alpha = 255);
static Color4 FromColor3(const Color3& color3, u8 alpha = 255);

View File

@@ -15,6 +15,7 @@
#include <string>
#include <iostream>
#include <JGL/Color4.h>
#include <JGL/Texture.h>
#include <JGL/enums.h>
#include <JGL/FontCache.h>
#include <JGL/Font.h>
@@ -102,8 +103,8 @@ namespace JGL {
void OutlineRect(const Color3& color, const Vector2& pos, const Vector2& size, float thickness = 1);
///Draws a sprite to the screen.
void DrawSprite(GLuint texture, const Vector2& pos, const Vector2& size, u8 opacity = 255, Inversion::Inversion inversion = Inversion::None);
void DrawSprite(GLuint texture, float x, float y, float w, float h, u8 opacity = 255, Inversion::Inversion inversion = Inversion::None);
void DrawSprite(const GLuint& texture, const Vector2& pos, const Vector2& size, u8 opacity = 255, Inversion::Inversion inversion = Inversion::None);
void DrawSprite(const GLuint& texture, float x, float y, float w, float h, u8 opacity = 255, Inversion::Inversion inversion = Inversion::None);
///Draws a non axis-aligned fill rect to the screen.
///The order of the vertices must be such that if you were to connect them you'd never go diagonally across the quad.

29
include/JGL/Texture.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <ReTexture/Texture.h>
#include <J3ML/LinearAlgebra.h>
#include <JGL/Color3.h>
#include <JGL/Color4.h>
#include <glad/glad.h>
namespace JGL {
class Texture {
private:
GLuint texture = 0;
Vector2 texture_size = {0, 0};
ReTexture::TextureFlag texture_flags;
ReTexture::TextureFormat texture_format;
public:
Texture() = default;
explicit Texture(const std::string& file);
Texture(const std::string& file, const ReTexture::TextureFlag& flags);
Texture(const std::vector<unsigned char>& pixel_data, const Vector2& size, const ReTexture::TextureFormat& format);
Texture(const std::vector<Color4>& pixel_data, const Vector2& size, const ReTexture::TextureFormat& format);
GLuint getTexture();
Vector2 getSize();
ReTexture::TextureFlag getFlags();
ReTexture::TextureFormat getFormat();
void eraseTexture();
std::vector<Color4> getPixelData();
};
}

View File

@@ -9,10 +9,8 @@
using J3ML::LinearAlgebra::Vector2;
using namespace JGL;
using namespace ReTexture;
Texture* image;
GLuint imageID;
//The Re3D style base projection.
std::vector<GLfloat> perspective(float fov, float aspect, float nearPlane, float farPlane) {
std::vector<float> result(16);
@@ -90,21 +88,7 @@ public:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
image = new Texture("assets/sprites/Re3D.png");
glGenTextures(1, &imageID);
glBindTexture(GL_TEXTURE_2D, imageID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (image->getTextureFormat() == TextureFormat::RGBA)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->getWidth(), image->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixelData.data());
if (image->getTextureFormat() == TextureFormat::RGB)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->getWidth(), image->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixelData.data());
glBindTexture(GL_TEXTURE_2D, 0);
}
Vector3 textAngle = {0,0,0};
@@ -127,7 +111,7 @@ public:
J2D::Begin();
J2D::FillQuad(Color4(Colors::Red), {500, 52}, {500, 152}, {600, 152}, {600, 52});
J2D::FillRect(Colors::Blue, {0,52}, {100,100});
J2D::DrawSprite(imageID, {0, 52}, {(float) image->getWidth(), (float) image->getHeight()}, 128);
J2D::DrawSprite(image->getTexture(), {0, 52}, image->getSize(), 128);
J2D::FillRect(Color4::FromColor3(Colors::Pinks::HotPink), {68, 120}, {32, 32});
J2D::FillGradientRect(Colors::Red, Colors::Blue, Gradient::DiagonalBottomLeft, {100,52}, {100,100});
J2D::FillRoundedRect(JGL::Colors::Red, {200, 52}, {100, 100}, 8, 8);

View File

@@ -126,7 +126,7 @@ namespace JGL {
}
//TODO rotation, I'm unsure if @josh wants degrees or radians.
void J2D::DrawSprite(GLuint texture, const Vector2& pos, const Vector2& size, u8 opacity, Inversion::Inversion inversion) {
void J2D::DrawSprite(const GLuint& texture, const Vector2& pos, const Vector2& size, u8 opacity, Inversion::Inversion inversion) {
if (!inJ2D)
ERROR("Attempt to Render J2D element before J2D begin.")
@@ -180,7 +180,7 @@ namespace JGL {
J2D::OutlineQuad(Color4(color), v1, v2, v3, v4);
}
void J2D::DrawSprite(GLuint texture, float x, float y, float w, float h, u8 opacity, Inversion::Inversion inversion) {
void J2D::DrawSprite(const GLuint& texture, float x, float y, float w, float h, u8 opacity, Inversion::Inversion inversion) {
J2D::DrawSprite(texture, {x, y}, {w, h}, opacity, inversion);
}

View File

@@ -97,13 +97,6 @@ namespace JGL
}
Vector2 Font::MeasureString(const std::string &text, unsigned int ptSize) {
// TODO: Check if a font of that size is in the cache and if so use the info from that because this is sloooooooooooooow.
// That'll make it go vroom vroom.
// TODO: Work in-progress implementation unfortunately.
// This is likely returning slightly incorrect results for likely several reasons.
// Half-ass solution for now ~ dawsh.
Vector2 extents = Vector2(0,0);
bool font_of_size_in_cache = false;
@@ -131,11 +124,11 @@ namespace JGL
FT_Set_Pixel_Sizes(this->face, ptSize, ptSize);
for (const char& c : text) {
FT_GlyphSlot slot = face->glyph;
auto glyph_index = FT_Get_Char_Index(this->face, c);
auto error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
if (error)
continue;
@@ -147,15 +140,12 @@ namespace JGL
extents += advance;
// Gives smaller results than we'd want.
if (extents.y < slot->metrics.height / 64) {
if (extents.y < slot->metrics.height / 64)
extents.y = slot->metrics.height / 64;
}
// Just fucking hardcode it, we know the glyph height is roughly always the ptSize anyway.
if (extents.y < ptSize)
{
extents.y = ptSize;
}
}
return extents;

85
src/JGL/Texture.cpp Normal file
View File

@@ -0,0 +1,85 @@
#include <JGL/Texture.h>
#include <iostream>
JGL::Texture::Texture(const std::string &file, const ReTexture::TextureFlag &flags) {
auto* t = new ReTexture::Texture(file, flags);
*this = Texture(t->pixelData, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat());
texture_flags = flags;
}
JGL::Texture::Texture(const std::string& file) {
auto* t = new ReTexture::Texture(file);
*this = Texture(t->pixelData, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat());
delete t;
}
JGL::Texture::Texture(const std::vector<Color4>& pixel_data, const Vector2 &size, const ReTexture::TextureFormat &format) {
std::vector<unsigned char> pixels(pixel_data.size());
memcpy(pixels.data(), pixel_data.data(), pixels.size());
*this = Texture(pixels, size, format);
}
JGL::Texture::Texture(const std::vector<unsigned char>& pixel_data, const Vector2& size, const ReTexture::TextureFormat& format) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
if (format == ReTexture::TextureFormat::RGBA)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int) size.x, (int) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data.data());
else if (format == ReTexture::TextureFormat::RGB)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (int) size.x, (int) size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, pixel_data.data());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
texture_size = size;
texture_format = format;
}
std::vector<JGL::Color4> JGL::Texture::getPixelData() {
std::vector<JGL::Color4> result((size_t) (texture_size.x * texture_size.y));
glBindTexture(GL_TEXTURE_2D, texture);
if (texture_format == ReTexture::TextureFormat::RGBA) {
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
return result;
}
std::vector<JGL::Color3> color3((size_t) (texture_size.x * texture_size.y));
if (texture_format == ReTexture::TextureFormat::RGB)
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, color3.data());
for (const auto& c : color3)
result.emplace_back(c);
return result;
}
void JGL::Texture::eraseTexture() {
if (texture != 0)
glDeleteTextures(1, &texture);
}
GLuint JGL::Texture::getTexture() {
return texture;
}
Vector2 JGL::Texture::getSize() {
return texture_size;
}
ReTexture::TextureFlag JGL::Texture::getFlags() {
return texture_flags;
}
ReTexture::TextureFormat JGL::Texture::getFormat() {
return texture_format;
}