Compare commits
17 Commits
Prerelease
...
Prerelease
Author | SHA1 | Date | |
---|---|---|---|
db7a37d647 | |||
26600915db | |||
7bc87d00ef | |||
5e65f17a90 | |||
426498d53c | |||
28bdc7f667 | |||
|
e8bfa7b6f0 | ||
d60620ef7c | |||
8cb470ad1c | |||
575a4a0f9b | |||
e9bdaf54b6 | |||
7b2f7de032 | |||
e8245c4442 | |||
bd918aa351 | |||
a0cc8524d9 | |||
1964aeae86 | |||
b84e2ee2c5 |
@@ -17,6 +17,6 @@ jobs:
|
||||
- run: echo "The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||
- run: echo "The workflow is now ready to run your tests on the runner."
|
||||
- run: echo "Install toolchain and run ReCI build test"
|
||||
- run: apt-get update && apt-get install -y lua5.3 git libxrandr-dev && git clone $RECI_GIT $RECI
|
||||
- run: apt-get update && apt-get install -y lua5.3 git libxrandr-dev libvulkan-dev && git clone $RECI_GIT $RECI
|
||||
- run: lua $RECI/reci.lua -f $RECI/scripts/buildtools.reci -f reci/scripts/builddeps.reci -f $RECI/scripts/buildtest.reci
|
||||
- run: echo "This job's status is ${{ job.status }}."
|
||||
|
@@ -22,12 +22,12 @@ CPMAddPackage(
|
||||
|
||||
CPMAddPackage(
|
||||
NAME J3ML
|
||||
URL https://git.redacted.cc/josh/j3ml/archive/3.4.3.zip
|
||||
URL https://git.redacted.cc/josh/j3ml/archive/3.4.5.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME ReWindow
|
||||
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-26.zip
|
||||
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-32.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
@@ -40,17 +40,7 @@ CPMAddPackage(
|
||||
URL https://git.redacted.cc/josh/jlog/Prerelease-16.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME ReImage
|
||||
URL https://git.redacted.cc/Redacted/ReImage/archive/Release-2.0.zip
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
#CPMAddPackage(
|
||||
#NAME harfbuzz
|
||||
#URL https://github.com/harfbuzz/harfbuzz/archive/refs/tags/9.0.0.zip
|
||||
#)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME freetype
|
||||
URL https://github.com/freetype/freetype/archive/refs/tags/VER-2-13-2.zip
|
||||
@@ -62,9 +52,7 @@ endif()
|
||||
file(COPY "assets" DESTINATION "${PROJECT_BINARY_DIR}")
|
||||
file(GLOB_RECURSE ASSETS "assets/*")
|
||||
file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp" )
|
||||
file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp" "src/internals/*.h")
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp" "src/*.h")
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
find_package(Freetype REQUIRED)
|
||||
@@ -85,8 +73,6 @@ include_directories(
|
||||
|
||||
target_include_directories(JGL PUBLIC
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${OPENGL_INCLUDE_DIRS}
|
||||
${ReImage_SOURCE_DIR}/include
|
||||
${mcolor_SOURCE_DIR}/include
|
||||
${J3ML_SOURCE_DIR}/include
|
||||
${jlog_SOURCE_DIR}/include
|
||||
@@ -99,13 +85,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} mcolor J3ML jlog ReImage glad)
|
||||
target_link_libraries(JGL PUBLIC mcolor J3ML jlog glad)
|
||||
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} mcolor J3ML glad jlog ReImage glad)
|
||||
target_link_libraries(JGL PUBLIC ${OPENGL_LIBRARIES} mcolor J3ML glad jlog glad)
|
||||
endif()
|
||||
|
||||
target_link_libraries(JGL_Demo PUBLIC JGL ReWindowLibrary Event glad)
|
||||
target_link_libraries(JGL_Demo PUBLIC JGL ReWindow Event glad)
|
||||
|
46
assets/models/cube.amo
Normal file
46
assets/models/cube.amo
Normal file
@@ -0,0 +1,46 @@
|
||||
ao Cube 1
|
||||
v 8
|
||||
1.000000 1.000000 1.000000
|
||||
1.000000 1.000000 -1.000000
|
||||
1.000000 -1.000000 1.000000
|
||||
1.000000 -1.000000 -1.000000
|
||||
-1.000000 1.000000 1.000000
|
||||
-1.000000 1.000000 -1.000000
|
||||
-1.000000 -1.000000 1.000000
|
||||
-1.000000 -1.000000 -1.000000
|
||||
vt 14
|
||||
0.625000 0.500000
|
||||
0.875000 0.500000
|
||||
0.875000 0.750000
|
||||
0.625000 0.750000
|
||||
0.375000 0.750000
|
||||
0.625000 1.000000
|
||||
0.375000 1.000000
|
||||
0.375000 0.000000
|
||||
0.625000 0.000000
|
||||
0.625000 0.250000
|
||||
0.375000 0.250000
|
||||
0.125000 0.500000
|
||||
0.375000 0.500000
|
||||
0.125000 0.750000
|
||||
vn 6
|
||||
0.000000 0.000000 1.000000
|
||||
0.000000 -1.000000 0.000000
|
||||
-1.000000 0.000000 0.000000
|
||||
0.000000 0.000000 -1.000000
|
||||
1.000000 0.000000 0.000000
|
||||
0.000000 1.000000 0.000000
|
||||
f 12
|
||||
2 0 0 0 1 0 4 2 0
|
||||
7 3 1 3 4 1 2 3 1
|
||||
5 5 2 7 6 2 6 7 2
|
||||
7 8 3 5 9 3 1 10 3
|
||||
3 11 4 1 12 4 0 4 4
|
||||
1 13 5 5 12 5 4 0 5
|
||||
2 0 0 4 1 0 6 2 0
|
||||
7 3 1 2 4 1 6 3 1
|
||||
5 5 2 6 6 2 4 7 2
|
||||
7 8 3 1 9 3 3 10 3
|
||||
3 11 4 0 12 4 2 4 4
|
||||
1 13 5 4 12 5 0 0 5
|
||||
end
|
@@ -44,6 +44,7 @@ namespace JGL::ShapeCache {
|
||||
inline VRamList* cube_normal_data = nullptr;
|
||||
// Facing straight out.
|
||||
inline VRamList* j2d_default_normal_data = nullptr;
|
||||
inline VRamList* square_origin_topleft_vertex_data = nullptr;
|
||||
void Init();
|
||||
}
|
||||
|
||||
@@ -52,8 +53,8 @@ namespace JGL {
|
||||
using namespace J3ML::LinearAlgebra;
|
||||
using namespace J3ML::Geometry;
|
||||
|
||||
[[nodiscard]] bool Init(const Vector2& window_size, float fovY, float far_plane);
|
||||
void Update(const Vector2& window_size);
|
||||
[[nodiscard]] bool Init(const Vector2i& window_size, float fovY, float far_plane);
|
||||
void Update(const Vector2i& window_size);
|
||||
inline void PurgeFontCache() { JGL::fontCache.purgeCache(); }
|
||||
|
||||
|
||||
@@ -106,6 +107,13 @@ namespace JGL::J2D {
|
||||
void DrawLine(const Color4& color, const Vector2& A, const Vector2& B, float thickness = 1);
|
||||
void DrawLine(const Color4& color, float x1, float y1, float x2, float y2, float thickness = 1);
|
||||
|
||||
/// Plots several line segments defined by a series of points to be connected together.
|
||||
/// @param color A 3-or-4 channel color value. @see classes Color3, Color4.
|
||||
/// @param points pointer to the first point in the list.
|
||||
/// @param point_count the number of points to draw.
|
||||
/// @param thickness The width at which to render the line.
|
||||
void DrawLines(const Color4& color, const Vector2* points, const size_t& point_count, float thickness = 1);
|
||||
|
||||
/// Plots a line segment using a series of points separated by a given distance.
|
||||
/// @param color A 3-or-4 channel color value. @see classes Color3, Color4.
|
||||
/// @param A The starting point of the line segment.
|
||||
|
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
/// Copy one Render Target onto another. Will break if they're not the same size.
|
||||
// TODO support different sizes. If the destination is too small fix it for them but log a warning.
|
||||
static void Blit(const RenderTarget& source, RenderTarget* destination);
|
||||
static void Blit(const RenderTarget& source, RenderTarget* destination, const Vector2i& position = {0, 0});
|
||||
|
||||
/// Plots a single pixel onto a Render Target.
|
||||
/// @param color The color to render.
|
||||
@@ -57,6 +57,12 @@ public:
|
||||
/// @param destination The destination RenderTarget.
|
||||
static void Blit(const Color4& color, const Vector2i& position, RenderTarget* destination);
|
||||
|
||||
/// Blit an input texture onto this render target at the given position.
|
||||
/// @param source Source texture.
|
||||
/// @param destination Render Target to draw on.
|
||||
/// @param position Where in the destination to draw.
|
||||
static void Blit(const Texture* source, RenderTarget* destination, const Vector2i& position = {0, 0});
|
||||
|
||||
/// @returns Whether or not this Render Target created it's Texture.
|
||||
[[nodiscard]] bool OwnsTexture() const;
|
||||
public:
|
||||
@@ -70,10 +76,10 @@ public:
|
||||
[[nodiscard]] bool MSAAEnabled() const;
|
||||
|
||||
/// @returns The JGL texture this Render Target draws on.
|
||||
[[nodiscard]] const Texture* GetJGLTexture() const;
|
||||
[[nodiscard]] const Texture* GetTexture() const;
|
||||
|
||||
/// @returns The OpenGL handle for the texture this Render Target draws on.
|
||||
[[nodiscard]] GLuint GetGLTextureHandle() const;
|
||||
[[nodiscard]] GLuint GetTextureHandle() const;
|
||||
|
||||
/// @returns The OpenGL handle for this Render Target.
|
||||
[[nodiscard]] GLuint GetGLFramebufferObjectHandle() const;
|
||||
@@ -113,4 +119,5 @@ public:
|
||||
/** @note If this Render Target was made with a Texture that already existed
|
||||
* the Texture will not be deleted. */
|
||||
~RenderTarget();
|
||||
|
||||
};
|
@@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
#include <ReImage/Image.h>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include<vector>
|
||||
#include <filesystem>
|
||||
#include <J3ML/LinearAlgebra/Vector2i.hpp>
|
||||
#include <Color3.hpp>
|
||||
#include <Color4.hpp>
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace JGL {
|
||||
using namespace ReImage;
|
||||
enum class TextureFilteringMode : u8 {
|
||||
using J3ML::LinearAlgebra::Vector2i;
|
||||
|
||||
enum class FilteringMode : u8 {
|
||||
NEAREST = 0, // Fastest for 2D, Sometimes causes graphical issues.
|
||||
BILINEAR = 1, // Fast and pretty, The best for 2D.
|
||||
|
||||
@@ -16,42 +17,59 @@ namespace JGL {
|
||||
MIPMAP_TRILINEAR = 4 // The prettiest. Still decent speed. Uses more vram.
|
||||
};
|
||||
|
||||
enum class TextureWrappingMode : u8 {
|
||||
enum class WrappingMode : u8 {
|
||||
REPEAT = 0,
|
||||
MIRRORED_REPEAT = 1,
|
||||
CLAMP_TO_EDGE = 2,
|
||||
CLAMP_TO_BORDER = 3 // Effectively the same as clamp_to_edge
|
||||
};
|
||||
enum class ColorFormat : bool { RGB = false, RGBA = true };
|
||||
class Texture;
|
||||
}
|
||||
|
||||
/// Represents texture data loaded on the GPU. Contains a handle that can be passed to OpenGL draw calls.
|
||||
class Texture {
|
||||
private:
|
||||
void Erase();
|
||||
protected:
|
||||
GLuint texture_handle = 0;
|
||||
Vector2 texture_size = {0, 0};
|
||||
ReImage::TextureFlag texture_flags;
|
||||
ReImage::TextureFormat texture_format;
|
||||
TextureFilteringMode texture_filtering_mode;
|
||||
TextureWrappingMode texture_wrapping_mode;
|
||||
void load(Image* software_texture, const Vector2& size, const TextureFormat& format, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode);
|
||||
public:
|
||||
/// Load a texture from a file,
|
||||
explicit Texture(const std::string& file, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE, const TextureFlag& flags = TextureFlag::INVERT_Y);
|
||||
Texture(Image* software_texture, const Vector2& size, const TextureFormat& format, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode);
|
||||
/* Initialize a texture filled with trash data
|
||||
this is primarily for the RenderTarget */
|
||||
explicit Texture(const Vector2& size);
|
||||
Texture(const Texture& rhs);
|
||||
~Texture();
|
||||
public:
|
||||
[[nodiscard]] GLuint GetGLTextureHandle() const;
|
||||
[[nodiscard]] Vector2 GetDimensions() const;
|
||||
[[nodiscard]] TextureFilteringMode GetFilteringMode() const;
|
||||
[[nodiscard]] TextureWrappingMode GetWrappingMode() const;
|
||||
[[nodiscard]] TextureFlag GetFlags() const;
|
||||
[[nodiscard]] TextureFormat GetFormat() const;
|
||||
[[nodiscard]] std::vector<Color4> GetPixelData() const;
|
||||
};
|
||||
/// TODO handle the case of a texture being loaded that exceeds the max texture size.
|
||||
/// Represents texture data loaded on the GPU. Contains a handle that can be passed to OpenGL draw calls.
|
||||
class JGL::Texture {
|
||||
protected:
|
||||
unsigned int texture_handle = 0;
|
||||
bool invert_y = false;
|
||||
Vector2i size = {0, 0};
|
||||
ColorFormat format = ColorFormat::RGBA;
|
||||
FilteringMode filtering_mode;
|
||||
WrappingMode wrapping_mode;
|
||||
void load(const unsigned char* pixels);
|
||||
std::vector<unsigned char> png(const std::filesystem::path& file);
|
||||
std::vector<unsigned char> bmp(const std::filesystem::path& file);
|
||||
public:
|
||||
/// @returns A handle used to identify this texture.
|
||||
[[nodiscard]] unsigned int GetHandle() const;
|
||||
/// @returns The size of this texture.
|
||||
[[nodiscard]] Vector2i GetDimensions() const;
|
||||
/// @returns The filtering mode this texture is using.
|
||||
[[nodiscard]] FilteringMode GetFilteringMode() const;
|
||||
/// @returns The way this texture behaves when used on geometry of different sizes.
|
||||
[[nodiscard]] WrappingMode GetWrappingMode() const;
|
||||
/// @returns The orientation of this texture in v-ram.
|
||||
/// @note true is right-side-up because OpenGL defaults to upside-down.
|
||||
[[nodiscard]] bool Inverted() const;
|
||||
[[nodiscard]] ColorFormat GetFormat() const;
|
||||
/// @returns The raw pixels this texture is made up of.
|
||||
/// @note This will read-back from the GPU. Slow.
|
||||
[[nodiscard]] std::vector<Color4> GetPixelData() const;
|
||||
public:
|
||||
/// Load a texture from a file,
|
||||
explicit Texture(const std::filesystem::path& file, FilteringMode filtering_mode = FilteringMode::BILINEAR, WrappingMode wrapping_mode = WrappingMode::CLAMP_TO_EDGE, bool invert_y = true);
|
||||
/// Load a texture from raw pixels.
|
||||
Texture(const Color4* pixels, const Vector2i& size, const ColorFormat& format, FilteringMode filtering_mode, WrappingMode wrapping_mode);
|
||||
/// Load a texture from raw pixels.
|
||||
Texture(const Color3* pixels, const Vector2i& size, const ColorFormat& format, FilteringMode filtering_mode, WrappingMode wrapping_mode);
|
||||
/// Construct a Texture Atlas from many different textures.
|
||||
/// @note THIS IS UNFINISHED.
|
||||
Texture(const Texture* textures, const size_t& texture_count);
|
||||
/// Initialize a texture filled with trash data.
|
||||
/// @see RenderTarget
|
||||
explicit Texture(const Vector2i& size);
|
||||
|
||||
}
|
||||
Texture(const Texture& rhs);
|
||||
~Texture();
|
||||
};
|
@@ -93,6 +93,7 @@ public:
|
||||
const std::vector<Normal>& vertex_normals = {}, const std::vector<TextureCoordinate>& texture_coordinates = {});
|
||||
|
||||
static VertexArray LoadWavefrontOBJ(const std::string& file_text);
|
||||
static VertexArray LoadAMO(const std::string& file_text);
|
||||
};
|
||||
|
||||
|
||||
|
70
main.cpp
70
main.cpp
@@ -1,16 +1,17 @@
|
||||
#include <JGL/JGL.h>
|
||||
#include <rewindow/types/window.h>
|
||||
#include <ReWindow/types/Window.h>
|
||||
#include <Colors.hpp>
|
||||
#include <chrono>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <J3ML/Geometry/AABB.hpp>
|
||||
#include <rewindow/logger/logger.h>
|
||||
#include <ReWindow/Logger.h>
|
||||
#include <JGL/types/VertexArray.h>
|
||||
|
||||
using J3ML::LinearAlgebra::Vector2;
|
||||
using namespace JGL::Fonts;
|
||||
using namespace JGL;
|
||||
using JGL::Font;
|
||||
|
||||
float fps = 0.0f;
|
||||
|
||||
@@ -111,13 +112,13 @@ Texture* image;
|
||||
Texture* image_mask;
|
||||
RenderTarget* j2d_render_target;
|
||||
|
||||
class JGLDemoWindow : public ReWindow::RWindow
|
||||
class JGLDemoWindow : public ReWindow::OpenGLWindow
|
||||
{
|
||||
public:
|
||||
void initGL() {
|
||||
camera = new Camera;
|
||||
|
||||
if (!JGL::Init(GetSize(), 75, 100))
|
||||
if (!JGL::Init({ GetSize().x, GetSize().y}, 75, 100))
|
||||
Logger::Fatal("Initialization failed.");
|
||||
|
||||
// Load a custom font.
|
||||
@@ -127,9 +128,9 @@ public:
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(GL_TRUE);
|
||||
image = new Texture("assets/sprites/Re3D.png", TextureFilteringMode::BILINEAR);
|
||||
image = new Texture("assets/sprites/Re3D.png", FilteringMode::BILINEAR);
|
||||
image_mask = new Texture("assets/sprites/alpha_mask_2.png");
|
||||
j2d_render_target = new RenderTarget({540, 540}, {0,0,0,0}, false, MSAA_SAMPLE_RATE::MSAA_NONE);
|
||||
j2d_render_target = new RenderTarget({540, 500}, {0,0,0,0}, false, MSAA_SAMPLE_RATE::MSAA_NONE);
|
||||
|
||||
//Texture::MultiplyByAlphaMask(*image, *image_mask);
|
||||
}
|
||||
@@ -145,7 +146,7 @@ public:
|
||||
pulse++;
|
||||
float dt = GetDeltaTime();
|
||||
|
||||
JGL::Update(GetSize());
|
||||
JGL::Update({ GetSize().x, GetSize().y });
|
||||
|
||||
if (fov_increasing)
|
||||
fov += 0.025;
|
||||
@@ -169,6 +170,7 @@ public:
|
||||
/* if rendering to screen space directly. */
|
||||
auto test_light = PointLight({2,1,2}, {pulse,pulse,pulse, 255}, {pulse, pulse, pulse, 255}, {0,0,0}, 1, 0.1, 0.01);
|
||||
// If a 3D object has transparency. The things you'd like to see through it must be drawn before.
|
||||
|
||||
J3D::Begin();
|
||||
J3D::DrawLine(Colors::Red, {-0.33,-0.125,1}, {-1,-0.125,1});
|
||||
J3D::DrawLine(Colors::Red, {-0.33,-0.125,1}, {-0.33,0.25,1});
|
||||
@@ -182,19 +184,13 @@ public:
|
||||
|
||||
AABB boxes[1] = {{Vector3(-0.2125, -0.2125,0.28750), Vector3(0.2125,0.2125,0.7125)}};
|
||||
J3D::BatchWireframeAABB(Colors::Yellow, boxes, 1, 1);
|
||||
//J3D::WireframeOBB(Colors::Red, {0, 0, 1.5f}, {0.40f, 0.10f, 0.10f}, {0,textAngle.y, 0});
|
||||
//J3D::FillSphere({0,255,0,120}, sphere);
|
||||
|
||||
//J3D::DrawCubicBezierCurve(Colors::Blue, {0,0,0.3}, {0,0,0.5}, {0.2,0,0.3}, {0.2, 0.3, 0.1}, 30);
|
||||
|
||||
//J3D::WireframeIcosahedron(Colors::Green, {0,0,0.5f}, 0.125f, 1.f);
|
||||
J3D::End();
|
||||
|
||||
J2D::Begin(j2d_render_target, true);
|
||||
J2D::FillRect(Colors::Blue, {0,52}, {100,100});
|
||||
J2D::DrawSprite(image, {300, 400}, sprite_radians * 0.10f, {0.5,0.5}, {1, 1}, Colors::White);
|
||||
J2D::DrawMirrorSprite(image, {400, 300}, Direction::Horizontal | Direction::Vertical, sprite_radians, {0.5,0.5}, {1, 1}, Colors::White);
|
||||
J2D::DrawPartialSprite(image, {225, 300}, image->GetDimensions() * 0.25, image->GetDimensions() * 0.75, sprite_radians, {0.5, 0.5}, {1,1}, Colors::White);
|
||||
J2D::DrawPartialSprite(image, Vector2(225, 300), Vector2(image->GetDimensions()) * 0.25, Vector2(image->GetDimensions()) * 0.75, sprite_radians, {0.5, 0.5}, {1,1}, Colors::White);
|
||||
J2D::FillRect(Colors::Pinks::HotPink, {68, 120}, {32, 32});
|
||||
J2D::FillGradientRect(Colors::Red, Colors::Blue, Direction::Diagonal_SWNE, {100,52}, {100,100});
|
||||
J2D::FillRoundedRect(Colors::Red, {200, 52}, {100, 100}, 8, 8);
|
||||
@@ -210,14 +206,12 @@ public:
|
||||
J2D::DrawGradientLine(Colors::Red, Colors::Blue, {105, 375}, {200, 275}, 2);
|
||||
auto result = Jupiteroid.MeasureString("Jupiteroid Font", 16);
|
||||
|
||||
//J2D::FillRect(Colors::Gray, {0, 0}, result);
|
||||
J2D::DrawString(Colors::Green, "Jupteroid Font", 0.f, 0, 1.f, 16, Jupiteroid);
|
||||
J2D::DrawString(Colors::White, "Position: " + std::to_string(camera->position.x) + " " + std::to_string(camera->position.y) + " " + std::to_string(camera->position.z), 0, 16, 1,16, Jupiteroid);
|
||||
J2D::DrawString(Colors::White, "ViewAngle: " + std::to_string(camera->angle.x) + " " + std::to_string(camera->angle.y) + " " + std::to_string(camera->angle.z), 0, 33, 1,16, Jupiteroid);
|
||||
J2D::DrawString(Colors::White, "Framerate: " + std::to_string((int) fps), 0, 48, 1, 16, Jupiteroid);
|
||||
std::array<Vector2, 5> polygon = {Vector2(200, 400), {220, 420}, {220, 430}, {230, 410}, {200, 400}};
|
||||
J2D::OutlinePolygon(Colors::White, polygon.data(), polygon.size());
|
||||
//J2D::FillPolygon(Colors::White, {{200, 400}, {220, 420}, {220, 430}, {230, 410}, {200, 400}});
|
||||
J2D::DrawCubicBezierCurve(Colors::Blues::CornflowerBlue,
|
||||
a.position,
|
||||
b.position,
|
||||
@@ -230,16 +224,10 @@ public:
|
||||
c.Draw();
|
||||
d.Draw();
|
||||
J2D::End();
|
||||
RenderTarget::Blit(Colors::Red, {0, 0}, j2d_render_target);
|
||||
|
||||
//Draw the Render Target that we just drew all that stuff onto.
|
||||
|
||||
J2D::Begin();
|
||||
J2D::DrawPartialRenderTarget(j2d_render_target, {0, 0}, {0,0}, {512, 512});
|
||||
J2D::DrawRenderTarget(j2d_render_target, {0, 0});
|
||||
J2D::DrawSprite(image, image_mask, {0, 0}, 0.25, {0.5, 0.5}, {1,1});
|
||||
//J2D::DrawSprite(, {0, 0}, 0, {0.5, 0.5}, {1,1}, Colors::White);
|
||||
|
||||
//J2D::DrawSprite( {0, 0}, 0, {0.5, 0.5}, {1,1}, Colors::White);
|
||||
J2D::End();
|
||||
|
||||
}
|
||||
@@ -273,15 +261,15 @@ public:
|
||||
|
||||
|
||||
auto mouse = GetMouseCoordinates();
|
||||
a.Update(mouse);
|
||||
b.Update(mouse);
|
||||
c.Update(mouse);
|
||||
d.Update(mouse);
|
||||
a.Update({(float) mouse.x, (float) mouse.y});
|
||||
b.Update({(float) mouse.x, (float) mouse.y});
|
||||
c.Update({(float) mouse.x, (float) mouse.y});
|
||||
d.Update({(float) mouse.x, (float) mouse.y});
|
||||
display();
|
||||
int glError = glGetError();
|
||||
if (glError != GL_NO_ERROR)
|
||||
std::cout << glError << std::endl;
|
||||
GLSwapBuffers();
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
@@ -304,39 +292,37 @@ public:
|
||||
}
|
||||
|
||||
bool OnResizeRequest(const ReWindow::WindowResizeRequestEvent& e) override {return true;}
|
||||
JGLDemoWindow() : ReWindow::RWindow() {}
|
||||
JGLDemoWindow(const std::string& title, int width, int height) : ReWindow::RWindow(title, width, height) {}
|
||||
JGLDemoWindow(const std::string& title, int width, int height) : ReWindow::OpenGLWindow(title, width, height, 2, 1) {}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
auto* window = new JGLDemoWindow("JGL Demo Window", 1280, 720);
|
||||
window->SetRenderer(RenderingAPI::OPENGL);
|
||||
window->Open();
|
||||
if (!window->Open())
|
||||
exit(-1);
|
||||
window->initGL();
|
||||
window->SetResizable(true);
|
||||
window->SetVsyncEnabled(true);
|
||||
window->SetVsyncEnabled(false);
|
||||
|
||||
std::ifstream file("assets/models/cube.obj");
|
||||
std::ifstream file("assets/models/cube.amo");
|
||||
if (!file.is_open())
|
||||
return -1;
|
||||
|
||||
/*
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
std::string file_text = buffer.str();
|
||||
file.close();
|
||||
//std::cout << "File contents:\n" << file_text << std::endl;
|
||||
std::cout << file_text << std::endl;
|
||||
|
||||
auto result = VertexArray::LoadWavefrontOBJ(file_text);
|
||||
auto result = VertexArray::LoadAMO(file_text);
|
||||
*/
|
||||
|
||||
ReWindow::Logger::Error.EnableConsole(false);
|
||||
ReWindow::Logger::Warning.EnableConsole(false);
|
||||
ReWindow::Logger::Debug.EnableConsole(false);
|
||||
//ReWindow::Logger::Error.EnableConsole(false);
|
||||
//ReWindow::Logger::Warning.EnableConsole(false);
|
||||
//ReWindow::Logger::Debug.EnableConsole(false);
|
||||
|
||||
while (window->IsAlive())
|
||||
window->ManagedRefresh();
|
||||
return 0;
|
||||
|
||||
//for (const auto& v3 : result)
|
||||
//std::cout << v3.x << " " << v3.y << " " << v3.z << std::endl;
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
#include "JGL/JGL.h"
|
||||
#include <JGL/JGL.h>
|
||||
|
||||
namespace JGL::Data {
|
||||
unsigned char Jupiteroid_Data[] = {
|
15
src/JGL.cpp
15
src/JGL.cpp
@@ -5,12 +5,12 @@
|
||||
#include <glad/glad.h>
|
||||
#include <JGL/JGL.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
#include "internals/include/internals.h"
|
||||
#include "renderer/OpenGL/internals/internals.h"
|
||||
|
||||
namespace JGL {
|
||||
using namespace J3ML;
|
||||
|
||||
bool Init(const Vector2& window_size, float fovY, float far_plane) {
|
||||
bool Init(const Vector2i& ws, float fovY, float far_plane) {
|
||||
gladLoadGL();
|
||||
if (!MeetsRequirements()) {
|
||||
Logger::Fatal("The graphics driver does not meet the minimum requirements to run this program.");
|
||||
@@ -20,15 +20,18 @@ namespace JGL {
|
||||
InitTextEngine();
|
||||
Fonts::Init();
|
||||
ShapeCache::Init();
|
||||
OpenGLState::window_size = window_size;
|
||||
JGL::window_size = ws;
|
||||
J3D::fov = fovY;
|
||||
J3D::far_plane = far_plane;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Update(const Vector2& window_size) {
|
||||
OpenGLState::window_size = window_size;
|
||||
glViewport(0, 0, (int) window_size.x, (int) window_size.y);
|
||||
void Update(const Vector2i& ws) {
|
||||
if (state_stack.Size())
|
||||
Logger::Error("You shouldn't be running JGL::Update while inside a J2D or J3D context.");
|
||||
|
||||
JGL::window_size = ws;
|
||||
glViewport(0, 0, window_size.x, window_size.y);
|
||||
}
|
||||
|
||||
bool MeetsRequirements() {
|
||||
|
@@ -43,10 +43,13 @@ void JGL::ShapeCache::Init() {
|
||||
if (!cube_index_data)
|
||||
cube_index_data = new VRamList(indices.data(), indices.size());
|
||||
|
||||
if (!cube_normal_data) {
|
||||
if (!cube_normal_data)
|
||||
cube_normal_data = new VRamList(vertex_normals.data(), vertex_normals.size());
|
||||
}
|
||||
|
||||
if (!square_origin_topleft_vertex_data) {
|
||||
std::array<Vector2, 4> square_vertices = { Vector2(0, 0), {1, 0}, {1, -1}, {0, -1} };
|
||||
square_origin_topleft_vertex_data = new VRamList(square_vertices.data(), square_vertices.size());
|
||||
}
|
||||
if (!j2d_default_normal_data) {
|
||||
std::array<GLfloat, 3> normal {0, 0, 1};
|
||||
j2d_default_normal_data = new VRamList(normal.data(), normal.size());
|
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace JGL {
|
||||
class VertexArray;
|
||||
VertexArray LoadWavefrontOBJ(const std::string& file_text);
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
/// Things used in J2D and J3D that should not be exposed to the user of the library.
|
||||
#pragma once
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include "J3ML/LinearAlgebra/Vector2.hpp"
|
||||
#include "JGL/types/RenderTarget.h"
|
||||
#include "JGL/types/Light.h"
|
||||
#include "JGL/logger/logger.h"
|
||||
|
||||
namespace JGL {
|
||||
inline constexpr std::array<const LightBase*, 8> empty_light_array = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
inline bool inJ2D = false;
|
||||
inline bool inJ3D = false;
|
||||
std::vector<Vector3> TriangleMeshVertexNormals(const Vector3* vertices, const size_t& vertex_count, const unsigned int* indices, const size_t& index_count);
|
||||
}
|
||||
|
||||
namespace JGL::OpenGLState {
|
||||
inline JGL::RenderTarget* render_target = nullptr;
|
||||
inline Vector2 window_size;
|
||||
|
||||
inline GLfloat oldColor[4] = {0, 0, 0, 1};
|
||||
inline GLfloat baseColor[4] = {1, 1, 1, 1};
|
||||
|
||||
inline GLuint current_fbo = 0;
|
||||
inline GLint viewport[4] = {0, 0, 0, 0};
|
||||
|
||||
inline bool wasTexture2DEnabled = false;
|
||||
inline bool wasTextureCoordArrayEnabled = false;
|
||||
inline bool wasNormalArrayEnabled = false;
|
||||
|
||||
inline bool wasDepthTestEnabled = false;
|
||||
inline bool wasVertexArraysEnabled = false;
|
||||
inline bool wasCullFaceEnabled = false;
|
||||
inline bool wasBlendEnabled = false;
|
||||
inline bool wasColorArrayEnabled = false;
|
||||
inline GLint activeTextureUnit = 0;
|
||||
}
|
||||
|
||||
namespace JGL::J2D {
|
||||
inline std::array<const LightBase*, 8> required_lights;
|
||||
inline std::vector<const LightBase*> light_array;
|
||||
}
|
||||
|
||||
namespace JGL::J3D {
|
||||
// List of lights required for each objects in the scene. up-to 8. For example, the sun. Or a flash-light.
|
||||
inline std::array<const LightBase*, 8> required_lights;
|
||||
// List of all lights in the scene.
|
||||
inline std::vector<const LightBase*> optional_lights;
|
||||
inline float far_plane = 0;
|
||||
inline float fov = 0;
|
||||
// Enables lighting and selects the correct lights to use.
|
||||
void SelectLights(const Vector3& position);
|
||||
// Resets the GL lights to default and disables them. Then, disables lighting.
|
||||
void ResetLights();
|
||||
[[nodiscard]] bool UsingLighting();
|
||||
|
||||
}
|
@@ -1,176 +1,72 @@
|
||||
#include <JGL/JGL.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <J3ML/Algorithm/Bezier.hpp>
|
||||
#include "../internals/include/internals.h"
|
||||
#include "internals/internals.h"
|
||||
|
||||
void JGL::J2D::Begin(RenderTarget* rt, bool clear_buffers) {
|
||||
GLfloat old_clear_color[4];
|
||||
if (rt != nullptr) {
|
||||
OpenGLState::render_target = rt;
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, old_clear_color);
|
||||
glGetIntegerv(GL_VIEWPORT, OpenGLState::viewport);
|
||||
OpenGLState::current_fbo = JGL::RenderTarget::GetActiveGLFramebufferHandle();
|
||||
JGL::RenderTarget::SetActiveGLRenderTarget(*rt);
|
||||
|
||||
if (!(rt->GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
Logger::Warning("You're rendering onto a texture that is upside-down. Your draw commands won't work how you'd expect.");
|
||||
}
|
||||
void JGL::J2D::Begin(RenderTarget* render_target, bool clear_buffers) {
|
||||
State current_state = default_state;
|
||||
state_stack.Push(State::SaveState());
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
if (rt == nullptr)
|
||||
glViewport(0, 0, (int) OpenGLState::window_size.x, (int) OpenGLState::window_size.y),
|
||||
glOrtho(0, OpenGLState::window_size.x, OpenGLState::window_size.y, 0, -1, 1);
|
||||
else
|
||||
glOrtho(0, rt->GetDimensions().x, rt->GetDimensions().y, 0, -1, 1);
|
||||
if (render_target) {
|
||||
if (!render_target->GetTexture()->Inverted())
|
||||
Logger::Warning("You're rendering onto a texture that is upside-down. Your draw commands won't work how you'd expect.");
|
||||
|
||||
current_state.current_fbo = render_target->GetGLFramebufferObjectHandle();
|
||||
current_state.viewport[2] = render_target->GetDimensions().x;
|
||||
current_state.viewport[3] = render_target->GetDimensions().y;
|
||||
|
||||
current_state.clear_color[0] = render_target->GetClearColor().RN();
|
||||
current_state.clear_color[1] = render_target->GetClearColor().GN();
|
||||
current_state.clear_color[2] = render_target->GetClearColor().BN();
|
||||
current_state.clear_color[3] = render_target->GetClearColor().AN();
|
||||
}
|
||||
else {
|
||||
current_state.viewport[2] = window_size.x;
|
||||
current_state.viewport[3] = window_size.y;
|
||||
}
|
||||
|
||||
State::RestoreState(current_state);
|
||||
if (render_target != nullptr && clear_buffers) {
|
||||
glClearColor(render_target->GetClearColor().RedChannelNormalized(), render_target->GetClearColor().GreenChannelNormalized(), render_target->GetClearColor().BlueChannelNormalized(), render_target->GetClearColor().AlphaChannelNormalized());
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
glOrtho(0, current_state.viewport[2], current_state.viewport[3], 0, -1, 1);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
//Get what the draw color was before we did anything.
|
||||
glGetFloatv(GL_CURRENT_COLOR, OpenGLState::oldColor);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &OpenGLState::activeTextureUnit);
|
||||
OpenGLState::activeTextureUnit = OpenGLState::activeTextureUnit - GL_TEXTURE0;
|
||||
|
||||
if (OpenGLState::activeTextureUnit != 0) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (glIsEnabled(GL_DEPTH_TEST))
|
||||
OpenGLState::wasDepthTestEnabled = true,
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
else
|
||||
OpenGLState::wasDepthTestEnabled = false;
|
||||
|
||||
if (!glIsEnabled(GL_VERTEX_ARRAY))
|
||||
OpenGLState::wasVertexArraysEnabled = false,
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
else
|
||||
OpenGLState::wasVertexArraysEnabled = true;
|
||||
|
||||
if (glIsEnabled(GL_NORMAL_ARRAY))
|
||||
OpenGLState::wasNormalArrayEnabled = true,
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
else
|
||||
OpenGLState::wasNormalArrayEnabled = false;
|
||||
|
||||
if (!glIsEnabled(GL_CULL_FACE))
|
||||
OpenGLState::wasCullFaceEnabled = false,
|
||||
glEnable(GL_CULL_FACE),
|
||||
glCullFace(GL_BACK);
|
||||
else
|
||||
OpenGLState::wasCullFaceEnabled = true;
|
||||
|
||||
if (!glIsEnabled(GL_BLEND))
|
||||
OpenGLState::wasBlendEnabled = false,
|
||||
glEnable(GL_BLEND),
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
else
|
||||
OpenGLState::wasBlendEnabled = true;
|
||||
|
||||
if (glIsEnabled(GL_TEXTURE_2D))
|
||||
OpenGLState::wasTexture2DEnabled = true,
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
|
||||
OpenGLState::wasTextureCoordArrayEnabled = true;
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (glIsEnabled(GL_COLOR_ARRAY))
|
||||
OpenGLState::wasColorArrayEnabled = true,
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
else
|
||||
OpenGLState::wasColorArrayEnabled = false;
|
||||
|
||||
if (!inJ3D)
|
||||
inJ2D = true;
|
||||
else { Logger::Error("Beginning J2D context inside of J3D context?"); }
|
||||
|
||||
if (rt != nullptr && clear_buffers) {
|
||||
glClearColor(rt->GetClearColor().RedChannelNormalized(), rt->GetClearColor().GreenChannelNormalized(), rt->GetClearColor().BlueChannelNormalized(), rt->GetClearColor().AlphaChannelNormalized());
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(old_clear_color[0], old_clear_color[1], old_clear_color[2], old_clear_color[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::J2D::End() {
|
||||
//Change back to the previous projection (The 3D one in Re3D's case.)
|
||||
//Change back to the previous projection.
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
if (OpenGLState::wasDepthTestEnabled)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
if (!OpenGLState::wasVertexArraysEnabled)
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
auto previous_state = state_stack.PreviousState();
|
||||
if (!previous_state)
|
||||
Logger::Fatal("Calling J2D::End before J2D::Begin.");
|
||||
|
||||
if (!OpenGLState::wasCullFaceEnabled)
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (!OpenGLState::wasBlendEnabled)
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
//Select whatever texture mapper was selected before.
|
||||
glActiveTexture(GL_TEXTURE0 + OpenGLState::activeTextureUnit);
|
||||
glClientActiveTexture(GL_TEXTURE0 + OpenGLState::activeTextureUnit);
|
||||
|
||||
if (OpenGLState::wasTexture2DEnabled)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (OpenGLState::wasTextureCoordArrayEnabled)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (OpenGLState::wasNormalArrayEnabled)
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
if (OpenGLState::wasColorArrayEnabled)
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
//Put the draw color back how it was before.
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
|
||||
if (OpenGLState::render_target != nullptr) {
|
||||
OpenGLState::render_target->MSAABlit();
|
||||
OpenGLState::render_target = nullptr;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OpenGLState::current_fbo);
|
||||
glViewport(OpenGLState::viewport[0], OpenGLState::viewport[1], OpenGLState::viewport[2], OpenGLState::viewport[3]);
|
||||
}
|
||||
inJ2D = false;
|
||||
}
|
||||
|
||||
void JGL::J2D::RequiredLight(const JGL::LightBase* light) {
|
||||
bool success = false;
|
||||
for (auto& item : required_lights)
|
||||
if (item == nullptr) {
|
||||
item = light;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
Logger::Error("You cannot specify more than 8 required lights.");
|
||||
}
|
||||
|
||||
void JGL::J2D::OptionalLights(const LightBase** lights, const size_t& light_count) {
|
||||
for (size_t i = 0; i < light_count; i++)
|
||||
light_array.push_back(lights[i]);
|
||||
State::RestoreState(*previous_state);
|
||||
state_stack.Pop();
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawPoint(const Color4& color, const Vector2& coordinates, float radius) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
glPointSize(radius);
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), coordinates.ptr());
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawPoint(const Color4& color, float x, float y, float radius) {
|
||||
@@ -178,7 +74,7 @@ void JGL::J2D::DrawPoint(const Color4& color, float x, float y, float radius) {
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawLine(const Color4& color, const Vector2& A, const Vector2& B, float thickness) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
Vector2 vertices[] = {A, B};
|
||||
|
||||
@@ -186,13 +82,24 @@ void JGL::J2D::DrawLine(const Color4& color, const Vector2& A, const Vector2& B,
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawLine(const Color4& color, float x, float y, float w, float h, float thickness) {
|
||||
JGL::J2D::DrawLine(color, {x, y}, {w, h}, thickness);
|
||||
}
|
||||
|
||||
void J2D::DrawLines(const Color4& color, const Vector2* points, const size_t& point_count, float thickness) {
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
glLineWidth(thickness);
|
||||
glColor3ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), points);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, point_count);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawDottedLine(const Color4& color, const Vector2& A, const Vector2& B, float spacing, float thickness) {
|
||||
float distance = Vector2::Distance(A, B);
|
||||
Vector2 direction = (B - A).Normalized();
|
||||
@@ -243,7 +150,7 @@ void JGL::J2D::DrawDashedLine(const Color4& color, float x1, float y1, float x2,
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawGradientLine(const Color4& color1, const Color4& color2, const Vector2& A, const Vector2& B, float thickness) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {A, B};
|
||||
@@ -256,7 +163,7 @@ void JGL::J2D::DrawGradientLine(const Color4& color1, const Color4& color2, cons
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void DrawGradientLine(const Color4& color1, const Color4& color2, float x, float y, float w, float h, float thickness) {
|
||||
@@ -264,7 +171,7 @@ void DrawGradientLine(const Color4& color1, const Color4& color2, float x, float
|
||||
}
|
||||
|
||||
void JGL::J2D::OutlineRect(const Color4& color, const Vector2& pos, const Vector2& size, float thickness) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {{pos.x, pos.y}, {pos.x, pos.y + size.y}, {pos.x + size.x, pos.y + size.y}, {pos.x + size.x, pos.y}};
|
||||
@@ -273,22 +180,28 @@ void JGL::J2D::OutlineRect(const Color4& color, const Vector2& pos, const Vector
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 4);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillRect(const Color4& color, const Vector2& pos, const Vector2& size) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {{pos.x, pos.y}, {pos.x, pos.y + size.y}, {pos.x + size.x, pos.y + size.y}, {pos.x + size.x, pos.y}};
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ShapeCache::square_origin_topleft_vertex_data->GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), nullptr);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(pos.x, pos.y + size.y, 0);
|
||||
glScalef(size.x, size.y, 1);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glPopMatrix();
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillGradientRect(const Color4& color1, const Color4& color2, const Direction& gradient, const Vector2& pos, const Vector2& size) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {{pos.x, pos.y}, {pos.x, pos.y + size.y}, {pos.x + size.x, pos.y + size.y}, {pos.x + size.x, pos.y}};
|
||||
@@ -317,11 +230,11 @@ void JGL::J2D::FillGradientRect(const Color4& color1, const Color4& color2, cons
|
||||
glColorPointer(4, GL_FLOAT, 0, colors.data());
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillRoundedRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius, unsigned int subdivisions) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
JGL::J2D::FillRect(color, {pos.x + radius, pos.y}, {size.x - 2 * radius, size.y});
|
||||
@@ -384,16 +297,16 @@ void JGL::J2D::DrawSprite(const JGL::RenderTarget& rt, const Vector2& position,
|
||||
|
||||
//Correct for the render-target being upside-down.
|
||||
Direction d{};
|
||||
if (inversion == Direction::None && !(rt.GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
if (inversion == Direction::None && !rt.GetTexture()->Inverted())
|
||||
d = Direction::Vertical;
|
||||
else if (inversion == Direction::Horizontal) {
|
||||
d = Direction::Horizontal;
|
||||
if (!(rt.GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
if (!rt.GetTexture()->Inverted())
|
||||
d = Direction::Horizontal | Direction::Vertical;
|
||||
}
|
||||
else if (inversion& Direction::Horizontal && inversion& Direction::Vertical) {
|
||||
d = Direction::Horizontal;
|
||||
if (!(rt.GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
if (!rt.GetTexture()->Inverted())
|
||||
d = Direction::Horizontal | Direction::Vertical;
|
||||
}
|
||||
|
||||
@@ -401,15 +314,16 @@ void JGL::J2D::DrawSprite(const JGL::RenderTarget& rt, const Vector2& position,
|
||||
if (rt.OwnsTexture())
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
JGL::J2D::DrawPartialSprite(*rt.GetJGLTexture(), position, {0, 0}, Vector2(rt.GetDimensions()), rad_rotation, origin, scale, color, d);
|
||||
auto r_position = Vector2(Math::Floor(position.x), Math::Floor(position.y));
|
||||
JGL::J2D::DrawPartialSprite(*rt.GetTexture(), r_position, {0, 0}, Vector2(rt.GetDimensions()), rad_rotation, origin, scale, color, d);
|
||||
|
||||
if (rt.OwnsTexture())
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawSprite(const Texture& texture, const Texture &alpha_mask, const Vector2& position, float rad_rotation,
|
||||
void JGL::J2D::DrawSprite(const Texture& texture, const Texture& alpha_mask, const Vector2& position, float rad_rotation,
|
||||
const Vector2& origin, const Vector2& scale,const Color4& color, JGL::Direction inversion) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
if (texture.GetDimensions() != alpha_mask.GetDimensions())
|
||||
@@ -417,11 +331,9 @@ void JGL::J2D::DrawSprite(const Texture& texture, const Texture &alpha_mask, con
|
||||
|
||||
const Vector2 size = Vector2(texture.GetDimensions());
|
||||
|
||||
std::array<Vector2, 4> textureCoordinates{};
|
||||
if (texture.GetFlags() & INVERT_Y)
|
||||
std::array<Vector2, 4> textureCoordinates = { Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 0) };
|
||||
if (texture.Inverted())
|
||||
textureCoordinates = {Vector2(0, 1), Vector2(0, 0), Vector2(1, 0), Vector2(1, 1)};
|
||||
else
|
||||
textureCoordinates = {Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 0)};
|
||||
|
||||
// TODO: Kind of a mess, refactor to be more sensible later.
|
||||
// Factors in scaling and origin correctly.
|
||||
@@ -463,7 +375,7 @@ void JGL::J2D::DrawSprite(const Texture& texture, const Texture &alpha_mask, con
|
||||
// Texture 0.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetGLTextureHandle());
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(Vector2), textureCoordinates.data());
|
||||
|
||||
@@ -475,7 +387,7 @@ void JGL::J2D::DrawSprite(const Texture& texture, const Texture &alpha_mask, con
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, alpha_mask.GetGLTextureHandle());
|
||||
glBindTexture(GL_TEXTURE_2D, alpha_mask.GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(Vector2), textureCoordinates.data());
|
||||
|
||||
@@ -485,7 +397,6 @@ void JGL::J2D::DrawSprite(const Texture& texture, const Texture &alpha_mask, con
|
||||
// Reset Texture 1.
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// Reset Texture 0.
|
||||
@@ -495,7 +406,7 @@ void JGL::J2D::DrawSprite(const Texture& texture, const Texture &alpha_mask, con
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawSprite(const Texture* texture, const Texture* alpha_mask, const Vector2& position, float rad_rotation,
|
||||
@@ -518,17 +429,17 @@ void JGL::J2D::DrawPartialRenderTarget(const JGL::RenderTarget& rt, const Vector
|
||||
|
||||
//Correct for the render-target being upside-down.
|
||||
Direction d{};
|
||||
if (inversion == Direction::None && !(rt.GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
if (inversion == Direction::None && !rt.GetTexture()->Inverted())
|
||||
d = Direction::Vertical;
|
||||
|
||||
else if (inversion == Direction::Horizontal) {
|
||||
d = Direction::Horizontal;
|
||||
if (!(rt.GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
if (!rt.GetTexture()->Inverted())
|
||||
d = Direction::Horizontal | Direction::Vertical;
|
||||
}
|
||||
else if (inversion& Direction::Horizontal && inversion& Direction::Vertical) {
|
||||
d = Direction::Horizontal;
|
||||
if (!(rt.GetJGLTexture()->GetFlags() & INVERT_Y))
|
||||
if (!rt.GetTexture()->Inverted())
|
||||
d = Direction::Horizontal | Direction::Vertical;
|
||||
}
|
||||
|
||||
@@ -536,7 +447,10 @@ void JGL::J2D::DrawPartialRenderTarget(const JGL::RenderTarget& rt, const Vector
|
||||
if (rt.OwnsTexture())
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
JGL::J2D::DrawPartialSprite(*rt.GetJGLTexture(), position, sub_texture_position, sub_texture_size, rad_rotation, origin, scale, color, d);
|
||||
auto r_position = Vector2(Math::Floor(position.x), Math::Floor(position.y));
|
||||
auto r_sub_texture_position = Vector2(Math::Floor(sub_texture_position.x), Math::Floor(sub_texture_position.y));
|
||||
|
||||
JGL::J2D::DrawPartialSprite(*rt.GetTexture(), r_position, r_sub_texture_position, sub_texture_size, rad_rotation, origin, scale, color, d);
|
||||
|
||||
if (rt.OwnsTexture())
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -549,14 +463,14 @@ void JGL::J2D::DrawPartialRenderTarget(const JGL::RenderTarget* rt, const Vector
|
||||
|
||||
void JGL::J2D::DrawSprite(const Texture& texture, const Vector2& pos, float rad_rotation, const Vector2& origin,
|
||||
const Vector2& scale, const Color4& color, Direction inversion) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
|
||||
const Vector2 size = Vector2(texture.GetDimensions());
|
||||
|
||||
std::array<Vector2, 4> textureCoordinates{};
|
||||
if (texture.GetFlags() & INVERT_Y)
|
||||
if (texture.Inverted())
|
||||
textureCoordinates = {Vector2(0, 1), Vector2(0, 0), Vector2(1, 0), Vector2(1, 1)};
|
||||
else
|
||||
textureCoordinates = {Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 0)};
|
||||
@@ -598,12 +512,12 @@ void JGL::J2D::DrawSprite(const Texture& texture, const Vector2& pos, float rad_
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glColor4ubv(color.ptr());
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetGLTextureHandle());
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(Vector2), textureCoordinates.data());
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
@@ -622,13 +536,13 @@ void JGL::J2D::DrawSprite(const Texture& texture, float positionX, float positio
|
||||
void JGL::J2D::DrawPartialSprite(const Texture& texture, const Vector2& position, const Vector2& sub_texture_position,
|
||||
const Vector2& sub_texture_size, float rad_rotation, const Vector2& origin,
|
||||
const Vector2& scale, const Color4& color, Direction inversion) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
const Vector2 textureSize = Vector2(texture.GetDimensions());
|
||||
std::array<GLfloat, 8> textureCoordinates{};
|
||||
// Calculate texture coordinates (relative to the whole texture)
|
||||
if (!(texture.GetFlags() & INVERT_Y))
|
||||
if (!texture.Inverted())
|
||||
textureCoordinates = {
|
||||
sub_texture_position.x / textureSize.x,
|
||||
sub_texture_position.y / textureSize.y,
|
||||
@@ -687,12 +601,12 @@ void JGL::J2D::DrawPartialSprite(const Texture& texture, const Vector2& position
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glColor4ubv(color.ptr());
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetGLTextureHandle());
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates.data());
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
@@ -708,20 +622,20 @@ void JGL::J2D::DrawPartialSprite(const JGL::Texture& texture, float positionX, f
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawMirrorSprite(const Texture& texture, const Vector2& position, Direction mirror_axis, float rad_rotation, const Vector2& origin, const Vector2& scale, const Color4& color) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
if (mirror_axis == Direction::None)
|
||||
Logger::Warning("Drawing non-mirrored sprite with JGL::J2D::DrawMirrorSprite?");
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetGLTextureHandle());
|
||||
glBindTexture(GL_TEXTURE_2D, texture.GetHandle());
|
||||
Vector2 size = Vector2(texture.GetDimensions());
|
||||
|
||||
std::array<Vector2, 4> textureCoordinates = {Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 0)};
|
||||
if (mirror_axis == Direction::Horizontal) {
|
||||
size.x *= 2;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
if (texture.GetFlags() & INVERT_Y)
|
||||
if (texture.Inverted())
|
||||
textureCoordinates = {Vector2(0, 1), Vector2(0, 0), Vector2(2, 0), Vector2(2, 1)};
|
||||
else
|
||||
textureCoordinates = {Vector2(0, 0), Vector2(0, 1), Vector2(2, 1), Vector2(2, 0)};
|
||||
@@ -730,7 +644,7 @@ void JGL::J2D::DrawMirrorSprite(const Texture& texture, const Vector2& position,
|
||||
else if (mirror_axis == Direction::Vertical) {
|
||||
size.y *= 2;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
if (texture.GetFlags() & INVERT_Y)
|
||||
if (texture.Inverted())
|
||||
textureCoordinates = {Vector2(0, 2), Vector2(0, 0), Vector2(1, 0), Vector2(1, 2)};
|
||||
else
|
||||
textureCoordinates = {Vector2(0, 0), Vector2(0, 2), Vector2(1, 2), Vector2(1, 0)};
|
||||
@@ -740,7 +654,7 @@ void JGL::J2D::DrawMirrorSprite(const Texture& texture, const Vector2& position,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
size *= 2;
|
||||
if (texture.GetFlags() & INVERT_Y)
|
||||
if (texture.Inverted())
|
||||
textureCoordinates = {Vector2(0, 2), Vector2(0, 0), Vector2(2, 0), Vector2(2, 2)};
|
||||
else
|
||||
textureCoordinates = {Vector2(0, 0), Vector2(0, 2), Vector2(2, 2), Vector2(2, 0)};
|
||||
@@ -775,23 +689,24 @@ void JGL::J2D::DrawMirrorSprite(const Texture& texture, const Vector2& position,
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
|
||||
//Reset the wrapping mode.
|
||||
if (texture.GetWrappingMode() == TextureWrappingMode::CLAMP_TO_EDGE)
|
||||
if (texture.GetWrappingMode() == WrappingMode::CLAMP_TO_EDGE)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
else if (texture.GetWrappingMode() == TextureWrappingMode::REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
else if (texture.GetWrappingMode() == WrappingMode::REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
else if (texture.GetWrappingMode() == TextureWrappingMode::CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
else if (texture.GetWrappingMode() == WrappingMode::CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void JGL::J2D::OutlineCircle(const Color4& color, const Vector2& center, float radius, unsigned int subdivisions, float thickness) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
float step = (2.f * Math::Pi) / (float) subdivisions;
|
||||
@@ -814,11 +729,11 @@ void JGL::J2D::OutlineCircle(const Color4& color, const Vector2& center, float r
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glDrawArrays(GL_LINE_LOOP, 0, (int) vertices.size());
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillCircle(const Color4& color, const Vector2& center, float radius, unsigned int subdivisions) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
GLfloat angle, x, y;
|
||||
@@ -842,11 +757,11 @@ void JGL::J2D::FillCircle(const Color4& color, const Vector2& center, float radi
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, (int) vertices.size());
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::OutlineTriangle(const Color4& color, const Triangle2D& tri, float thickness) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {{tri.A.x, tri.A.y}, {tri.B.x, tri.B.y}, {tri.C.x, tri.C.y}};
|
||||
@@ -855,11 +770,11 @@ void JGL::J2D::OutlineTriangle(const Color4& color, const Triangle2D& tri, float
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 3);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillTriangle(const Color4& color, const Triangle2D& tri) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {{tri.A.x, tri.A.y}, {tri.B.x, tri.B.y}, {tri.C.x, tri.C.y}};
|
||||
@@ -867,11 +782,11 @@ void JGL::J2D::FillTriangle(const Color4& color, const Triangle2D& tri) {
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillGradientTriangle(const Color4& a_color, const Color4& b_color, const Color4& c_color, const Triangle2D& tri) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
Vector2 vertices[] = {{tri.A.x, tri.A.y}, {tri.B.x, tri.B.y}, {tri.C.x, tri.C.y}};
|
||||
@@ -884,7 +799,7 @@ void JGL::J2D::FillGradientTriangle(const Color4& a_color, const Color4& b_color
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
//TODO render all in once pass with GL_LINE_LOOP instead of separate lines.
|
||||
@@ -907,7 +822,7 @@ void JGL::J2D::DrawCubicBezierCurve(const Color4& color, const Vector2& controlA
|
||||
}
|
||||
|
||||
void JGL::J2D::OutlinePolygon(const Color4& color, const Vector2* points, int points_size, float thickness) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
if (points[0] != points[points_size -1])
|
||||
@@ -917,7 +832,7 @@ void JGL::J2D::OutlinePolygon(const Color4& color, const Vector2* points, int po
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), points);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, points_size);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawGradientLine(const Color4& color_a, const Color4& color_b, float x, float y, float w, float h,
|
||||
@@ -927,7 +842,7 @@ void JGL::J2D::DrawGradientLine(const Color4& color_a, const Color4& color_b, fl
|
||||
|
||||
void JGL::J2D::DrawArc(const Color4& color, const Vector2& center, float radius, float arc_begin, float arc_end, unsigned int subdivisions, float thickness)
|
||||
{
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
if (arc_begin == arc_end)
|
||||
@@ -955,7 +870,7 @@ void JGL::J2D::DrawArc(const Color4& color, const Vector2& center, float radius,
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glDrawArrays(GL_LINE_STRIP, 0, (int) vertices.size());
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::OutlineRoundedRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius, float thickness)
|
||||
@@ -1042,7 +957,7 @@ void JGL::J2D::OutlineChamferRect(const Color4& color, const Vector2& pos, const
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 8);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::DrawPoints(const Color4& color, const Vector2* points, int num_points, float radius) {
|
||||
@@ -1050,7 +965,7 @@ void JGL::J2D::DrawPoints(const Color4& color, const Vector2* points, int num_po
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), points);
|
||||
glDrawArrays(GL_POINTS, 0, num_points);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FIllTriangle(const Color4& color, const Vector2& triA, const Vector2& triB, const Vector2& triC) {
|
||||
@@ -1064,7 +979,7 @@ void JGL::J2D::FillGradientTriangle(const Color4& a_color, const Color4& b_color
|
||||
|
||||
void JGL::J2D::OutlineEllipse(const Color4& color, const Vector2& position, float radius_x, float radius_y, float thickness,
|
||||
int subdivisions) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
float step = (2.f * Math::Pi) / (float) subdivisions;
|
||||
@@ -1086,11 +1001,11 @@ void JGL::J2D::OutlineEllipse(const Color4& color, const Vector2& position, floa
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glDrawArrays(GL_LINE_LOOP, 0, (int) vertices.size());
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J2D::FillEllipse(const Color4& color, const Vector2& position, float radius_x, float radius_y, int subdivisions) {
|
||||
if (!inJ2D)
|
||||
if (!state_stack.Size())
|
||||
Logger::Error("Drawing J2D element before J2D begin.");
|
||||
|
||||
GLfloat angle, x, y;
|
||||
@@ -1114,5 +1029,5 @@ void JGL::J2D::FillEllipse(const Color4& color, const Vector2& position, float r
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, (int) vertices.size());
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
}
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
@@ -4,7 +4,7 @@
|
||||
#include <J3ML/Geometry/OBB.hpp>
|
||||
#include <J3ML/Algorithm/Bezier.hpp>
|
||||
#include <JGL/types/Light.h>
|
||||
#include "../internals/include/internals.h"
|
||||
#include "internals/internals.h"
|
||||
|
||||
|
||||
std::array<GLfloat, 16> JGL::OpenGLPerspectiveProjectionRH(float fovY, float aspect, float z_near, float z_far) {
|
||||
@@ -28,7 +28,7 @@ void JGL::J3D::ChangeFarPlane(float far_plane) {
|
||||
|
||||
void JGL::J3D::RequiredLight(const JGL::LightBase* light) {
|
||||
bool success = false;
|
||||
for (auto& i : required_lights)
|
||||
for (auto& i : current_state.required_lights)
|
||||
if (i == nullptr) {
|
||||
i = light;
|
||||
success = true;
|
||||
@@ -41,86 +41,82 @@ void JGL::J3D::RequiredLight(const JGL::LightBase* light) {
|
||||
|
||||
void JGL::J3D::OptionalLights(const JGL::LightBase** lights, const size_t& light_count) {
|
||||
for (size_t i = 0; i < light_count; i++)
|
||||
optional_lights.push_back(lights[i]);
|
||||
current_state.optional_lights.push_back(lights[i]);
|
||||
}
|
||||
|
||||
void JGL::J3D::Begin(bool two_pass) {
|
||||
auto aspect = (float) OpenGLState::window_size.x / (float) OpenGLState::window_size.y;
|
||||
auto aspect = (float) window_size.x / (float) window_size.y;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMultMatrixf(OpenGLPerspectiveProjectionRH(fov, aspect, 0.001, far_plane).data());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
//Get what the draw color was before we did anything.
|
||||
glGetFloatv(GL_CURRENT_COLOR, OpenGLState::oldColor);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glGetFloatv(GL_CURRENT_COLOR, current_state.draw_color);
|
||||
glColor4fv(current_state.draw_color);
|
||||
|
||||
if (!glIsEnabled(GL_DEPTH_TEST))
|
||||
OpenGLState::wasDepthTestEnabled = false,
|
||||
current_state.depth_test = false,
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
OpenGLState::wasDepthTestEnabled = true;
|
||||
current_state.depth_test = true;
|
||||
|
||||
OpenGLState::wasVertexArraysEnabled = false;
|
||||
current_state.vertex_array = false;
|
||||
if (!glIsEnabled(GL_VERTEX_ARRAY))
|
||||
OpenGLState::wasVertexArraysEnabled = false,
|
||||
current_state.vertex_array = false,
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if (glIsEnabled(GL_NORMAL_ARRAY))
|
||||
OpenGLState::wasNormalArrayEnabled = true,
|
||||
current_state.normal_array = true,
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
|
||||
OpenGLState::wasTextureCoordArrayEnabled = true,
|
||||
current_state.texture_coordinate_array = true,
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (glIsEnabled(GL_TEXTURE_2D))
|
||||
OpenGLState::wasTexture2DEnabled = true,
|
||||
current_state.texture_2D = true,
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
OpenGLState::wasCullFaceEnabled = false;
|
||||
current_state.cull_face = false;
|
||||
if (glIsEnabled(GL_CULL_FACE))
|
||||
OpenGLState::wasCullFaceEnabled = true,
|
||||
current_state.cull_face = true,
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (!glIsEnabled(GL_BLEND))
|
||||
OpenGLState::wasBlendEnabled = false,
|
||||
current_state.blend = false,
|
||||
glEnable(GL_BLEND),
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
else
|
||||
OpenGLState::wasBlendEnabled = true;
|
||||
current_state.blend = true;
|
||||
|
||||
// Reset the lights.
|
||||
required_lights = empty_light_array;
|
||||
optional_lights = {};
|
||||
current_state.required_lights = empty_light_array;
|
||||
current_state.optional_lights = {};
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
if (!inJ2D)
|
||||
inJ3D = true;
|
||||
else
|
||||
Logger::Error("Beginning J3D context inside of J2D context?");
|
||||
}
|
||||
|
||||
void JGL::J3D::End() {
|
||||
if (!OpenGLState::wasDepthTestEnabled)
|
||||
if (!current_state.depth_test)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
if (!OpenGLState::wasVertexArraysEnabled)
|
||||
if (!current_state.vertex_array)
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if (OpenGLState::wasTexture2DEnabled)
|
||||
if (current_state.texture_2D)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (!OpenGLState::wasBlendEnabled)
|
||||
if (!current_state.blend)
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
if (OpenGLState::wasCullFaceEnabled)
|
||||
if (current_state.cull_face)
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
if (OpenGLState::wasNormalArrayEnabled)
|
||||
if (current_state.normal_array)
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
if (OpenGLState::wasTextureCoordArrayEnabled)
|
||||
if (current_state.texture_coordinate_array)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (glIsEnabled(GL_LIGHTING)) {
|
||||
@@ -135,25 +131,21 @@ void JGL::J3D::End() {
|
||||
glDisable(GL_LIGHT7);
|
||||
}
|
||||
|
||||
required_lights = empty_light_array;
|
||||
optional_lights = {};
|
||||
current_state.required_lights = empty_light_array;
|
||||
current_state.optional_lights = {};
|
||||
|
||||
//Put the draw color back how it was before.
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
inJ3D = false;
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::DrawLine(const Color4& color, const Vector3& A, const Vector3& B, float thickness) {
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
|
||||
Vector3 vertices[] = {A, B};
|
||||
|
||||
glLineWidth(thickness);
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(Vector3), vertices);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::WireframeSphere(const Color4& color, const Vector3& position, float radius, float thickness, unsigned int sectors, unsigned int stacks) {
|
||||
@@ -166,9 +158,6 @@ void JGL::J3D::WireframeSphere(const Color4& color, const Sphere& sphere, float
|
||||
}
|
||||
|
||||
void JGL::J3D::BatchWireframeSphere(const Color4& color, const Sphere* spheres, const size_t& sphere_count, float thickness, unsigned int sectors, unsigned int stacks) {
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
|
||||
// Create one sphere with a radius of 1 about 0, 0.
|
||||
float r = 1;
|
||||
std::vector<Vector3> vertices((sectors + 1) * (stacks + 1));
|
||||
@@ -204,7 +193,7 @@ void JGL::J3D::BatchWireframeSphere(const Color4& color, const Sphere* spheres,
|
||||
glDrawArrays(GL_LINE_LOOP, 0, vertices.size());
|
||||
glPopMatrix();
|
||||
}
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::WireframeRevoSphere(const Color4& color, const Vector3& position, float radius, float thickness, unsigned int sectors, unsigned int revolutions, bool draw_stacks) {
|
||||
@@ -263,14 +252,10 @@ void JGL::J3D::BatchWireframeRevoSphere(const Color4& color, const Sphere* spher
|
||||
glPopMatrix();
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::WireframeIcosphere(const Color4& color, const Vector3& position, float radius, float thickness,
|
||||
unsigned int subdivisions) {
|
||||
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
void JGL::J3D::WireframeIcosphere(const Color4& color, const Vector3& position, float radius, float thickness, unsigned int subdivisions) {
|
||||
|
||||
// NOTE2SELF: Code i'm borrowing this from uses float-packed-arrays rather than discrete Vectors
|
||||
// working on translating that correctly...
|
||||
@@ -341,9 +326,6 @@ void JGL::J3D::WireframeIcosphere(const Color4& color, const Vector3& position,
|
||||
}
|
||||
|
||||
void JGL::J3D::WireframeIcosahedron(const Color4& color, const Vector3& position, float radius, float thickness) {
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
|
||||
// TODO: Revise this once J3ML::Geometry::Icosahedron is implemented.
|
||||
const float h_angle = J3ML::Math::Pi / 180.f * 72.f; // 72 degree = 360 / 5;
|
||||
const float v_angle = J3ML::Math::Atan(1.0f / 2.f); // elevation = 26.565;
|
||||
@@ -382,7 +364,7 @@ void JGL::J3D::WireframeIcosahedron(const Color4& color, const Vector3& position
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, vertices.size());
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(Vector3), vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::BatchWireframeAABB(const Color4& color, const AABB* boxes, const size_t& box_count, float thickness) {
|
||||
@@ -402,7 +384,7 @@ void JGL::J3D::BatchWireframeAABB(const Color4& color, const AABB* boxes, const
|
||||
glPopMatrix();
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glColor4fv(OpenGLState::baseColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::WireframeAABB(const Color4& color, const Vector3& pos, const Vector3& radii, float thickness) {
|
||||
@@ -411,8 +393,6 @@ void JGL::J3D::WireframeAABB(const Color4& color, const Vector3& pos, const Vect
|
||||
}
|
||||
|
||||
void JGL::J3D::BatchFillAABB(const Color4& color, const AABB* boxes, const size_t& box_count) {
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
glColor4ubv(color.ptr());
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ShapeCache::cube_vertex_data->GetHandle());
|
||||
@@ -444,9 +424,9 @@ void JGL::J3D::BatchFillAABB(const Color4& color, const AABB* boxes, const size_
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
if (using_lights)
|
||||
glDisable(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
void JGL::J3D::FillAABB(const Color4& color, const Vector3& pos, const Vector3& radii) {
|
||||
@@ -463,9 +443,6 @@ void JGL::J3D::FillSphere(const Color4& color, const Sphere& sphere, unsigned in
|
||||
}
|
||||
|
||||
void JGL::J3D::BatchFillSphere(const Color4& color, const Sphere* spheres, const size_t& sphere_count, unsigned int sectors, unsigned int stacks) {
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
|
||||
float r = 1;
|
||||
std::vector<Vector3> vertices((sectors + 1) * (stacks + 1));
|
||||
std::vector<unsigned int> indices; indices.reserve(sectors * stacks * 6);
|
||||
@@ -522,7 +499,7 @@ void JGL::J3D::BatchFillSphere(const Color4& color, const Sphere* spheres, const
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::FillSphere(const Color4& color, const Vector3& position, float radius, unsigned int sectors, unsigned int stacks) {
|
||||
@@ -555,7 +532,7 @@ void JGL::J3D::BatchWireframeOBB(const Color4& color, const OBB* boxes, const si
|
||||
glDrawElements(GL_LINES, indices.size(), GL_UNSIGNED_INT, indices.data());
|
||||
glPopMatrix();
|
||||
}
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
}
|
||||
|
||||
void JGL::J3D::WireframeOBB(const Color4& color, const OBB& obb, float thickness) {
|
||||
@@ -585,8 +562,6 @@ void JGL::J3D::DrawCubicBezierCurve(const Color4& color, const Vector3& controlA
|
||||
}
|
||||
|
||||
void JGL::J3D::DrawVertexArray(const Color4& color, const VertexArray& vertex_array, const Vector3& position) {
|
||||
if (!inJ3D)
|
||||
Logger::Error("Drawing J3D element before J3D begin.");
|
||||
glColor4ubv(color.ptr());
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
@@ -601,7 +576,7 @@ void JGL::J3D::DrawVertexArray(const Color4& color, const VertexArray& vertex_ar
|
||||
|
||||
//glDrawElements(GL_LINES, vertex_array.GetIndices()->GetLength(), GL_UNSIGNED_INT, nullptr);
|
||||
//std::cout << vertex_array.GetVertices()->GetLength() << std::endl;
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include <JGL/JGL.h>
|
||||
#include "../internals/include/internals.h"
|
||||
#include "internals/internals.h"
|
||||
|
||||
|
||||
#if __linux__
|
||||
@@ -158,7 +158,7 @@ namespace JGL {
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(Vector2), texcoords.data());
|
||||
glDrawArrays(GL_TRIANGLES, 0, (int) vertices.size() * 6);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
glColor4fv(default_state.draw_color);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
@@ -244,7 +244,7 @@ namespace JGL {
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor4fv(OpenGLState::oldColor);
|
||||
glColor4fv(current_state.draw_color);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPopMatrix();
|
@@ -1,22 +1,22 @@
|
||||
#include "../include/internals.h"
|
||||
#include "J3ML/LinearAlgebra/Vector4.hpp"
|
||||
#include "JGL/types/Light.h"
|
||||
#include "internals.h"
|
||||
#include <J3ML/LinearAlgebra/Vector4.hpp>
|
||||
#include <JGL/types/Light.h>
|
||||
|
||||
// TODO handle the case that a required light is in the list of optional lights.
|
||||
void JGL::J3D::SelectLights(const Vector3& position) {
|
||||
std::array<const LightBase*, 8> result = required_lights;
|
||||
std::array<const LightBase*, 8> result = current_state.required_lights;
|
||||
|
||||
unsigned int required_light_count = 0;
|
||||
for (const auto& i : result)
|
||||
if (i) required_light_count++;
|
||||
|
||||
// If there is optional lights.
|
||||
if (!optional_lights.empty()) {
|
||||
if (!current_state.optional_lights.empty()) {
|
||||
// The number of lights we need to solve for
|
||||
unsigned int remaining_lights = 8 - required_light_count;
|
||||
|
||||
std::vector<std::pair<float, const LightBase*>> light_influence;
|
||||
for (const auto* light: optional_lights)
|
||||
for (const auto* light: current_state.optional_lights)
|
||||
light_influence.emplace_back(light->GetAttenuationAtPosition(position), light);
|
||||
|
||||
// Sort by biggest influence.
|
||||
@@ -82,11 +82,11 @@ void JGL::J3D::ResetLights() {
|
||||
}
|
||||
|
||||
bool JGL::J3D::UsingLighting() {
|
||||
if (!optional_lights.empty())
|
||||
if (!current_state.optional_lights.empty())
|
||||
return true;
|
||||
|
||||
for (unsigned int i = 0; i < required_lights.size(); i++)
|
||||
if (required_lights[i])
|
||||
for (unsigned int i = 0; i < current_state.required_lights.size(); i++)
|
||||
if (current_state.required_lights[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -117,3 +117,94 @@ std::vector<Vector3> JGL::TriangleMeshVertexNormals(const Vector3* vertices, con
|
||||
|
||||
return normals;
|
||||
}
|
||||
|
||||
void JGL::StateStack::Push(const JGL::State& state) {
|
||||
states.push_back(state);
|
||||
}
|
||||
|
||||
void JGL::StateStack::Pop() {
|
||||
states.pop_back();
|
||||
}
|
||||
|
||||
JGL::State* JGL::StateStack::PreviousState() {
|
||||
if (states.empty())
|
||||
return nullptr;
|
||||
|
||||
return &states.back();
|
||||
}
|
||||
|
||||
JGL::State JGL::State::SaveState() {
|
||||
State result;
|
||||
|
||||
result.depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||
result.vertex_array = glIsEnabled(GL_VERTEX_ARRAY);
|
||||
result.normal_array = glIsEnabled(GL_NORMAL_ARRAY);
|
||||
result.cull_face = glIsEnabled(GL_CULL_FACE);
|
||||
result.blend = glIsEnabled(GL_BLEND);
|
||||
result.texture_2D = glIsEnabled(GL_TEXTURE_2D);
|
||||
result.texture_coordinate_array = glIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
result.color_array = glIsEnabled(GL_COLOR_ARRAY);
|
||||
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &result.selected_texture_unit);
|
||||
result.selected_texture_unit -= GL_TEXTURE0;
|
||||
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, result.clear_color);
|
||||
glGetFloatv(GL_CURRENT_COLOR, result.draw_color);
|
||||
glGetIntegerv(GL_VIEWPORT, result.viewport);
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&result.current_fbo);
|
||||
glGetIntegerv(GL_BLEND_SRC, &result.blend_func[0]);
|
||||
glGetIntegerv(GL_BLEND_DST, &result.blend_func[1]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void JGL::State::RestoreState(const State& state) {
|
||||
if (state.depth_test)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
if (state.vertex_array)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
else
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if (state.normal_array)
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
else
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
if (state.cull_face)
|
||||
glEnable(GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (state.blend)
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + state.selected_texture_unit);
|
||||
glClientActiveTexture(GL_TEXTURE0 + state.selected_texture_unit);
|
||||
|
||||
if (state.texture_2D)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
else
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
if (state.texture_coordinate_array)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
else
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (state.color_array)
|
||||
glEnable(GL_COLOR_ARRAY);
|
||||
else
|
||||
glDisable(GL_COLOR_ARRAY);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, state.current_fbo);
|
||||
glViewport(state.viewport[0], state.viewport[1], state.viewport[2], state.viewport[3]);
|
||||
glClearColor(state.clear_color[0], state.clear_color[1], state.clear_color[2], state.clear_color[3]);
|
||||
glColor4f(state.draw_color[0], state.draw_color[1], state.draw_color[2], state.draw_color[3]);
|
||||
glBlendFunc(state.blend_func[0], state.blend_func[1]);
|
||||
}
|
86
src/renderer/OpenGL/internals/internals.h
Normal file
86
src/renderer/OpenGL/internals/internals.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
#include <JGL/types/RenderTarget.h>
|
||||
#include <JGL/types/Light.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
|
||||
namespace JGL {
|
||||
class State;
|
||||
class StateStack;
|
||||
}
|
||||
|
||||
class JGL::State {
|
||||
public:
|
||||
GLfloat clear_color[4] = {0, 0, 0, 1};
|
||||
GLfloat draw_color[4] = {1, 1, 1, 1};
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
GLint blend_func[2];
|
||||
GLuint current_fbo = 0;
|
||||
|
||||
bool texture_2D = false;
|
||||
bool texture_coordinate_array = false;
|
||||
bool normal_array = false;
|
||||
bool depth_test = false;
|
||||
bool vertex_array = false;
|
||||
bool cull_face = false;
|
||||
bool blend = false;
|
||||
bool color_array = false;
|
||||
GLint selected_texture_unit = 0;
|
||||
// List of lights required for each object in the scene. up-to 8. For example, the sun. Or a flash-light.
|
||||
std::array<const LightBase*, 8> required_lights{};
|
||||
// List of all lights in the scene.
|
||||
std::vector<const LightBase*> optional_lights{};
|
||||
public:
|
||||
static State SaveState();
|
||||
static void RestoreState(const State& state);
|
||||
};
|
||||
|
||||
class JGL::StateStack {
|
||||
private:
|
||||
std::vector<State> states{};
|
||||
public:
|
||||
size_t Size() { return states.size(); }
|
||||
void Push(const State& state);
|
||||
void Pop();
|
||||
State* PreviousState();
|
||||
public:
|
||||
StateStack() = default;
|
||||
~StateStack() = default;
|
||||
};
|
||||
|
||||
namespace JGL {
|
||||
inline constexpr std::array<const LightBase*, 8> empty_light_array = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
std::vector<Vector3> TriangleMeshVertexNormals(const Vector3* vertices, const size_t& vertex_count, const unsigned int* indices, const size_t& index_count);
|
||||
inline StateStack state_stack;
|
||||
inline Vector2i window_size;
|
||||
//inline State current_state;
|
||||
}
|
||||
|
||||
namespace JGL::J2D {
|
||||
inline State default_state
|
||||
{
|
||||
{0, 0, 0, 1},
|
||||
{1, 1, 1, 1},
|
||||
{0, 0, 0, 0},
|
||||
{GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
|
||||
0, false, false,
|
||||
false, false, true, true,
|
||||
true, false, 0,
|
||||
{}, {}
|
||||
};
|
||||
}
|
||||
|
||||
namespace JGL::J3D {
|
||||
inline State current_state;
|
||||
inline float far_plane = 0;
|
||||
inline float fov = 0;
|
||||
// Enables lighting and selects the correct lights to use.
|
||||
void SelectLights(const Vector3& position);
|
||||
// Resets the GL lights to default and disables them. Then, disables lighting.
|
||||
void ResetLights();
|
||||
[[nodiscard]] bool UsingLighting();
|
||||
}
|
@@ -3,12 +3,12 @@
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <stdexcept>
|
||||
|
||||
const JGL::Texture* JGL::RenderTarget::GetJGLTexture() const {
|
||||
const JGL::Texture* JGL::RenderTarget::GetTexture() const {
|
||||
return texture;
|
||||
}
|
||||
|
||||
GLuint JGL::RenderTarget::GetGLTextureHandle() const {
|
||||
return texture->GetGLTextureHandle();
|
||||
GLuint JGL::RenderTarget::GetTextureHandle() const {
|
||||
return texture->GetHandle();
|
||||
}
|
||||
|
||||
GLuint JGL::RenderTarget::GetGLFramebufferObjectHandle() const {
|
||||
@@ -56,6 +56,7 @@ JGL::RenderTarget::RenderTarget(const JGL::Texture* texture, const Color4& clear
|
||||
if (texture->GetDimensions().x < 1 || texture->GetDimensions().y < 1)
|
||||
Logger::Fatal("Creating a render target where the color attachment is empty?");
|
||||
|
||||
this->size = { static_cast<int>(texture->GetDimensions().x), static_cast<int>(texture->GetDimensions().y) };
|
||||
GLuint current_fbo = GetActiveGLFramebufferHandle();
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
@@ -63,7 +64,7 @@ JGL::RenderTarget::RenderTarget(const JGL::Texture* texture, const Color4& clear
|
||||
glGenFramebuffers(1, &framebuffer_object);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object);
|
||||
glViewport(0,0, size.x, size.y);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetGLTextureHandle(), 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetHandle(), 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
throw std::runtime_error("A new framebuffer could not be allocated.");
|
||||
@@ -71,7 +72,6 @@ JGL::RenderTarget::RenderTarget(const JGL::Texture* texture, const Color4& clear
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
this->clear_color = clear_color;
|
||||
this->size = {(int) size.x, (int) size.y};
|
||||
this->texture = texture;
|
||||
texture_created_by_us = false;
|
||||
}
|
||||
@@ -84,22 +84,18 @@ JGL::RenderTarget::RenderTarget(const Vector2i& size, const Color4& clear_color,
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
//Textures behave strangely if they're not square aaaaaaaaaaaaa.
|
||||
unsigned int biggest;
|
||||
if (size.x >= size.y)
|
||||
biggest = size.x;
|
||||
else biggest = size.y;
|
||||
|
||||
texture = new Texture(Vector2(biggest, biggest));
|
||||
texture = new Texture(size);
|
||||
glGenFramebuffers(1, &framebuffer_object);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object);
|
||||
glViewport(0,0, size.x, size.y);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetGLTextureHandle(), 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetHandle(), 0);
|
||||
|
||||
if (use_depth) {
|
||||
GLuint depthBuffer;
|
||||
glGenRenderbuffers(1, &depthBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, biggest, biggest);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x, size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
using_depth = true;
|
||||
@@ -171,18 +167,12 @@ void JGL::RenderTarget::Resize(const Vector2i& new_size) {
|
||||
// Erase it.
|
||||
delete texture;
|
||||
|
||||
unsigned int biggest;
|
||||
if (new_size.x >= new_size.y)
|
||||
biggest = new_size.x;
|
||||
else
|
||||
biggest = new_size.y;
|
||||
|
||||
auto cc = GetClearColor();
|
||||
glClearColor(cc.RedChannelNormalized(), cc.GreenChannelNormalized(), cc.BlueChannelNormalized(), cc.AlphaChannelNormalized());
|
||||
glViewport(0,0, size.x, size.y);
|
||||
|
||||
texture = new Texture(Vector2(biggest, biggest));
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetGLTextureHandle(), 0);
|
||||
texture = new Texture(new_size);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetHandle(), 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
|
||||
glClearColor(old_clear_color[0], old_clear_color[1], old_clear_color[2], old_clear_color[3]);
|
||||
@@ -295,22 +285,22 @@ void JGL::RenderTarget::MSAABlit() const {
|
||||
}
|
||||
|
||||
// Fixes using render targets on a texture that has mipmaps.
|
||||
if (GetJGLTexture()->GetFilteringMode() == TextureFilteringMode::MIPMAP_NEAREST
|
||||
|| GetJGLTexture()->GetFilteringMode() == TextureFilteringMode::MIPMAP_BILINEAR ||
|
||||
GetJGLTexture()->GetFilteringMode() == TextureFilteringMode::MIPMAP_TRILINEAR) {
|
||||
if (GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_NEAREST
|
||||
|| GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_BILINEAR ||
|
||||
GetTexture()->GetFilteringMode() == FilteringMode::MIPMAP_TRILINEAR) {
|
||||
GLint current_texture = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, GetJGLTexture()->GetGLTextureHandle());
|
||||
glBindTexture(GL_TEXTURE_2D, GetTexture()->GetHandle());
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
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?");
|
||||
void JGL::RenderTarget::Blit(const JGL::RenderTarget& source, JGL::RenderTarget* destination, const Vector2i& position) {
|
||||
if (source.GetDimensions().x > destination->GetDimensions().x || source.GetDimensions().y > destination->GetDimensions().y)
|
||||
Logger::Warning("Blitting a Render Target onto another Render Target but the destination Render Target is too small?");
|
||||
|
||||
// Save the GL state.
|
||||
GLuint current_fbo = GetActiveGLFramebufferHandle();
|
||||
@@ -322,7 +312,7 @@ void JGL::RenderTarget::Blit(const JGL::RenderTarget& source, JGL::RenderTarget*
|
||||
// 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);
|
||||
glBlitFramebuffer(0, 0, source.size.x, source.size.y, position.x, position.y, position.x + source.size.x, position.y + source.size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Put the GL state back.
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, current_read_fbo);
|
||||
@@ -330,6 +320,12 @@ void JGL::RenderTarget::Blit(const JGL::RenderTarget& source, JGL::RenderTarget*
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
|
||||
}
|
||||
|
||||
void JGL::RenderTarget::Blit(const Texture* source, RenderTarget* destination, const Vector2i& position) {
|
||||
auto temp = new RenderTarget(source);
|
||||
Blit(*temp, destination);
|
||||
delete temp;
|
||||
}
|
||||
|
||||
// To avoid repeatedly allocating and deallocating.
|
||||
JGL::RenderTarget* pixel = nullptr;
|
||||
void JGL::RenderTarget::Blit(const Color4& color, const Vector2i& position, JGL::RenderTarget* destination) {
|
||||
|
@@ -1,192 +1,274 @@
|
||||
#include <JGL/types/Texture.h>
|
||||
#include <iostream>
|
||||
#include <JGL/types/RenderTarget.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <glad/glad.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace ReImage;
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "internals/stb_image.h"
|
||||
|
||||
namespace JGL
|
||||
{
|
||||
Texture::Texture(const std::string& file, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode, const TextureFlag& flags)
|
||||
{
|
||||
auto* t = new ReImage::Image(file, flags);
|
||||
GLuint previous_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*) &previous_texture);
|
||||
using namespace JGL;
|
||||
|
||||
load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode, wrapping_mode);
|
||||
texture_flags = flags;
|
||||
Texture::Texture(const std::filesystem::path& file, FilteringMode filtering_mode, WrappingMode wrapping_mode, bool invert_y) :
|
||||
invert_y(invert_y), filtering_mode(filtering_mode), wrapping_mode(wrapping_mode) {
|
||||
std::vector<unsigned char> pixels{};
|
||||
|
||||
delete t;
|
||||
std::ifstream ifStream(file, std::ios::in | std::ios::binary);
|
||||
if (!ifStream.is_open())
|
||||
Logger::Fatal("Trying to load a texture from: " + file.string() + "but we couldn't read the file.");
|
||||
|
||||
unsigned char bmpFileHeader[14];
|
||||
|
||||
ifStream.read(reinterpret_cast<char*>(bmpFileHeader), 14);
|
||||
if (bmpFileHeader[0] == 'B' && bmpFileHeader[1] == 'M')
|
||||
pixels = bmp(file);
|
||||
|
||||
//TODO determine if it's a PNG using the file header instead.
|
||||
else if (file.string().ends_with(".png"))
|
||||
pixels = png(file);
|
||||
ifStream.close();
|
||||
|
||||
|
||||
if (invert_y) {
|
||||
unsigned int row_size = size.x * 4;;
|
||||
if (format == ColorFormat::RGB)
|
||||
row_size = size.x * 3;
|
||||
|
||||
std::vector<unsigned char> temp(row_size);
|
||||
for (unsigned int y = 0; y < size.y / 2; ++y) {
|
||||
unsigned char *topRow = &pixels[y * row_size];
|
||||
unsigned char *bottomRow = &pixels[(size.y - y - 1) * row_size];
|
||||
std::copy(bottomRow, bottomRow + row_size, temp.begin());
|
||||
std::copy(topRow, topRow + row_size, bottomRow);
|
||||
std::copy(temp.begin(), temp.end(), topRow);
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture(const Vector2& size) {
|
||||
GLuint previous_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*) &previous_texture);
|
||||
load(pixels.data());
|
||||
}
|
||||
|
||||
glGenTextures(1, &texture_handle);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_handle);
|
||||
//NEAREST
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
//Clamp
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
std::vector<unsigned char> Texture::png(const std::filesystem::path& file) {
|
||||
std::vector<unsigned char> result{};
|
||||
int channels;
|
||||
|
||||
unsigned char* image_data = stbi_load(file.c_str(), &size.x, &size.y, &channels, 0);
|
||||
if (!image_data)
|
||||
Logger::Fatal("Trying to load a texture from: " + file.string() + "but we couldn't read the file.");
|
||||
|
||||
if (channels == 4)
|
||||
format = ColorFormat::RGBA;
|
||||
else if (channels == 3)
|
||||
format = ColorFormat::RGB;
|
||||
|
||||
if (image_data)
|
||||
result.assign(image_data, image_data + size.x * size.y * channels);
|
||||
|
||||
stbi_image_free(image_data);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> Texture::bmp(const std::filesystem::path& file) {
|
||||
std::vector<unsigned char> result{};
|
||||
std::ifstream bmp_file(file, std::ios::in | std::ios::binary);
|
||||
|
||||
unsigned char bmpFileHeader[14];
|
||||
unsigned char bmpInfoHeader[40];
|
||||
|
||||
bmp_file.read(reinterpret_cast<char *>(bmpFileHeader), 14);
|
||||
bmp_file.read(reinterpret_cast<char *>(bmpInfoHeader), 40);
|
||||
|
||||
size.x = bmpInfoHeader[4] + (bmpInfoHeader[5] << 8) + (bmpInfoHeader[6] << 16) + (bmpInfoHeader[7] << 24);
|
||||
size.y = bmpInfoHeader[8] + (bmpInfoHeader[9] << 8) + (bmpInfoHeader[10] << 16) + (bmpInfoHeader[11] << 24);
|
||||
|
||||
int row_padded = (size.x * 3 + 3) & (~3);
|
||||
result.resize(size.x * size.y * 3);
|
||||
|
||||
std::vector<unsigned char> rowData(row_padded);
|
||||
for (int y = size.y - 1; y >= 0; --y) {
|
||||
bmp_file.read(reinterpret_cast<char *>(rowData.data()), row_padded);
|
||||
for (int x = 0; x < size.x; ++x) {
|
||||
result[(y * size.x + x) * 3 + 2] = rowData[x * 3 + 0];
|
||||
result[(y * size.x + x) * 3 + 1] = rowData[x * 3 + 1];
|
||||
result[(y * size.x + x) * 3 + 0] = rowData[x * 3 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
bmp_file.close();
|
||||
format = ColorFormat::RGB;
|
||||
return result;
|
||||
}
|
||||
|
||||
Texture::Texture(const Vector2i& size) : invert_y(true), format(ColorFormat::RGBA), size(size), filtering_mode(FilteringMode::NEAREST), wrapping_mode(WrappingMode::CLAMP_TO_EDGE) {
|
||||
GLuint previous_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*) &previous_texture);
|
||||
|
||||
glGenTextures(1, &texture_handle);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_handle);
|
||||
//NEAREST
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
//Clamp
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, previous_texture);
|
||||
}
|
||||
|
||||
void Texture::load(const unsigned char* pixels) {
|
||||
GLuint previous_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*) &previous_texture);
|
||||
|
||||
glGenTextures(1, &texture_handle);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_handle);
|
||||
|
||||
if (format == ColorFormat::RGBA)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
else if (format == ColorFormat::RGB)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.x, size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
if (wrapping_mode == WrappingMode::CLAMP_TO_EDGE)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int) size.x, (int) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
else if (wrapping_mode == WrappingMode::REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
texture_format = TextureFormat::RGBA;
|
||||
texture_size = size;
|
||||
texture_filtering_mode = TextureFilteringMode::NEAREST;
|
||||
texture_wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE;
|
||||
// Because in vram it'll be right side up.
|
||||
texture_flags = TextureFlag::INVERT_Y;
|
||||
else if (wrapping_mode == WrappingMode::MIRRORED_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, previous_texture);
|
||||
else if (wrapping_mode == WrappingMode::CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
|
||||
if (filtering_mode == FilteringMode::NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
else if (filtering_mode == FilteringMode::BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
else if (filtering_mode == FilteringMode::MIPMAP_NEAREST ||
|
||||
filtering_mode == FilteringMode::MIPMAP_BILINEAR ||
|
||||
filtering_mode == FilteringMode::MIPMAP_TRILINEAR) {
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
|
||||
if (filtering_mode == FilteringMode::MIPMAP_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
else if (filtering_mode == FilteringMode::MIPMAP_BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
else if (filtering_mode == FilteringMode::MIPMAP_TRILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, previous_texture);
|
||||
}
|
||||
|
||||
void Texture::load(Image* software_texture, const Vector2& size, const TextureFormat& format,
|
||||
TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode) {
|
||||
std::vector<Color4> JGL::Texture::GetPixelData() const {
|
||||
GLint current_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
GLuint previous_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*) &previous_texture);
|
||||
|
||||
glGenTextures(1, &texture_handle);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_handle);
|
||||
|
||||
if (format == TextureFormat::RGBA)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int) size.x, (int) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
software_texture->pixel_data.data());
|
||||
|
||||
else if (format == TextureFormat::RGB)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (int) size.x, (int) size.y, 0, GL_RGB, GL_UNSIGNED_BYTE,
|
||||
software_texture->pixel_data.data());
|
||||
|
||||
if (wrapping_mode == TextureWrappingMode::CLAMP_TO_EDGE)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
else if (wrapping_mode == TextureWrappingMode::REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
else if (wrapping_mode == TextureWrappingMode::MIRRORED_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
|
||||
else if (wrapping_mode == TextureWrappingMode::CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
if (filtering_mode == TextureFilteringMode::NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
else if (filtering_mode == TextureFilteringMode::BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
else if (filtering_mode == TextureFilteringMode::MIPMAP_NEAREST ||
|
||||
filtering_mode == TextureFilteringMode::MIPMAP_BILINEAR ||
|
||||
filtering_mode == TextureFilteringMode::MIPMAP_TRILINEAR) {
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
|
||||
if (filtering_mode == TextureFilteringMode::MIPMAP_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
else if (filtering_mode == TextureFilteringMode::MIPMAP_BILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
else if (filtering_mode == TextureFilteringMode::MIPMAP_TRILINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR),
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
texture_size = size;
|
||||
texture_format = format;
|
||||
texture_filtering_mode = filtering_mode;
|
||||
glBindTexture(GL_TEXTURE_2D, previous_texture);
|
||||
}
|
||||
|
||||
std::vector<Color4> JGL::Texture::GetPixelData() const {
|
||||
GLint current_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
std::vector<Color4> result((size_t) (texture_size.x * texture_size.y));
|
||||
glBindTexture(GL_TEXTURE_2D, texture_handle);
|
||||
|
||||
if (texture_format == TextureFormat::RGBA) {
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
|
||||
glBindTexture(GL_TEXTURE_2D, current_texture);
|
||||
return result;
|
||||
}
|
||||
|
||||
//if RGB
|
||||
std::vector<Color3> color3((size_t) (texture_size.x * texture_size.y));
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, color3.data());
|
||||
for (const auto &c: color3)
|
||||
result.emplace_back(c);
|
||||
std::vector<Color4> result((size_t) (size.x * size.y));
|
||||
glBindTexture(GL_TEXTURE_2D, texture_handle);
|
||||
|
||||
if (format == ColorFormat::RGBA) {
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
|
||||
glBindTexture(GL_TEXTURE_2D, current_texture);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Texture::Erase() {
|
||||
if (texture_handle != 0)
|
||||
glDeleteTextures(1, &texture_handle);
|
||||
texture_handle = 0;
|
||||
//if RGB
|
||||
std::vector<Color3> color3((size_t) (size.x * size.y));
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, color3.data());
|
||||
for (const auto &c: color3)
|
||||
result.emplace_back(c);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, current_texture);
|
||||
return result;
|
||||
}
|
||||
|
||||
GLuint Texture::GetHandle() const {
|
||||
return texture_handle;
|
||||
}
|
||||
|
||||
Vector2i Texture::GetDimensions() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Texture::Inverted() const {
|
||||
return invert_y;
|
||||
}
|
||||
|
||||
ColorFormat Texture::GetFormat() const {
|
||||
return format;
|
||||
}
|
||||
|
||||
FilteringMode Texture::GetFilteringMode() const {
|
||||
return filtering_mode;
|
||||
}
|
||||
|
||||
WrappingMode Texture::GetWrappingMode() const {
|
||||
return wrapping_mode;
|
||||
}
|
||||
|
||||
Texture::Texture(const Color4* pixels, const Vector2i& size, const ColorFormat& format, FilteringMode filtering_mode, WrappingMode wrapping_mode) :
|
||||
size(size), format(format), filtering_mode(filtering_mode), wrapping_mode(wrapping_mode) {
|
||||
load((unsigned char*) pixels);
|
||||
}
|
||||
|
||||
Texture::Texture(const Color3* pixels, const Vector2i& size, const ColorFormat& format, FilteringMode filtering_mode, WrappingMode wrapping_mode) :
|
||||
size(size), format(format), filtering_mode(filtering_mode), wrapping_mode(wrapping_mode) {
|
||||
load((unsigned char*) pixels);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (texture_handle != 0)
|
||||
glDeleteTextures(1, &texture_handle);
|
||||
texture_handle = 0;
|
||||
}
|
||||
|
||||
Texture::Texture(const Texture& rhs) {
|
||||
auto* this_texture = new Texture(rhs.GetDimensions());
|
||||
auto this_render_target = RenderTarget(this_texture);
|
||||
auto rhs_render_target = RenderTarget(&rhs);
|
||||
|
||||
RenderTarget::Blit(rhs_render_target, &this_render_target);
|
||||
|
||||
this->texture_handle = this_texture->texture_handle;
|
||||
this->size = this_texture->size;
|
||||
this->invert_y = this_texture->invert_y;
|
||||
this->format = this_texture->format;
|
||||
this->filtering_mode = this_texture->filtering_mode;
|
||||
this->wrapping_mode = this_texture->wrapping_mode;
|
||||
operator delete(this_texture);
|
||||
}
|
||||
|
||||
Texture::Texture(const Texture* textures, const size_t& texture_count) {
|
||||
int length = 0;
|
||||
int biggest_y = 0;
|
||||
|
||||
for (int i = 0; i < texture_count; i++) {
|
||||
if (biggest_y < textures[i].size.y)
|
||||
biggest_y = textures[i].size.y;
|
||||
length += textures[i].size.x;
|
||||
}
|
||||
|
||||
GLuint Texture::GetGLTextureHandle() const {
|
||||
return texture_handle;
|
||||
auto* result = new Texture(Vector2i(length, biggest_y));
|
||||
auto render_target = RenderTarget(result);
|
||||
|
||||
int next_x = 0;
|
||||
for (int i = 0; i < texture_count; i++) {
|
||||
RenderTarget::Blit(&textures[i], &render_target, Vector2i(next_x, 0));
|
||||
next_x += textures[i].GetDimensions().x;
|
||||
}
|
||||
|
||||
Vector2 Texture::GetDimensions() const {
|
||||
return texture_size;
|
||||
}
|
||||
|
||||
TextureFlag Texture::GetFlags() const {
|
||||
return texture_flags;
|
||||
}
|
||||
|
||||
TextureFormat Texture::GetFormat() const {
|
||||
return texture_format;
|
||||
}
|
||||
|
||||
TextureFilteringMode Texture::GetFilteringMode() const {
|
||||
return texture_filtering_mode;
|
||||
}
|
||||
|
||||
TextureWrappingMode Texture::GetWrappingMode() const {
|
||||
return texture_wrapping_mode;
|
||||
}
|
||||
|
||||
Texture::Texture(Image* software_texture, const Vector2& size, const TextureFormat& format,
|
||||
TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode) {
|
||||
load(software_texture, size, format, filtering_mode, wrapping_mode);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
Erase();
|
||||
}
|
||||
|
||||
Texture::Texture(const Texture& rhs) {
|
||||
auto* this_texture = new Texture(rhs.GetDimensions());
|
||||
auto this_render_target = RenderTarget(this);
|
||||
auto rhs_render_target = RenderTarget(&rhs);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#include <JGL/types/VertexArray.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
#include "../internals/include/WavefrontOBJ.h"
|
||||
|
||||
using namespace JGL;
|
||||
|
||||
@@ -178,7 +177,3 @@ VertexArray::VertexArray(const std::vector<Vertex>& vertex_positions, const std:
|
||||
bool VertexArray::Static() {
|
||||
return animations.empty();
|
||||
}
|
||||
|
||||
VertexArray VertexArray::LoadWavefrontOBJ(const std::string& file_text) {
|
||||
return JGL::LoadWavefrontOBJ(file_text);
|
||||
}
|
||||
|
7988
src/types/internals/stb_image.h
Normal file
7988
src/types/internals/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,3 @@
|
||||
#include "../include/WavefrontOBJ.h"
|
||||
#include <JGL/types/VertexArray.h>
|
||||
#include <JGL/logger/logger.h>
|
||||
|
||||
@@ -61,7 +60,19 @@ std::pair<Vector3, unsigned long> ParseVector3(const std::string& file_text, con
|
||||
return {Vector3(x_result.first, y_result.first, z_result.first), z_result.second + 1};
|
||||
}
|
||||
|
||||
std::pair<std::array<Vector3, 3>, unsigned long> ParseFaceData(const std::string& file_text, const unsigned long& offset) {
|
||||
std::pair<Vector4, unsigned long> ParseVector4(const std::string& file_text, const unsigned long& offset) {
|
||||
auto x_result = ParseNumber(file_text, offset);
|
||||
auto y_result = ParseNumber(file_text, x_result.second + 1);
|
||||
auto z_result = ParseNumber(file_text, y_result.second + 1);
|
||||
auto w_result = ParseNumber(file_text, z_result.second + 1);
|
||||
|
||||
if (x_result.second == offset || y_result.second == x_result.second || z_result.second == y_result.second || w_result.second == z_result.second)
|
||||
return {Vector4(0, 0, 0, 0), offset};
|
||||
|
||||
return {Vector4(x_result.first, y_result.first, z_result.first, w_result.first), w_result.second + 1};
|
||||
}
|
||||
|
||||
std::pair<std::array<Vector3, 3>, unsigned long> ParseWavefrontFaceData(const std::string& file_text, const unsigned long& offset) {
|
||||
unsigned long new_offset = offset;
|
||||
std::array<Vector3, 3> face_data;
|
||||
|
||||
@@ -103,7 +114,7 @@ std::pair<std::array<Vector3, 3>, unsigned long> ParseFaceData(const std::string
|
||||
return {face_data, new_offset};
|
||||
}
|
||||
|
||||
VertexArray JGL::LoadWavefrontOBJ(const std::string &file_text) {
|
||||
VertexArray VertexArray::LoadWavefrontOBJ(const std::string &file_text) {
|
||||
std::vector<std::array<Vector3, 3>> faceline_data;
|
||||
|
||||
std::vector<TextureCoordinate> temp_uvs;
|
||||
@@ -111,7 +122,6 @@ VertexArray JGL::LoadWavefrontOBJ(const std::string &file_text) {
|
||||
std::vector<Vertex> temp_vertices;
|
||||
|
||||
unsigned long offset = 0;
|
||||
|
||||
while (offset < file_text.size()) {
|
||||
char c = file_text[offset];
|
||||
|
||||
@@ -161,7 +171,7 @@ VertexArray JGL::LoadWavefrontOBJ(const std::string &file_text) {
|
||||
else if (c == 'f' && offset + 1 < file_text.size() && file_text[offset + 1] == ' ') {
|
||||
offset += 2;
|
||||
|
||||
auto faceline_result = ParseFaceData(file_text, offset);
|
||||
auto faceline_result = ParseWavefrontFaceData(file_text, offset);
|
||||
if (faceline_result.second != offset) {
|
||||
faceline_data.push_back(faceline_result.first);
|
||||
offset = faceline_result.second;
|
||||
@@ -200,4 +210,125 @@ VertexArray JGL::LoadWavefrontOBJ(const std::string &file_text) {
|
||||
final_indices.data(), final_indices.size(),
|
||||
final_normals.data(), final_normals.size(),
|
||||
final_uvs.data(), final_uvs.size());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
VertexArray JGL::LoadAMO(const std::string& file_text) {
|
||||
std::vector<Vector3> temp_vertices;
|
||||
std::vector<Vector3> temp_normals;
|
||||
std::vector<Vector2> temp_uvs;
|
||||
std::vector<std::array<Vector3, 3>> faceline_data;
|
||||
std::string name;
|
||||
|
||||
unsigned long offset = 0;
|
||||
while (offset < file_text.size()) {
|
||||
char c = file_text[offset];
|
||||
|
||||
// If we've dropped on a newline character somehow then just skip passed it.
|
||||
if (c == '\n' || c == '\r') {
|
||||
offset++; continue;
|
||||
}
|
||||
|
||||
// File name.
|
||||
else if (offset + 2 < file_text.size() && c == 'a' && file_text[offset + 1] == 'o' && file_text[offset + 2] == ' ') {
|
||||
offset += 3;
|
||||
while (offset < file_text.size()) {
|
||||
if (file_text[offset] != '\n' && file_text[offset] != '\r')
|
||||
name.push_back(file_text[offset]), offset++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertices
|
||||
else if (offset + 1 < file_text.size() && c == 'v' && file_text[offset + 1] == ' ') {
|
||||
offset += 2; auto parsed_number = ParseNumber(file_text, offset);
|
||||
|
||||
if (parsed_number.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the Vertex count at: " + std::to_string(offset));
|
||||
|
||||
unsigned long vertex_count = parsed_number.first;
|
||||
offset = parsed_number.second;
|
||||
|
||||
for (unsigned long i = 0; i < vertex_count; i++) {
|
||||
// Skip by newlines.
|
||||
while (file_text[offset] == '\n' || file_text[offset] == '\r')
|
||||
offset++;
|
||||
|
||||
auto parsed_vector3 = ParseVector3(file_text, offset);
|
||||
if (parsed_vector3.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the Vertex at: " + std::to_string(offset));
|
||||
|
||||
temp_vertices.push_back(parsed_vector3.first);
|
||||
offset = parsed_vector3.second;
|
||||
}
|
||||
}
|
||||
|
||||
// UVs
|
||||
else if (offset + 2 < file_text.size() && c == 'v' && file_text[offset + 1] == 't' && file_text[offset + 2] == ' ') {
|
||||
offset += 3; auto parsed_number = ParseNumber(file_text, offset);
|
||||
|
||||
if (parsed_number.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the UV count at: " + std::to_string(offset));
|
||||
|
||||
unsigned long uv_count = parsed_number.first;
|
||||
offset = parsed_number.second;
|
||||
|
||||
for (unsigned long i = 0; i < uv_count; i++) {
|
||||
// Skip by newlines.
|
||||
while (file_text[offset] == '\n' || file_text[offset] == '\r')
|
||||
offset++;
|
||||
|
||||
auto parsed_vector2 = ParseVector2(file_text, offset);
|
||||
if (parsed_vector2.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the UV at: " + std::to_string(offset));
|
||||
|
||||
temp_uvs.push_back(parsed_vector2.first);
|
||||
offset = parsed_vector2.second;
|
||||
}
|
||||
}
|
||||
|
||||
// Normals
|
||||
else if (offset + 2 < file_text.size() && c == 'v' && file_text[offset + 1] == 'n' && file_text[offset + 2] == ' ') {
|
||||
offset += 3; auto parsed_number = ParseNumber(file_text, offset);
|
||||
|
||||
if (parsed_number.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the Normal count at: " + std::to_string(offset));
|
||||
|
||||
unsigned long uv_count = parsed_number.first;
|
||||
offset = parsed_number.second;
|
||||
|
||||
for (unsigned long i = 0; i < uv_count; i++) {
|
||||
// Skip by newlines.
|
||||
while (file_text[offset] == '\n' || file_text[offset] == '\r')
|
||||
offset++;
|
||||
|
||||
auto parsed_vector3 = ParseVector3(file_text, offset);
|
||||
if (parsed_vector3.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the Normal at: " + std::to_string(offset));
|
||||
|
||||
temp_normals.push_back(parsed_vector3.first);
|
||||
offset = parsed_vector3.second;
|
||||
}
|
||||
}
|
||||
|
||||
// Face Lines
|
||||
else if (offset + 1 < file_text.size() && c == 'f' && file_text[offset + 1] == ' ') {
|
||||
offset += 2; auto parsed_number = ParseNumber(file_text, offset);
|
||||
|
||||
if (parsed_number.second == offset)
|
||||
Logger::Fatal("We couldn't interpret the Face Line count at: " + std::to_string(offset));
|
||||
|
||||
unsigned long faceline_count = parsed_number.first;
|
||||
for (unsigned long i = 0; i < faceline_count; i++) {
|
||||
// Skip by newlines.
|
||||
while (file_text[offset] == '\n' || file_text[offset] == '\r')
|
||||
offset++;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
Reference in New Issue
Block a user