diff --git a/AGE/include/Age/Age.h b/AGE/include/Age/Age.h index e3f1a0e..bc3703f 100644 --- a/AGE/include/Age/Age.h +++ b/AGE/include/Age/Age.h @@ -31,6 +31,7 @@ #include "Age/Renderer/Buffer.h" #include "Age/Renderer/Shader.h" #include "Age/Renderer/Texture.h" +#include "Age/Renderer/SubTexture2D.h" #include "Age/Renderer/Context.h" #include "Age/Renderer/OrthographicCamera.h" #include "Age/Renderer/OrthographicCameraController.h" diff --git a/AGE/src/Age/Core/Core.h b/AGE/src/Age/Core/Core.h index 05c16ff..11c7df4 100644 --- a/AGE/src/Age/Core/Core.h +++ b/AGE/src/Age/Core/Core.h @@ -40,6 +40,11 @@ namespace AGE { template using Ref = std::shared_ptr; + template + constexpr Ref MakeRef(Args&& ... args) { + return std::make_shared(std::forward(args)...); + } + template using Scope = std::unique_ptr; } diff --git a/AGE/src/Age/Renderer/OrthographicCameraController.cpp b/AGE/src/Age/Renderer/OrthographicCameraController.cpp index 5ecf9d0..981b61c 100644 --- a/AGE/src/Age/Renderer/OrthographicCameraController.cpp +++ b/AGE/src/Age/Renderer/OrthographicCameraController.cpp @@ -72,9 +72,7 @@ namespace AGE { AGE_PROFILE_FUNCTION(); m_AspectRatio = width / height; - m_Camera.SetProjection( - -m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel - ); + CalculateView(); } bool OrthographicCameraController::OnMouseScrolled(MouseScrolledEvent& e) { @@ -82,8 +80,7 @@ namespace AGE { m_ZoomLevel -= e.YOffset() * 0.25f; m_ZoomLevel = std::max(m_ZoomLevel, 0.25f); - m_Bounds = {-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel}; - m_Camera.SetProjection(m_Bounds.Left, m_Bounds.Right, m_Bounds.Bottom, m_Bounds.Top); + CalculateView(); return false; } @@ -93,4 +90,14 @@ namespace AGE { OnResize((float)e.Width(), (float)e.Height()); return false; } + + void OrthographicCameraController::SetZoomLevel(float level) { + m_ZoomLevel = level; + CalculateView(); + } + + void OrthographicCameraController::CalculateView() { + m_Bounds = {-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel}; + m_Camera.SetProjection(m_Bounds.Left, m_Bounds.Right, m_Bounds.Bottom, m_Bounds.Top); + } } // AGE diff --git a/AGE/src/Age/Renderer/OrthographicCameraController.h b/AGE/src/Age/Renderer/OrthographicCameraController.h index 9c39def..5802936 100644 --- a/AGE/src/Age/Renderer/OrthographicCameraController.h +++ b/AGE/src/Age/Renderer/OrthographicCameraController.h @@ -32,12 +32,13 @@ namespace AGE { void OnEvent(Event& e); void OnResize(float width, float height); + void CalculateView(); OrthographicCamera& GetCamera() { return m_Camera; } const OrthographicCamera& GetCamera() const { return m_Camera; } float ZoomLevel() const { return m_ZoomLevel; } - void SetZoomLevel(float level) { m_ZoomLevel = level; } + void SetZoomLevel(float level); [[nodiscard]] inline CameraBounds Bounds() const { return m_Bounds; } private: diff --git a/AGE/src/Age/Renderer/Renderer2D.cpp b/AGE/src/Age/Renderer/Renderer2D.cpp index 10cb6a5..07594fe 100644 --- a/AGE/src/Age/Renderer/Renderer2D.cpp +++ b/AGE/src/Age/Renderer/Renderer2D.cpp @@ -34,7 +34,7 @@ namespace AGE { uint32_t QuadIndexCount = 0; - std::array, MaxTextureSlots> TextureSlots; + std::array, MaxTextureSlots> TextureSlots{UnitTexture}; uint32_t TextureSlotIndex = 1; //0 - Unit Texture; glm::vec4 QuadVertexPositions[4]; @@ -161,39 +161,39 @@ namespace AGE { void Renderer2D::DrawQuad(const glm::vec3& pos, const glm::vec2& size, const glm::vec4& color) { AGE_PROFILE_FUNCTION(); - DrawQuad(pos, size, nullptr, color); + DrawQuad(pos, size, s_Data.UnitTexture, color); } void Renderer2D::DrawQuad( const glm::vec2& pos, const glm::vec2& size, const Ref& texture, - const float tillingFactor + const float tilingFactor ) { AGE_PROFILE_FUNCTION(); - DrawQuad(glm::vec3(pos, 0.0f), size, texture, tillingFactor); + DrawQuad(glm::vec3(pos, 0.0f), size, texture, tilingFactor); } void Renderer2D::DrawQuad( const glm::vec3& pos, const glm::vec2& size, const Ref& texture, - const float tillingFactor + const float tilingFactor ) { AGE_PROFILE_FUNCTION(); - DrawQuad(pos, size, texture, glm::vec4(1.0f), tillingFactor); + DrawQuad(pos, size, texture, glm::vec4(1.0f), tilingFactor); } void Renderer2D::DrawQuad( const glm::vec2& pos, const glm::vec2& size, const Ref& texture, - const glm::vec4& color + const glm::vec4& color, float tilingFactor ) { AGE_PROFILE_FUNCTION(); - DrawQuad(glm::vec3(pos, 0.0f), size, texture, color); + DrawQuad(glm::vec3(pos, 0.0f), size, texture, color, tilingFactor); } void Renderer2D::DrawQuad( const glm::vec3& pos, const glm::vec2& size, const Ref& texture, - const glm::vec4& color, const float tillingFactor + const glm::vec4& color, const float tilingFactor ) { AGE_PROFILE_FUNCTION(); @@ -213,36 +213,105 @@ namespace AGE { *s_Data.QuadVertexBufferPtr = QuadVertex{ {pos.x - halfSize.x, pos.y + halfSize.y, pos.z}, vertexColor, - {1.0f, 1.0f}, + {0.0f, 1.0f}, (float)textureIndex, - tillingFactor + tilingFactor }; s_Data.QuadVertexBufferPtr++; *s_Data.QuadVertexBufferPtr = QuadVertex{ {pos.x + halfSize.x, pos.y + halfSize.y, pos.z}, vertexColor, - {0.0f, 1.0f}, + {1.0f, 1.0f}, (float)textureIndex, - tillingFactor + tilingFactor }; s_Data.QuadVertexBufferPtr++; *s_Data.QuadVertexBufferPtr = QuadVertex{ {pos.x + halfSize.x, pos.y - halfSize.y, pos.z}, vertexColor, + {1.0f, 0.0f}, + (float)textureIndex, + tilingFactor + }; + s_Data.QuadVertexBufferPtr++; + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + {pos.x - halfSize.x, pos.y - halfSize.y, pos.z}, + vertexColor, {0.0f, 0.0f}, (float)textureIndex, - tillingFactor + tilingFactor + }; + s_Data.QuadVertexBufferPtr++; + + s_Data.QuadIndexCount += 6; + s_Data.Stats.QuadCount++; + } + + void Renderer2D::DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref & subTexture, float tilingFactor) { + DrawQuad(glm::vec3{pos, 0.0f}, size, subTexture, glm::vec4{1.0f}, tilingFactor); + } + + void Renderer2D::DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref & subTexture, float tilingFactor) { + DrawQuad(pos, size, subTexture, glm::vec4{1.0f}, tilingFactor); + } + + void Renderer2D::DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref & subTexture, const glm::vec4& color, float tilingFactor) { + DrawQuad(glm::vec3{pos, 0.0f}, size, subTexture, color, tilingFactor); + } + + void Renderer2D::DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref & subTexture, const glm::vec4& color, float tilingFactor) { + auto texture = subTexture->GetTexture(); + + int textureIndex = FindTextureIndex(texture); + + // Reset color to white if texture is corrupted to properly display error texture + glm::vec4 vertexColor{color}; + if (texture && !texture->IsCorrect()) { + vertexColor = {1.0f, 1.0f, 1.0f, 1.0f}; + } + + if (s_Data.QuadIndexCount >= s_Data.MaxIndices) + NextBatch(); + + glm::vec2 halfSize{size * 0.5f}; + const glm::vec2* texCoords = subTexture->TexCoords(); + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + {pos.x - halfSize.x, pos.y + halfSize.y, pos.z}, + vertexColor, + texCoords[0], + (float)textureIndex, + tilingFactor + }; + s_Data.QuadVertexBufferPtr++; + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + {pos.x + halfSize.x, pos.y + halfSize.y, pos.z}, + vertexColor, + texCoords[1], + (float)textureIndex, + tilingFactor + }; + s_Data.QuadVertexBufferPtr++; + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + {pos.x + halfSize.x, pos.y - halfSize.y, pos.z}, + vertexColor, + texCoords[2], + (float)textureIndex, + tilingFactor }; s_Data.QuadVertexBufferPtr++; *s_Data.QuadVertexBufferPtr = QuadVertex{ {pos.x - halfSize.x, pos.y - halfSize.y, pos.z}, vertexColor, - {1.0f, 0.0f}, + texCoords[3], (float)textureIndex, - tillingFactor + tilingFactor }; s_Data.QuadVertexBufferPtr++; @@ -251,7 +320,7 @@ namespace AGE { } int Renderer2D::FindTextureIndex(const Ref& texture) { - int textureIndex = 0; + int textureIndex = -1; if (texture != nullptr) { for (int i{0}; i < s_Data.TextureSlotIndex; i++) { @@ -261,7 +330,7 @@ namespace AGE { } } - if (textureIndex == 0) { + if (textureIndex == -1) { textureIndex = (int)s_Data.TextureSlotIndex; s_Data.TextureSlots[textureIndex] = texture; s_Data.TextureSlotIndex++; @@ -279,23 +348,23 @@ namespace AGE { // ///////////////////////////////////////////////////////////////////////////////////////////////// void Renderer2D::DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, const float rotationDeg, const glm::vec4& color) { - DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, nullptr, color, 1.0f); + DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, s_Data.UnitTexture, color, 1.0f); } void Renderer2D::DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, const float rotationDeg, const glm::vec4& color) { - DrawRotatedQuad(pos, size, rotationDeg, nullptr, color, 1.0f); + DrawRotatedQuad(pos, size, rotationDeg, s_Data.UnitTexture, color, 1.0f); } - void Renderer2D::DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, const float rotationDeg, const Ref& texture, float tillingFactor) { - DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, nullptr, glm::vec4{1.0f}, 1.0f); + void Renderer2D::DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, const float rotationDeg, const Ref& texture, float tilingFactor) { + DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, s_Data.UnitTexture, glm::vec4{1.0f}, 1.0f); } - void Renderer2D::DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, const float rotationDeg, const Ref& texture, float tillingFactor) { - DrawRotatedQuad(pos, size, rotationDeg, nullptr, glm::vec4{1.0f}, 1.0f); + void Renderer2D::DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, const float rotationDeg, const Ref& texture, float tilingFactor) { + DrawRotatedQuad(pos, size, rotationDeg, s_Data.UnitTexture, glm::vec4{1.0f}, 1.0f); } - void Renderer2D::DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, const float rotationDeg, const Ref& texture, const glm::vec4& color) { - DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, nullptr, glm::vec4{1.0f}, 1.0f); + void Renderer2D::DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, const float rotationDeg, const Ref& texture, const glm::vec4& color, float tilingFactor) { + DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, s_Data.UnitTexture, glm::vec4{1.0f}, tilingFactor); } void Renderer2D::DrawRotatedQuad( @@ -349,6 +418,70 @@ namespace AGE { s_Data.Stats.QuadCount++; } + void Renderer2D::DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref & subTexture, float tilingFactor) { + DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, subTexture, glm::vec4{1.0f}, tilingFactor); + } + + void Renderer2D::DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref & subTexture, float tilingFactor) { + DrawRotatedQuad(pos, size, rotationDeg, subTexture, glm::vec4{1.0f}, tilingFactor); + } + + void Renderer2D::DrawRotatedQuad( + const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref & subTexture, const glm::vec4& color, float tilingFactor + ) { + DrawRotatedQuad(glm::vec3{pos, 0.0f}, size, rotationDeg, subTexture, color, tilingFactor); + } + + void Renderer2D::DrawRotatedQuad( + const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref & subTexture, const glm::vec4& color, float tillingFactor + ) { + glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) + * glm::rotate(glm::mat4(1.0f), glm::radians(rotationDeg), {0.0f, 0.0f, 1.0f}) + * glm::scale(glm::mat4(1.0f), {size.x, size.y, 0.0f}); + + int textureIndex = FindTextureIndex(subTexture->GetTexture()); + const glm::vec2* texCoord = subTexture->TexCoords(); + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + transform * s_Data.QuadVertexPositions[0], + color, + texCoord[0], + (float)textureIndex, + tillingFactor + }; + s_Data.QuadVertexBufferPtr++; + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + transform * s_Data.QuadVertexPositions[1], + color, + texCoord[1], + (float)textureIndex, + tillingFactor + }; + s_Data.QuadVertexBufferPtr++; + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + transform * s_Data.QuadVertexPositions[2], + color, + texCoord[2], + (float)textureIndex, + tillingFactor + }; + s_Data.QuadVertexBufferPtr++; + + *s_Data.QuadVertexBufferPtr = QuadVertex{ + transform * s_Data.QuadVertexPositions[3], + color, + texCoord[3], + (float)textureIndex, + tillingFactor + }; + s_Data.QuadVertexBufferPtr++; + + s_Data.QuadIndexCount += 6; + s_Data.Stats.QuadCount++; + } + #pragma endregion #pragma region Statistics diff --git a/AGE/src/Age/Renderer/Renderer2D.h b/AGE/src/Age/Renderer/Renderer2D.h index e352e9a..d9e3395 100644 --- a/AGE/src/Age/Renderer/Renderer2D.h +++ b/AGE/src/Age/Renderer/Renderer2D.h @@ -9,6 +9,7 @@ #include "OrthographicCamera.h" #include "Texture.h" +#include "SubTexture2D.h" namespace AGE { @@ -32,9 +33,9 @@ namespace AGE { static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const glm::vec4& color); static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const glm::vec4& color); - static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref& texture, float tillingFactor = 1.0f); - static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref& texture, float tillingFactor = 1.0f); - static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref& texture, const glm::vec4& color); + static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref& texture, float tilingFactor = 1.0f); + static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref& texture, float tilingFactor = 1.0f); + static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref& texture, const glm::vec4& color, float tilingFactor = 1.0f); /** * @brief Adds quad to current batch. @@ -42,9 +43,24 @@ namespace AGE { * @param size - size in meters. * @param texture - texture. If none, white 1x1 texture will be used. * @param color - tint color. - * @param tillingFactor - tilling factor for the texture. + * @param tilingFactor - tilling factor for the texture. + */ + static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref& texture, const glm::vec4& color, float tilingFactor = 1.0f); + + + static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref& subTexture, float tilingFactor = 1.0f); + static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref& subTexture, float tilingFactor = 1.0f); + static void DrawQuad(const glm::vec2& pos, const glm::vec2& size, const Ref& subTexture, const glm::vec4& color, float tilingFactor = 1.0f); + + /** + * @brief Adds quad to current batch. + * @param pos - world position. + * @param size - size in meters. + * @param subTexture - sub texture. + * @param color - tint color. + * @param tilingFactor - tilling factor for the texture. */ - static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref& texture, const glm::vec4& color, float tillingFactor = 1.0f); + static void DrawQuad(const glm::vec3& pos, const glm::vec2& size, const Ref& subTexture, const glm::vec4& color, float tilingFactor = 1.0f); #pragma endregion @@ -52,9 +68,9 @@ namespace AGE { static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const glm::vec4& color); static void DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const glm::vec4& color); - static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, float tillingFactor = 1.0f); - static void DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, float tillingFactor = 1.0f); - static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, const glm::vec4& color); + static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, float tilingFactor = 1.0f); + static void DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, float tilingFactor = 1.0f); + static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, const glm::vec4& color, float tilingFactor = 1.0f); /** * @brief Adds a rotated quad to the current batch. @@ -69,6 +85,24 @@ namespace AGE { const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref& texture, const glm::vec4& color, float tillingFactor = 1.0f ); + + static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref& subTexture, float tilingFactor = 1.0f); + static void DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref& subTexture, float tilingFactor = 1.0f); + static void DrawRotatedQuad(const glm::vec2& pos, const glm::vec2& size, float rotationDeg, const Ref& subTexture, const glm::vec4& color, float tilingFactor = 1.0f); + + /** + * @brief Adds a rotated quad to the current batch. + * @param pos - world position. + * @param size - size in meters. + * @param rotationDeg - rotation in degrees. + * @param subTexture - sub texture + * @param color - tint color. + * @param tillingFactor - tilling factor for the texture. + */ + static void DrawRotatedQuad( + const glm::vec3& pos, const glm::vec2& size, float rotationDeg, const Ref& subTexture, const glm::vec4& color, float tillingFactor = 1.0f + ); + #pragma endregion struct Statistics { diff --git a/AGE/src/Age/Renderer/SubTexture2D.cpp b/AGE/src/Age/Renderer/SubTexture2D.cpp new file mode 100644 index 0000000..9841658 --- /dev/null +++ b/AGE/src/Age/Renderer/SubTexture2D.cpp @@ -0,0 +1,27 @@ +// +// Created by alex on 1/31/23. +// + +#include "SubTexture2D.h" + +namespace AGE { + SubTexture2D::SubTexture2D(const Ref & texture, const glm::vec2& min, const glm::vec2& max) : m_Texture{texture} { + m_TexCoords[0] = {min.x, max.y}; + m_TexCoords[1] = {max.x, max.y}; + m_TexCoords[2] = {max.x, min.y}; + m_TexCoords[3] = {min.x, min.y}; + } + + Ref SubTexture2D::CreateFromCoords(const Ref & texture, const glm::vec2& offset, const glm::vec2& cellSizePx, const glm::vec2& spriteSize) { + const auto sheetWidth = (float)texture->Width(), sheetHeight = (float)texture->Height(); + + const glm::vec2 min{ + (offset.x * cellSizePx.x) / sheetWidth, 1.0f - ((offset.y * cellSizePx.y * spriteSize.y) / sheetHeight) - (cellSizePx.y * spriteSize.y) / sheetHeight + }; + const glm::vec2 max{ + min.x + (spriteSize.x * cellSizePx.x / sheetWidth), 1.0f - (offset.y * cellSizePx.y) / sheetHeight + }; + + return MakeRef(texture, min, max); + } +} // AGE diff --git a/AGE/src/Age/Renderer/SubTexture2D.h b/AGE/src/Age/Renderer/SubTexture2D.h new file mode 100644 index 0000000..510a6ba --- /dev/null +++ b/AGE/src/Age/Renderer/SubTexture2D.h @@ -0,0 +1,30 @@ +// +// Created by alex on 1/31/23. +// + +#ifndef AGE_SUBTEXTURE2D_H +#define AGE_SUBTEXTURE2D_H + +#include "Age/Core/Core.h" +#include "Texture.h" +#include "glm/glm.hpp" + +namespace AGE { + + class SubTexture2D { + public: + SubTexture2D(const Ref & texture, const glm::vec2& min, const glm::vec2& max); + + [[nodiscard]] const glm::vec2* TexCoords() const { return m_TexCoords; } + [[nodiscard]] const Ref & GetTexture() const { return m_Texture; } + + static Ref CreateFromCoords(const Ref& texture, const glm::vec2& offset, const glm::vec2& cellSizePx, const glm::vec2& spriteSize = {1.0f, 1.0f}); + + private: + Ref m_Texture; + glm::vec2 m_TexCoords[4]{}; + }; + +} // AGE + +#endif //AGE_SUBTEXTURE2D_H diff --git a/AGE/src/Age/Renderer/Texture.cpp b/AGE/src/Age/Renderer/Texture.cpp index 5dedb0f..10b9b4f 100644 --- a/AGE/src/Age/Renderer/Texture.cpp +++ b/AGE/src/Age/Renderer/Texture.cpp @@ -13,7 +13,7 @@ #endif namespace AGE { - Ref Texture2D::Create(const age_string_t& path) { + Ref Texture2D::Create(const age_string_t& path) { AGE_PROFILE_FUNCTION(); switch (Renderer::GetAPI()) { @@ -33,7 +33,7 @@ namespace AGE { return nullptr; } - Ref Texture2D::Create(const uint32_t width, const uint32_t height) { + Ref Texture2D::Create(const uint32_t width, const uint32_t height) { AGE_PROFILE_FUNCTION(); switch (Renderer::GetAPI()) { @@ -42,7 +42,26 @@ namespace AGE { #ifdef AGE_INCLUDE_OPENGL return std::make_shared(width, height); #else - AGE_CORE_ASSER(false, "OpenGL is not available, because it is not included into the current compilation") + AGE_CORE_ASSERT(false, "OpenGL is not available, because it is not included into the current compilation") +#endif + default: { + AGE_CORE_ASSERT(false, + "Could not create a Vertex Array, as there is no RendererAPI selected"); + } + } + + return nullptr; + } + Ref Texture2D::ErrorTexture() { + AGE_PROFILE_FUNCTION(); + + switch (Renderer::GetAPI()) { + case RenderAPI::API::None: AGE_CORE_ASSERT(false, "RendererAPI::None is not supported"); + case RenderAPI::API::OpenGL: +#ifdef AGE_INCLUDE_OPENGL + return OpenGLTexture2D::ErrorTextureImpl(); +#else + AGE_CORE_ASSERT(false, "OpenGL is not available, because it is not included into the current compilation") #endif default: { AGE_CORE_ASSERT(false, diff --git a/AGE/src/Age/Renderer/Texture.h b/AGE/src/Age/Renderer/Texture.h index 2e22bda..40a15b9 100644 --- a/AGE/src/Age/Renderer/Texture.h +++ b/AGE/src/Age/Renderer/Texture.h @@ -29,8 +29,9 @@ namespace AGE { public: static Ref Create(const age_string_t& path); static Ref Create(const uint32_t width, const uint32_t height); + static Ref ErrorTexture(); - virtual bool operator==(const Texture2D& other) const = 0; + virtual bool operator==(const Texture2D& other) const { return ID() == other.ID(); }; }; } diff --git a/AGE/src/Platform/OpenGL/OpenGLTexture.cpp b/AGE/src/Platform/OpenGL/OpenGLTexture.cpp index fba5977..cd8c704 100644 --- a/AGE/src/Platform/OpenGL/OpenGLTexture.cpp +++ b/AGE/src/Platform/OpenGL/OpenGLTexture.cpp @@ -171,4 +171,13 @@ namespace AGE { SetData(&data, sizeof(data)); } + + Ref OpenGLTexture2D::ErrorTextureImpl() { + static Ref errorTexture{MakeRef()}; + return errorTexture; + } + + OpenGLTexture2D::OpenGLTexture2D() { + SetErrorTexture(); + } } // AGE diff --git a/AGE/src/Platform/OpenGL/OpenGLTexture.h b/AGE/src/Platform/OpenGL/OpenGLTexture.h index b6b4718..cc796c2 100644 --- a/AGE/src/Platform/OpenGL/OpenGLTexture.h +++ b/AGE/src/Platform/OpenGL/OpenGLTexture.h @@ -13,6 +13,7 @@ namespace AGE { public: OpenGLTexture2D(const age_string_t& path); OpenGLTexture2D(const uint32_t width, uint32_t height); + OpenGLTexture2D(); virtual ~OpenGLTexture2D() override; virtual void SetData(void* data, uint32_t size) override; @@ -31,6 +32,8 @@ namespace AGE { return m_RendererID == ((OpenGLTexture2D&)other).m_RendererID; } + static Ref ErrorTextureImpl(); + private: uint32_t m_Height, m_Width; age_string_t m_Path; diff --git a/Sandbox/assets/textures/tilemap.png b/Sandbox/assets/textures/tilemap.png new file mode 100644 index 0000000..35a8cd9 Binary files /dev/null and b/Sandbox/assets/textures/tilemap.png differ diff --git a/Sandbox/src/Sandbox2DLayer.cpp b/Sandbox/src/Sandbox2DLayer.cpp index 59eac36..bd948a8 100644 --- a/Sandbox/src/Sandbox2DLayer.cpp +++ b/Sandbox/src/Sandbox2DLayer.cpp @@ -10,13 +10,29 @@ #include "glm/gtc/type_ptr.hpp" +static const char* s_MapTiles = + "WWWWWWWWWWWWWWWWWWWWWWWW" + "WWWWWWDDDDDDDDDDDWWWWWWW" + "WWWWDDDDDDDDDDDDDDWWWWWW" + "WWWWDDDDDDDDDDDDDDDWWWWW" + "WWWDDDDDDDWWWWDDDDDDWWWW" + "WWDDDDDWWWWWWWDDDDDDWWWW" + "WWDDDDDWWWWWSDDDDDDDDWWW" + "WWWDDDDWWWWDDDDDDDDDDWWW" + "WWWDDDDDDDDDDDDDDDDDWWWW" + "WWWWDDDDDDDDDDDDDDDWWWWW" + "WWWWWWWWDDDDDDDDDWWWWWWW" + "WWWWWWWWWWWWWWWWWWWWWWWW"; + Sandbox2DLayer::Sandbox2DLayer() : m_CameraController(1280.0f / 720.0f), m_Particles(5000) { AGE_PROFILE_FUNCTION(); - m_CreeperFaceTex = AGE::Texture2D::Create("assets/textures/creeper-face.png"); - m_IncorrectTex = AGE::Texture2D::Create("wrong/path/to.png"); - m_CheckerboardTex = AGE::Texture2D::Create("assets/textures/Checkerboard.png"); - m_GearTex = AGE::Texture2D::Create("assets/textures/gear-sprite.png"); + m_SpriteSheet = AGE::Texture2D::Create("assets/textures/tilemap.png"); + + m_TileMap['W'] = AGE::SubTexture2D::CreateFromCoords(m_SpriteSheet, {11.0f, 1.0f}, {128.0f, 128.0f}); + m_TileMap['D'] = AGE::SubTexture2D::CreateFromCoords(m_SpriteSheet, {6.0f, 1.0f}, {128.0f, 128.0f}); + + m_CameraController.SetZoomLevel(7.0f); } void Sandbox2DLayer::OnUpdate(AGE::Timestep ts) { @@ -27,38 +43,34 @@ void Sandbox2DLayer::OnUpdate(AGE::Timestep ts) { AGE::RenderCommand::Clear(); AGE::Renderer2D::BeginScene(m_CameraController.GetCamera()); - AGE::Renderer2D::DrawQuad(glm::vec3{0.0f, 0.0f, -1.0f}, glm::vec2{20.0f}, m_CheckerboardTex, 20.0f); - - int xCount{5}; - int yCount{xCount}; - - for (int x{-xCount}; x <= xCount; x++) { - float normX = (float)(x + xCount) / ((float)xCount * 2.0f); - for (int y{-yCount}; y <= yCount; y++) { - float normY = (float)(y + yCount) / ((float)yCount * 2.0f); - - float r = normX * 0.6f; - float b = normY * 0.6f; - float g = 0.4f; - - AGE::Renderer2D::DrawQuad(glm::vec3{x, y, -0.1f}, glm::vec2{0.9f}, m_CheckerboardTex, glm::vec4{r, g, b, 1.0f}, 0.25f); + uint32_t mapHeight{12}; + uint32_t mapWidth{24}; + for(uint32_t y{0}; y < mapHeight; y++) { + float normY = (float)y - ((float)mapHeight / 2.0f); + for(uint32_t x{0}; x < mapWidth; x++) { + float normX = (float)x - ((float)mapWidth / 2.0f); + if(m_TileMap.find(s_MapTiles[y * mapWidth + x]) == m_TileMap.end()) { + AGE::Renderer2D::DrawQuad({normX, normY, -0.1f}, {1.0f, 1.0f}, AGE::Texture2D::ErrorTexture()); + continue; + } + AGE::Renderer2D::DrawQuad({normX, normY, -0.1f}, {1.0f, 1.0f}, m_TileMap[s_MapTiles[y * mapWidth + x]]); } } static float lastParticleSpawn{0.0f}; static ParticleProps props{glm::vec2{0.0f}, - glm::vec2{0, 1.5f}, - 0.5f, + glm::vec2{0}, + 1.5f, 45.0f, 90.0f, - glm::vec4{0.9f, 0.6f, 0.0f, 1.0f}, - glm::vec4{0.6f, 0.1f, 0.0f, 1.0f}, + glm::vec4{2.5f, 2.0f, 1.0f, 1.0f}, + glm::vec4{0.6f, 0.0f, 0.0f, 0.3f}, 0.05f, 0.1f, 0.05f, 0.01, - 5.0f, + 1.0f, 0.0f}; lastParticleSpawn += ts; @@ -82,7 +94,6 @@ void Sandbox2DLayer::OnUpdate(AGE::Timestep ts) { m_Particles.OnUpdate(ts); m_Particles.Render(); - AGE::Renderer2D::EndScene(); } diff --git a/Sandbox/src/Sandbox2DLayer.h b/Sandbox/src/Sandbox2DLayer.h index 50b3dd5..6c0d42e 100644 --- a/Sandbox/src/Sandbox2DLayer.h +++ b/Sandbox/src/Sandbox2DLayer.h @@ -8,6 +8,8 @@ #include "Age/Age.h" #include "Particle.h" +class Sandbox2DUI; + class Sandbox2DLayer : public AGE::Layer { public: Sandbox2DLayer(); @@ -17,11 +19,12 @@ class Sandbox2DLayer : public AGE::Layer { private: AGE::OrthographicCameraController m_CameraController; - AGE::Ref m_CreeperFaceTex; - AGE::Ref m_CheckerboardTex; - AGE::Ref m_IncorrectTex; - AGE::Ref m_GearTex; - ParticleSystem m_Particles; + AGE::Ref m_SpriteSheet; + std::unordered_map> m_TileMap; + + friend class Sandbox2DUI; + + ParticleSystem m_Particles; }; class Sandbox2DUI : public AGE::ImGuiLayer {