添加批量drawcall

This commit is contained in:
2025-05-19 16:22:34 +08:00
parent f6ccb823c7
commit e67a193c77
58 changed files with 1358 additions and 162 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)
project(Sandbox)
project(Sandbox) # 占位符
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

View File

@ -47,8 +47,11 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
opengl32
glm::glm
)
target_compile_definitions(${PROJECT_NAME} PRIVATE HZ_BUILD_DLL STB_IMAGE_IMPLEMENTATION HZ_PROFILE)# 编译DLL时定义
target_compile_definitions(${PROJECT_NAME} PRIVATE HZ_BUILD_DLL STB_IMAGE_IMPLEMENTATION)# 编译DLL时定义
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(${PROJECT_NAME} PUBLIC HZ_PROFILE)# 编译DLL时定义
endif ()
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PUBLIC HZ_PLATFORM_WINDOWS IMGUI_API=__declspec\(dllexport\))# 编译DLL时定义

View File

@ -4,10 +4,11 @@
#define STB_IMAGE_IMPLEMENTATION
// For use by Hazel Applications
#include "Hazel/Application.h"
#include "Hazel/Core.h"
#include "Hazel/Log.h"
#include "Hazel/Window.h"
#include "Hazel/Core/Application.h"
#include "Hazel/Core/Core.h"
#include "Hazel/Core/Log.h"
#include "Hazel/Debug/Instrumentor.h"
#include "Hazel/Core/Window.h"
#include "Hazel/ImGui/ImGuiLayer.h"
@ -15,6 +16,7 @@
// ------------------------ Renderer ----------------------------
#include "Hazel/Renderer/Renderer.h"
#include "Hazel/Renderer/Renderer2D.h"
#include "Hazel/Renderer/RendererCommand.h"
#include "Hazel/Renderer/Buffer.h"
@ -22,10 +24,5 @@
#include "Hazel/Renderer/Texture.h"
#include "Hazel/Renderer/VertexArray.h"
#include "Hazel/Renderer/OrthographicCamera.h"
#include "Hazel/Renderer/OrthographicCameraController.h"
// ------------------------ Entry Point ------------------------
#include "Hazel/EntryPoint.h"
// -----------------------------------------------------------------

View File

@ -1,12 +1,12 @@
#include "Application.h"
#include "Hazel/Core/Application.h"
#include <iostream>
#include <Hazel/Debug/Instrumentor.h>
#include <SDL3/SDL.h>
#include "Log.h"
#include "Renderer/Renderer.h"
#include "Renderer/RendererCommand.h"
#include "Hazel/Core/Log.h"
#include "Hazel/Renderer/Renderer.h"
namespace Hazel {
@ -16,6 +16,8 @@ namespace Hazel {
Application::Application()
{
HZ_PROFILE_FUNCTION();
if (s_Instance != nullptr)
{
HZ_CORE_ERROR("Application already exists!");
@ -35,27 +37,37 @@ namespace Hazel {
}
Application::~Application() = default;
Application::~Application()
{
}
void Application::Run() {
HZ_PROFILE_FUNCTION();
while (m_Running)
{
float currentTime = (float)SDL_GetTicks();
TimeStep timestep = currentTime - m_lastFrameTime;
m_lastFrameTime = currentTime;
HZ_PROFILE_SCOPE("RunLoop");
float currentTime = static_cast<float>(SDL_GetTicks());
TimeStep timestep = currentTime - m_lastFrameTime;
m_lastFrameTime = currentTime;
if (!m_Minimized)
{
for (Layer* layer : m_layerStack)
{
layer->OnUpdate(timestep);
HZ_PROFILE_SCOPE("LayerStack OnUpdates");
for (Layer* layer : m_layerStack)
{
layer->OnUpdate(timestep);
}
}
m_imguiLayer->Begin();
for (Layer* layer : m_layerStack)
{
layer->OnImGuiRender();
HZ_PROFILE_SCOPE("LayerStack OnImGuiRender");
for (Layer* layer : m_layerStack)
{
layer->OnImGuiRender();
}
}
m_imguiLayer->End();
}
@ -66,6 +78,7 @@ namespace Hazel {
void Application::OnEvent(SDL_Event& e)
{
HZ_PROFILE_FUNCTION();
for (auto it = m_layerStack.end(); it != m_layerStack.begin();)
{
@ -91,17 +104,21 @@ namespace Hazel {
void Application::OnWindowResize(SDL_Event& e)
{
HZ_PROFILE_FUNCTION();
m_Minimized = false;
HZ_CORE_INFO("Resized window:({0}, {1})", m_Window->GetWidth(), m_Window->GetHeight());
Renderer::OnWindowResize(m_Window->GetWidth(), m_Window->GetHeight());
}
void Application::PushLayer(Layer* layer)
{
HZ_PROFILE_FUNCTION();
m_layerStack.PushLayer(layer);
layer->OnAttach();
}
void Application::PushOverlay(Layer* layer)
{
HZ_PROFILE_FUNCTION();
m_layerStack.PushOverlay(layer);
layer->OnAttach();
}

View File

@ -5,8 +5,8 @@
#include "Core.h"
#include "Layer.h"
#include "LayerStack.h"
#include "Core/TimeStep.h"
#include "ImGui/ImGuiLayer.h"
#include "Hazel/Core/TimeStep.h"
#include "Hazel/ImGui/ImGuiLayer.h"
namespace Hazel {

View File

@ -0,0 +1,28 @@
#pragma once
#ifdef HZ_PLATFORM_WINDOWS
extern Hazel::Application* Hazel::CreateApplication();
int main(int, char**) {
Hazel::Log::init();
HZ_PROFILE_BEGIN_SESSION("Start", "Start.json");
const auto app = Hazel::CreateApplication();
HZ_PROFILE_END_SESSION();
HZ_PROFILE_BEGIN_SESSION("Update", "Update.json");
app->Run();
HZ_PROFILE_END_SESSION();
HZ_PROFILE_BEGIN_SESSION("End", "End.json");
delete app;
HZ_PROFILE_END_SESSION();
}
#endif // HZ_PLATFORM_WINDOWS

View File

@ -2,7 +2,7 @@
// Created by sfd on 25-4-17.
//
#include "Layer.h"
#include "Hazel/Core/Layer.h"
namespace Hazel

View File

@ -10,7 +10,7 @@
#include "Core.h"
#include <SDL3/SDL.h>
#include "Core/TimeStep.h"
#include "Hazel/Core/TimeStep.h"
namespace Hazel {

View File

@ -2,7 +2,7 @@
// Created by sfd on 25-4-17.
//
#include "LayerStack.h"
#include "Hazel/Core/LayerStack.h"
namespace Hazel
{
@ -20,6 +20,7 @@ namespace Hazel
void LayerStack::PushLayer(Layer* layer)
{
m_layers.emplace(m_layers.begin() + m_LayerInsertIndex++, layer);
m_LayerInsertIndex ++;
}
void LayerStack::PushOverlay(Layer* layer)
@ -32,6 +33,7 @@ namespace Hazel
auto it = std::ranges::find(m_layers.begin(), m_layers.end(), layer);
if (it != m_layers.end())
{
layer->OnDetech();
m_layers.erase(it);
m_LayerInsertIndex--;
}
@ -43,6 +45,7 @@ namespace Hazel
auto it = std::ranges::find(m_layers.begin(), m_layers.end(), layer);
if (it != m_layers.end())
{
layer->OnDetech();
m_layers.erase(it);
}

View File

@ -1,4 +1,4 @@
#include "Log.h"
#include "Hazel/Core/Log.h"
#include <spdlog/sinks/stdout_color_sinks.h>

View File

@ -45,6 +45,7 @@ namespace Hazel
static Window* Create(const WindowProps& props = WindowProps());
virtual Uint32 GetMainWindowID() const = 0;
virtual void* GetNativeWindow() const = 0;
virtual void* GetNativeGLContext() const = 0;

View File

@ -0,0 +1,243 @@
#pragma once
#ifdef HZ_PROFILE
#include "Hazel/Core/Log.h"
#include <algorithm>
#include <chrono>
#include <fstream>
#include <iomanip>
#include <string>
#include <thread>
#include <mutex>
#include <sstream>
namespace Hazel {
using FloatingPointMicroseconds = std::chrono::duration<double, std::micro>;
struct ProfileResult
{
std::string Name;
FloatingPointMicroseconds Start;
std::chrono::microseconds ElapsedTime;
std::thread::id ThreadID;
};
struct InstrumentationSession
{
std::string Name;
};
class HAZEL_API Instrumentor
{
public:
Instrumentor(const Instrumentor&) = delete;
Instrumentor(Instrumentor&&) = delete;
void BeginSession(const std::string& name, const std::string& filepath = "results.json")
{
std::lock_guard lock(m_Mutex);
if (m_CurrentSession)
{
// If there is already a current session, then close it before beginning new one.
// Subsequent profiling output meant for the original session will end up in the
// newly opened session instead. That's better than having badly formatted
// profiling output.
if (Log::getCoreLogger()) // Edge case: BeginSession() might be before Log::Init()
{
HZ_CORE_ERROR("Instrumentor::BeginSession('{0}') when session '{1}' already open.", name, m_CurrentSession->Name);
}
InternalEndSession();
}
m_OutputStream.open(filepath);
if (m_OutputStream.is_open())
{
m_CurrentSession = new InstrumentationSession({name});
WriteHeader();
}
else
{
if (Log::getCoreLogger()) // Edge case: BeginSession() might be before Log::Init()
{
HZ_CORE_ERROR("Instrumentor could not open results file '{0}'.", filepath);
}
}
}
void EndSession()
{
std::lock_guard lock(m_Mutex);
InternalEndSession();
}
void WriteProfile(const ProfileResult& result)
{
std::stringstream json;
json << std::setprecision(3) << std::fixed;
json << ",{";
json << "\"cat\":\"function\",";
json << "\"dur\":" << (result.ElapsedTime.count()) << ',';
json << "\"name\":\"" << result.Name << "\",";
json << "\"ph\":\"X\",";
json << "\"pid\":0,";
json << "\"tid\":" << result.ThreadID << ",";
json << "\"ts\":" << result.Start.count();
json << "}";
std::lock_guard lock(m_Mutex);
if (m_CurrentSession)
{
m_OutputStream << json.str();
m_OutputStream.flush();
}
}
static Instrumentor& Get()
{
static Instrumentor instance;
return instance;
}
private:
Instrumentor()
: m_CurrentSession(nullptr)
{
}
~Instrumentor()
{
EndSession();
}
void WriteHeader()
{
m_OutputStream << "{\"otherData\": {},\"traceEvents\":[{}";
m_OutputStream.flush();
}
void WriteFooter()
{
m_OutputStream << "]}";
m_OutputStream.flush();
}
// Note: you must already own lock on m_Mutex before
// calling InternalEndSession()
void InternalEndSession()
{
if (m_CurrentSession)
{
WriteFooter();
m_OutputStream.close();
delete m_CurrentSession;
m_CurrentSession = nullptr;
}
}
private:
std::mutex m_Mutex;
InstrumentationSession* m_CurrentSession;
std::ofstream m_OutputStream;
};
class HAZEL_API InstrumentationTimer
{
public:
InstrumentationTimer(const char* name)
: m_Name(name), m_Stopped(false)
{
m_StartTimepoint = std::chrono::steady_clock::now();
}
~InstrumentationTimer()
{
if (!m_Stopped)
Stop();
}
void Stop()
{
auto endTimepoint = std::chrono::steady_clock::now();
auto highResStart = FloatingPointMicroseconds{ m_StartTimepoint.time_since_epoch() };
auto elapsedTime = std::chrono::time_point_cast<std::chrono::microseconds>(endTimepoint).time_since_epoch() - std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch();
Instrumentor::Get().WriteProfile({ m_Name, highResStart, elapsedTime, std::this_thread::get_id() });
m_Stopped = true;
}
private:
const char* m_Name;
std::chrono::time_point<std::chrono::steady_clock> m_StartTimepoint;
bool m_Stopped;
};
namespace InstrumentorUtils {
template <size_t N>
struct ChangeResult
{
char Data[N];
};
template <size_t N, size_t K>
constexpr auto CleanupOutputString(const char(&expr)[N], const char(&remove)[K])
{
ChangeResult<N> result = {};
size_t srcIndex = 0;
size_t dstIndex = 0;
while (srcIndex < N)
{
size_t matchIndex = 0;
while (matchIndex < K - 1 && srcIndex + matchIndex < N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
matchIndex++;
if (matchIndex == K - 1)
srcIndex += matchIndex;
result.Data[dstIndex++] = expr[srcIndex] == '"' ? '\'' : expr[srcIndex];
srcIndex++;
}
return result;
}
}
}
// Resolve which function signature macro will be used. Note that this only
// is resolved when the (pre)compiler starts, so the syntax highlighting
// could mark the wrong one in your editor!
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
#define HZ_FUNC_SIG __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
#define HZ_FUNC_SIG __PRETTY_FUNCTION__
#elif (defined(__FUNCSIG__) || (_MSC_VER))
#define HZ_FUNC_SIG __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
#define HZ_FUNC_SIG __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
#define HZ_FUNC_SIG __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
#define HZ_FUNC_SIG __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
#define HZ_FUNC_SIG __func__
#else
#define HZ_FUNC_SIG "HZ_FUNC_SIG unknown!"
#endif
#define HZ_PROFILE_BEGIN_SESSION(name, filepath) ::Hazel::Instrumentor::Get().BeginSession(name, filepath)
#define HZ_PROFILE_END_SESSION() ::Hazel::Instrumentor::Get().EndSession()
#define HZ_PROFILE_SCOPE_LINE2(name, line) constexpr auto fixedName##line = ::Hazel::InstrumentorUtils::CleanupOutputString(name, "__cdecl ");\
::Hazel::InstrumentationTimer timer##line(fixedName##line.Data)
#define HZ_PROFILE_SCOPE_LINE(name, line) HZ_PROFILE_SCOPE_LINE2(name, line)
#define HZ_PROFILE_SCOPE(name) HZ_PROFILE_SCOPE_LINE(name, __LINE__)
#define HZ_PROFILE_FUNCTION() HZ_PROFILE_SCOPE(HZ_FUNC_SIG)
#else
#define HZ_PROFILE_BEGIN_SESSION(name, filepath)
#define HZ_PROFILE_END_SESSION()
#define HZ_PROFILE_SCOPE(name)
#define HZ_PROFILE_FUNCTION()
#endif

View File

@ -1,17 +0,0 @@
#pragma once
#ifdef HZ_PLATFORM_WINDOWS
extern Hazel::Application* Hazel::CreateApplication();
int main(int, char**) {
Hazel::Log::init();
auto app = Hazel::CreateApplication();
app->Run();
}
#endif // HZ_PLATFORM_WINDOWS

View File

@ -7,7 +7,8 @@
#include <imgui.h>
#include <imgui_impl_opengl3.h>
#include <imgui_impl_sdl3.h>
#include <Hazel/Application.h>
#include <Hazel/Core/Application.h>
#include <Hazel/Debug/Instrumentor.h>
namespace Hazel
@ -22,6 +23,7 @@ namespace Hazel
void ImGuiLayer::OnAttach()
{
HZ_PROFILE_FUNCTION();
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui::StyleColorsDark();
@ -48,6 +50,7 @@ namespace Hazel
void ImGuiLayer::OnDetech()
{
HZ_PROFILE_FUNCTION();
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext();
@ -67,6 +70,7 @@ namespace Hazel
void ImGuiLayer::Begin()
{
HZ_PROFILE_FUNCTION();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();
@ -75,9 +79,10 @@ namespace Hazel
void ImGuiLayer::End()
{
HZ_PROFILE_FUNCTION();
ImGuiIO& io = ImGui::GetIO();
Application& app = Application::Get();
io.DisplaySize = ImVec2((float)app.GetWindow().GetWidth(), (float)app.GetWindow().GetHeight());
io.DisplaySize = ImVec2(static_cast<float>(app.GetWindow().GetWidth()), static_cast<float>(app.GetWindow().GetHeight()));
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

View File

@ -4,7 +4,7 @@
#ifndef IMGUILAYER_H
#define IMGUILAYER_H
#include <Hazel/Layer.h>
#include <Hazel/Core/Layer.h>
namespace Hazel {

View File

@ -4,15 +4,14 @@
#include "Buffer.h"
#include <Hazel/Log.h>
#include <Hazel/Core/Log.h>
#include "Renderer.h"
#include "Platform/OpenGL/OpenGLBuffer.h"
namespace Hazel
{
// std::shared_ptr<VertexBuffer> VertexBuffer::Create(float* vertices, uint32_t size)
VertexBuffer* VertexBuffer::Create(float* vertices, uint32_t size)
Ref<VertexBuffer> VertexBuffer::Create(uint32_t size)
{
switch (Renderer::GetAPI())
{
@ -21,8 +20,7 @@ namespace Hazel
return nullptr;
case RendererAPI::API::OPENGL:
// return std::make_shared<VertexBuffer>(OpenGLVertexBuffer(vertices, size));
return new OpenGLVertexBuffer(vertices, size);
break;
return std::make_shared<OpenGLVertexBuffer>(size);
default:
break;
}
@ -31,15 +29,34 @@ namespace Hazel
return nullptr;
}
IndexBuffer* IndexBuffer::Create(uint32_t* indices, uint32_t count)
// std::shared_ptr<VertexBuffer> VertexBuffer::Create(float* vertices, uint32_t size)
Ref<VertexBuffer> VertexBuffer::Create(float* vertices, uint32_t size)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::NONE:
HZ_CORE_ERROR("NONE is not Support!");
return nullptr;
case RendererAPI::API::OPENGL:
return new OpenGLIndexBuffer(indices, count);
case RendererAPI::API::OPENGL:
// return std::make_shared<VertexBuffer>(OpenGLVertexBuffer(vertices, size));
return std::make_shared<OpenGLVertexBuffer>(vertices, size);
default:
break;
}
HZ_CORE_ERROR("Unknown RendererAPI!");
return nullptr;
}
Ref<IndexBuffer> IndexBuffer::Create(uint32_t* indices, uint32_t count)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::NONE:
HZ_CORE_ERROR("NONE is not Support!");
return nullptr;
case RendererAPI::API::OPENGL:
return std::make_shared<OpenGLIndexBuffer>(indices, count);
break;
default:
break;

View File

@ -8,9 +8,9 @@
#include <cstdint>
#include <string>
#include <vector>
#include <Hazel/Log.h>
#include <Hazel/Core/Log.h>
#include "Hazel/Core.h"
#include "Hazel/Core/Core.h"
namespace Hazel
{
@ -127,10 +127,12 @@ namespace Hazel
virtual void Bind() const = 0;
virtual void Unbind() const = 0;
virtual void SetLayout(const BufferLayout& layout) = 0;
virtual void SetData(const void* data, uint32_t size) = 0;
virtual const BufferLayout& GetLayout() const = 0;
// static std::shared_ptr<VertexBuffer> Create(float* vertices, uint32_t size);
static VertexBuffer* Create(float* vertices, uint32_t size);
static Ref<VertexBuffer> Create(uint32_t size);
static Ref<VertexBuffer> Create(float* vertices, uint32_t size);
};
@ -145,7 +147,7 @@ namespace Hazel
virtual uint32_t GetCount() const = 0;
static IndexBuffer* Create(uint32_t* indices, uint32_t count);
static Ref<IndexBuffer> Create(uint32_t* indices, uint32_t count);
};
}

View File

@ -5,7 +5,7 @@
#ifndef GRAPHICSCONTEXT_H
#define GRAPHICSCONTEXT_H
#include "Hazel/Core.h"
#include "Hazel/Core/Core.h"
namespace Hazel
{

View File

@ -6,24 +6,27 @@
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <Hazel/Debug/Instrumentor.h>
namespace Hazel
{
OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top)
: m_ProjectionMatrix(glm::ortho(left, right, bottom, top, -1.0f, 1.0f)), m_ViewMatrix(glm::mat4(1.0f))
{
HZ_PROFILE_FUNCTION();
m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
}
void OrthographicCamera::SetProjection(float left, float right, float bottom, float top)
{
HZ_PROFILE_FUNCTION();
m_ProjectionMatrix = glm::ortho(left, right, bottom, top, -1.0f, 1.0f);
m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
}
void OrthographicCamera::RecalculateViewMatrix()
{
HZ_PROFILE_FUNCTION();
glm::mat4 transform = glm::translate(glm::mat4(1.0f), m_Position) * glm::rotate(glm::mat4(1.0f), glm::radians(m_Rotation), glm::vec3(0.0f, 0.0f, 1.0f));
m_ViewMatrix = glm::inverse(transform);

View File

@ -6,7 +6,7 @@
#define ORTHOGRAPHICCAMERA_H
#include <glm/glm.hpp>
#include "Hazel/Core.h"
#include "Hazel/Core/Core.h"
namespace Hazel
{

View File

@ -2,7 +2,10 @@
// Created by sfd on 25-5-12.
//
#include "OrthographicCameraController.h"
#include "Hazel/Renderer/OrthographicCameraController.h"
#include <Hazel/Core/Application.h>
#include <Hazel/Debug/Instrumentor.h>
namespace Hazel
@ -13,6 +16,7 @@ namespace Hazel
void OrthographicCameraController::OnUpdate(TimeStep ts)
{
HZ_PROFILE_FUNCTION();
const bool* state = SDL_GetKeyboardState(NULL);
float time = ts;
if (state[SDL_SCANCODE_A])
@ -53,12 +57,14 @@ namespace Hazel
void OrthographicCameraController::OnEvent(SDL_Event& e)
{
HZ_PROFILE_FUNCTION();
OnMouseScrolled(e);
OnWindowResized(e);
}
bool OrthographicCameraController::OnMouseScrolled(SDL_Event& e)
{
HZ_PROFILE_FUNCTION();
if (e.type == SDL_EVENT_MOUSE_WHEEL)
{
m_ZoomLevel += e.wheel.y * 0.25f;
@ -71,7 +77,8 @@ namespace Hazel
bool OrthographicCameraController::OnWindowResized(SDL_Event& e)
{
if (e.type == SDL_EVENT_WINDOW_RESIZED)
HZ_PROFILE_FUNCTION();
if (e.type == SDL_EVENT_WINDOW_RESIZED && (e.window.windowID == Application::Get().GetWindow().GetMainWindowID()))
{
m_AspectRatio = static_cast<float>(e.window.data1) / static_cast<float>(e.window.data2);
m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);

View File

@ -7,9 +7,9 @@
#include <SDL3/SDL_events.h>
#include "Core.h"
#include "Core/TimeStep.h"
#include "Renderer/OrthographicCamera.h"
#include "Hazel/Core/Core.h"
#include "Hazel/Core/TimeStep.h"
#include "Hazel/Renderer/OrthographicCamera.h"
@ -25,6 +25,8 @@ namespace Hazel
void OnUpdate(TimeStep ts);
void OnEvent(SDL_Event& e);
void SetZoomLevel(float level) {m_ZoomLevel = level;}
float GetZoomLevel() const {return m_ZoomLevel;}
OrthographicCamera& GetCamera() {return m_Camera;}
const OrthographicCamera& GetCamera() const {return m_Camera;}

View File

@ -5,6 +5,7 @@
#include "Renderer.h"
#include "Renderer2D.h"
#include "Platform/OpenGL/OpenGLShader.h"
#include "RendererCommand.h"
@ -16,6 +17,7 @@ namespace Hazel
void Renderer::Init()
{
RendererCommand::Init();
Renderer2D::Init();
}
void Renderer::OnWindowResize(uint32_t width, uint32_t height)

View File

@ -9,7 +9,7 @@
#include "RendererAPI.h"
#include "Shader.h"
#include "Hazel/Core.h"
#include "Hazel/Core/Core.h"
namespace Hazel
{

View File

@ -0,0 +1,326 @@
//
// Created by sfd on 25-5-17.
//
#include "Renderer2D.h"
#include <array>
#include <iostream>
#include <Hazel/Debug/Instrumentor.h>
#include "RendererCommand.h"
#include "Shader.h"
#include "glm/ext/matrix_transform.hpp"
namespace Hazel
{
// #define s_Data Renderer2DData::Get()
struct QuadVertex
{
glm::vec3 Position;
glm::vec4 Color;
glm::vec2 TexCoord;
float TexIndex;
// TODO:
};
struct Renderer2DStorage
{
const uint32_t MaxQuad = 10000;
const uint32_t MaxVertices = MaxQuad * 4;
const uint32_t MaxIndices = MaxQuad * 6;
static const uint32_t MaxTextureSlots = 32; //TODO: RenderCaps
Ref<VertexArray> QuadVertexArray;
Ref<VertexBuffer> QuadVertexBuffer;
Ref<Shader> TextureShader;
Ref<Texture2D> WhiteTexture;
uint32_t QuadIndexCount = 0;
QuadVertex* QuadVertexBufferBase = nullptr;
QuadVertex* QuadVertexBufferPtr = nullptr;
std::array<Ref<Texture2D>, MaxTextureSlots> TextureSlots;
uint32_t TextureSlotIndex = 1; // 0 use white texture
};
static Renderer2DStorage s_Data;
void Renderer2D::Init()
{
HZ_PROFILE_FUNCTION();
// s_Data = new Renderer2DStorage();
s_Data.QuadVertexArray = VertexArray::Create();
//= VertexBuffer::Create(squareVertices, sizeof(squareVertices));
s_Data.QuadVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(QuadVertex));
s_Data.QuadVertexBuffer->SetLayout(
{
{ShaderDataType::Float3, "a_Postion"},
{ShaderDataType::Float4, "a_Color"},
{ShaderDataType::Float2, "a_TexCoord"},
{ShaderDataType::Float, "a_TexIndex"}
});
s_Data.QuadVertexArray->AddVertexBuffer(s_Data.QuadVertexBuffer);
s_Data.QuadVertexBufferBase = new QuadVertex[s_Data.MaxVertices];
uint32_t* quadIndices = new uint32_t[s_Data.MaxIndices];
uint32_t offset = 0;
for (uint32_t i = 0; i < s_Data.MaxIndices; i += 6)
{
quadIndices[i + 0] = offset + 0;
quadIndices[i + 1] = offset + 1;
quadIndices[i + 2] = offset + 2;
quadIndices[i + 3] = offset + 2;
quadIndices[i + 4] = offset + 3;
quadIndices[i + 5] = offset + 0;
offset += 4;
}
Ref<IndexBuffer> quadIB = IndexBuffer::Create(quadIndices, s_Data.MaxIndices);
s_Data.QuadVertexArray->SetIndexBuffer(quadIB);
delete[] quadIndices;
s_Data.WhiteTexture = Texture2D::Create(1, 1);
uint32_t whiteTextureData = 0xffffffff;
s_Data.WhiteTexture->SetData(&whiteTextureData, sizeof(uint32_t));
int32_t samplers[s_Data.MaxTextureSlots];
for (uint32_t i = 0; i < s_Data.MaxTextureSlots; i ++)
{
samplers[i] = i;
}
s_Data.TextureShader = Shader::Create("assets/shaders/Texture.glsl");
s_Data.TextureShader->Bind();
s_Data.TextureShader->SetIntv("u_Textures", samplers, s_Data.MaxTextureSlots);
// set all texture slot to 0
s_Data.TextureSlots[0] = s_Data.WhiteTexture;
/*
memset(s_Data.TextureSlots.data(), 0, s_Data.TextureSlots.size() * sizeof(uint32_t));
or
for (uint32_t i = 0; i < s_Data.TextureSlots.size(); i ++)
{
s_Data.TextureSlots[i] = 0;
}
*/
}
void Renderer2D::BeginScene(const OrthographicCamera& camera)
{
HZ_PROFILE_FUNCTION();
s_Data.TextureShader->Bind();
s_Data.TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
s_Data.QuadIndexCount = 0;
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
s_Data.TextureSlotIndex = 1;
}
void Renderer2D::EndScene()
{
HZ_PROFILE_FUNCTION();
uint32_t datasize = (uint8_t*)s_Data.QuadVertexBufferPtr - (uint8_t*)s_Data.QuadVertexBufferBase;
s_Data.QuadVertexBuffer->SetData(s_Data.QuadVertexBufferBase, datasize);
Flush();
}
void Renderer2D::Flush()
{
for (uint32_t i = 0; i < s_Data.TextureSlotIndex; i ++ )
{
s_Data.TextureSlots[i]->Bind(i);
}
s_Data.WhiteTexture->Bind();
RendererCommand::DrawIndexed(s_Data.QuadVertexArray, s_Data.QuadIndexCount);
}
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color)
{
DrawQuad({position.x, position.y, 0.0f}, size, color);
}
void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color)
{
HZ_PROFILE_FUNCTION();
const float texIndex = 0.0f;
s_Data.QuadVertexBufferPtr->Position = position;
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {0.0f, 0.0f};
s_Data.QuadVertexBufferPtr->TexIndex = texIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadVertexBufferPtr->Position = { position.x + size.x, position.y, 0.0f };
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {1.0f, 0.0f};
s_Data.QuadVertexBufferPtr->TexIndex = texIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadVertexBufferPtr->Position = {position.x + size.x, position.y + size.y, 0.0f};
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {1.0f, 1.0f};
s_Data.QuadVertexBufferPtr->TexIndex = texIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadVertexBufferPtr->Position = {position.x, position.y + size.y, 0.0f};
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {0.0f, 1.0f};
s_Data.QuadVertexBufferPtr->TexIndex = texIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadIndexCount += 6;
/*
s_Data.TextureShader->SetFloat4("u_Color", color);
s_Data.TextureShader->SetFloat("u_TilingFactor", 1.f);
s_Data.WhiteTexture->Bind();
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
s_Data.TextureShader->SetMat4("u_Transform", transform);
s_Data.QuadVertexArray->Bind();
RendererCommand::DrawIndexed(s_Data.QuadVertexArray);
*/
}
void Renderer2D::Shutdown()
{
HZ_PROFILE_FUNCTION();
}
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture, const float tilingFactor, const glm::vec4& tintColor)
{
DrawQuad({position.x, position.y, 0.0f}, size, texture, tilingFactor, tintColor);
}
void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D>& texture, const float tilingFactor, const glm::vec4& tintColor)
{
HZ_PROFILE_FUNCTION();
constexpr glm::vec4 color = {1.0f, 1.0f, 1.0f, 1.0f};
float textureIndex = 0.0f;
auto &a = s_Data;
for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++)
{
if (*s_Data.TextureSlots[i].get() == *texture.get())
{
textureIndex = (float)i;
break;
}
}
if (textureIndex == 0.0f)
{
textureIndex = (float)s_Data.TextureSlotIndex;
s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture;
s_Data.TextureSlotIndex++;
}
s_Data.QuadVertexBufferPtr->Position = position;
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {0.0f, 0.0f};
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadVertexBufferPtr->Position = { position.x + size.x, position.y, 0.0f };
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {1.0f, 0.0f};
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadVertexBufferPtr->Position = {position.x + size.x, position.y + size.y, 0.0f};
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {1.0f, 1.0f};
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadVertexBufferPtr->Position = {position.x, position.y + size.y, 0.0f};
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = {0.0f, 1.0f};
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr ++;
s_Data.QuadIndexCount += 6;
s_Data.TextureShader->SetFloat4("u_Color", tintColor);
s_Data.TextureShader->SetFloat("u_TilingFactor", tilingFactor);
s_Data.TextureShader->Bind();
/*
texture->Bind();
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
s_Data.TextureShader->SetMat4("u_Transform", transform);
s_Data.TextureShader->Bind();
RendererCommand::DrawIndexed(s_Data.QuadVertexArray, s_Data.QuadIndexCount);
*/
}
void Renderer2D::DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, const float rotation,
const glm::vec4& color)
{
DrawRotateQuad({position.x, position.y, 0.0f}, size, rotation, color);
}
void Renderer2D::DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, const float rotation,
const glm::vec4& color)
{
HZ_PROFILE_FUNCTION();
s_Data.TextureShader->SetFloat4("u_Color", color);
s_Data.TextureShader->SetFloat("u_TilingFactor", 1.0f);
s_Data.TextureShader->Bind();
s_Data.WhiteTexture->Bind();
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::rotate(glm::mat4(1.0f), rotation, {0.0f, 0.0f, 1.0f}) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
s_Data.TextureShader->SetMat4("u_Transform", transform);
s_Data.TextureShader->Bind();
RendererCommand::DrawIndexed(s_Data.QuadVertexArray);
}
void Renderer2D::DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, const float rotation,
const Ref<Texture2D>& texture, const float tilingFactor, const glm::vec4& tintColor)
{
DrawRotateQuad({position.x, position.y, 0.0f}, size, rotation, texture, tilingFactor, tintColor);
}
void Renderer2D::DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, const float rotation,
const Ref<Texture2D>& texture, const float tilingFactor, const glm::vec4& tintColor)
{
HZ_PROFILE_FUNCTION();
s_Data.TextureShader->SetFloat4("u_Color", tintColor);
s_Data.TextureShader->SetFloat("u_TilingFactor", tilingFactor);
s_Data.TextureShader->Bind();
texture->Bind();
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::rotate(glm::mat4(1.0f), rotation, {0.0f, 0.0f, 1.0f}) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
s_Data.TextureShader->SetMat4("u_Transform", transform);
s_Data.TextureShader->Bind();
RendererCommand::DrawIndexed(s_Data.QuadVertexArray);
}
}

View File

@ -0,0 +1,39 @@
//
// Created by sfd on 25-5-17.
//
#ifndef RENDERER2D_H
#define RENDERER2D_H
#include "OrthographicCamera.h"
#include "Texture.h"
#include "Hazel/Core/Core.h"
namespace Hazel
{
class HAZEL_API Renderer2D{
public:
static void Init();
static void BeginScene(const OrthographicCamera& camera);
static void EndScene();
static void Flush();
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color);
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color);
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color);
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void Shutdown();
};
}
#endif //RENDERER2D_H

View File

@ -28,7 +28,7 @@ namespace Hazel
virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
virtual void Clear() = 0;
virtual void DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray) = 0;
virtual void DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t indexCount = 0) = 0;
inline static API GetAPI() {return s_API; }

View File

@ -31,9 +31,9 @@ namespace Hazel {
s_RendererAPI->Clear();
}
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray)
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, uint32_t indexCount = 0)
{
s_RendererAPI->DrawIndexed(vertexArray);
s_RendererAPI->DrawIndexed(vertexArray, indexCount);
}

View File

@ -6,7 +6,10 @@
#define SHADER_H
#include <string>
#include <unordered_map>
#include <Hazel/Core.h>
#include <Hazel/Core/Core.h>
#include "glm/fwd.hpp"
#include "glm/detail/func_packing_simd.inl"
namespace Hazel
@ -19,6 +22,14 @@ namespace Hazel
virtual void Bind() const = 0;
virtual void Unbind() const = 0;
virtual void SetFloat(const std::string& name, float value) = 0;
virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0;
virtual void SetFloat4(const std::string& name, const glm::vec4& value) = 0;
virtual void SetMat3(const std::string& name, const glm::mat3& value) = 0;
virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0;
virtual void SetInt(const std::string& name, int value) = 0;
virtual void SetIntv(const std::string& name, int* values, uint32_t count) = 0;
virtual const std::string& GetName() const = 0;
static Ref<Shader> Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc);

View File

@ -8,23 +8,41 @@
namespace Hazel
{
Ref<Texture2D> Texture2D::Create(const std::string& path)
{
Ref<Texture2D> Texture2D::Create(uint32_t width, uint32_t height)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::NONE:
HZ_CORE_ERROR("NONE is not Support!");
return nullptr;
case RendererAPI::API::NONE:
HZ_CORE_ERROR("NONE is not Support!");
return nullptr;
case RendererAPI::API::OPENGL:
// return std::make_shared<VertexBuffer>(OpenGLVertexBuffer(vertices, size));
return std::make_shared<OpenGLTexture2D>(path);
break;
default:
break;
// return std::make_shared<VertexBuffer>(OpenGLVertexBuffer(vertices, size));
return std::make_shared<OpenGLTexture2D>(width, height);
break;
default:
break;
}
HZ_CORE_ERROR("Unknown RendererAPI!");
return nullptr;
}
Ref<Texture2D> Texture2D::Create(const std::string& path)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::NONE:
HZ_CORE_ERROR("NONE is not Support!");
return nullptr;
case RendererAPI::API::OPENGL:
// return std::make_shared<VertexBuffer>(OpenGLVertexBuffer(vertices, size));
return std::make_shared<OpenGLTexture2D>(path);
break;
default:
break;
}
HZ_CORE_ERROR("Unknown RendererAPI!");
return nullptr;
}
}

View File

@ -6,7 +6,7 @@
#define TEXTURE_H
#include <string>
#include <Hazel\Core.h>
#include <Hazel\Core/Core.h>
namespace Hazel
@ -17,10 +17,13 @@ namespace Hazel
virtual ~Texture() = default;
virtual const uint32_t GetWidth() const = 0;
virtual const uint32_t GetHeight() const = 0;
virtual const uint32_t GetRendererID() const = 0;
virtual void Bind(uint32_t slot = 0) const = 0;
private:
virtual void SetData(void* data, uint32_t size) = 0;
virtual bool operator==(const Texture& other) const = 0;
};
@ -30,9 +33,9 @@ namespace Hazel
public:
virtual ~Texture2D() = default;
static Ref<Texture2D> Create(uint32_t width, uint32_t height);
static Ref<Texture2D> Create(const std::string& path);
};
}

View File

@ -14,7 +14,7 @@ namespace Hazel
{
}
VertexArray* VertexArray::Create()
Ref<VertexArray> VertexArray::Create()
{
switch (Renderer::GetAPI())
{
@ -22,8 +22,7 @@ namespace Hazel
HZ_CORE_ERROR("NONE is not Support!");
return nullptr;
case RendererAPI::API::OPENGL:
return new OpenGLVertexArray();
break;
return std::make_shared<OpenGLVertexArray>();
default:
break;
}

View File

@ -27,7 +27,7 @@ namespace Hazel
virtual const std::vector<std::shared_ptr<VertexBuffer>>& GetVertexBuffer() const = 0;
virtual const std::shared_ptr<IndexBuffer>& GetIndexBuffer() const = 0;
static VertexArray* Create();
static Ref<VertexArray> Create();
};
}

View File

@ -5,6 +5,7 @@
#include "OpenGLBuffer.h"
#include <glad/glad.h>
#include <Hazel/Debug/Instrumentor.h>
namespace Hazel
{
@ -14,32 +15,51 @@ namespace Hazel
////////////////////////////////////////////////////////////////////
OpenGLVertexBuffer::OpenGLVertexBuffer(float* vertices, uint32_t size)
{
HZ_PROFILE_FUNCTION();
glCreateBuffers(1, &m_RendererID);
glBindBuffer(GL_ARRAY_BUFFER, m_RendererID);
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
}
OpenGLVertexBuffer::OpenGLVertexBuffer(uint32_t size)
{
HZ_PROFILE_FUNCTION();
glCreateBuffers(1, &m_RendererID);
glBindBuffer(GL_ARRAY_BUFFER, m_RendererID);
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW);
}
OpenGLVertexBuffer::~OpenGLVertexBuffer()
{
HZ_PROFILE_FUNCTION();
glDeleteBuffers(1, &m_RendererID);
}
void OpenGLVertexBuffer::Bind() const
{
HZ_PROFILE_FUNCTION();
glBindBuffer(GL_ARRAY_BUFFER, m_RendererID);
}
void OpenGLVertexBuffer::Unbind() const
{
HZ_PROFILE_FUNCTION();
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void OpenGLVertexBuffer::SetData(const void* data, uint32_t size)
{
glBindBuffer(GL_ARRAY_BUFFER, m_RendererID);
glBufferSubData(GL_ARRAY_BUFFER, 0, size, data);
}
////////////////////////////////////////////////////////////////////
////////////////////// IndexBuffer ///////////////////////////
////////////////////////////////////////////////////////////////////
OpenGLIndexBuffer::OpenGLIndexBuffer(uint32_t* indices, uint32_t count) : m_Count(count)
{
HZ_PROFILE_FUNCTION();
glCreateBuffers(1, &m_RendererID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(uint32_t), indices, GL_STATIC_DRAW);
@ -47,16 +67,19 @@ namespace Hazel
OpenGLIndexBuffer::~OpenGLIndexBuffer()
{
HZ_PROFILE_FUNCTION();
glDeleteBuffers(1, &m_RendererID);
}
void OpenGLIndexBuffer::Bind() const
{
HZ_PROFILE_FUNCTION();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID);
}
void OpenGLIndexBuffer::Unbind() const
{
HZ_PROFILE_FUNCTION();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

View File

@ -12,11 +12,13 @@ namespace Hazel
class OpenGLVertexBuffer : public VertexBuffer
{
public:
OpenGLVertexBuffer(uint32_t size);
OpenGLVertexBuffer(float* vertices, uint32_t size);
virtual ~OpenGLVertexBuffer();
virtual void Bind() const override;
virtual void Unbind() const override;
virtual void SetLayout(const BufferLayout& layout) override {m_Layout = layout;}
virtual void SetData(const void* data, uint32_t size) override;
virtual const BufferLayout& GetLayout() const override {return m_Layout;}
private:
uint32_t m_RendererID;

View File

@ -4,7 +4,8 @@
#include "OpenGLContext.h"
#include <Hazel/Log.h>
#include <Hazel/Core/Log.h>
#include <Hazel/Debug/Instrumentor.h>
#include <SDL3/SDL_opengl.h>
@ -16,6 +17,7 @@ namespace Hazel
void OpenGLContext::Init()
{
HZ_PROFILE_FUNCTION();
m_GLContext = SDL_GL_CreateContext(m_windowHandle);
if (!m_GLContext)
{
@ -34,6 +36,7 @@ namespace Hazel
void OpenGLContext::SwapBuffers()
{
HZ_PROFILE_FUNCTION();
SDL_GL_SwapWindow(m_windowHandle);
}

View File

@ -4,13 +4,16 @@
#include "OpenGLRendererAPI.h"
#include <Hazel/Debug/Instrumentor.h>
#include <SDL3/SDL_opengl.h>
namespace Hazel
{
void OpenGLRendererAPI::Init()
{
HZ_PROFILE_FUNCTION();
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
@ -30,8 +33,10 @@ namespace Hazel
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray)
void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t indexCount)
{
glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, 0);
uint32_t count = indexCount == 0 ? vertexArray->GetIndexBuffer()->GetCount() : indexCount;
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
}

View File

@ -16,7 +16,7 @@ namespace Hazel
virtual void SetClearColor(const glm::vec4& color) override;
virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
virtual void Clear() override;
virtual void DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray) override;
virtual void DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t indexCount = 0) override;
};
}

View File

@ -7,7 +7,8 @@
#include <fstream>
#include <vector>
#include <array>
#include <Hazel/Log.h>
#include <Hazel/Core/Log.h>
#include <Hazel/Debug/Instrumentor.h>
#include "glm/gtc/type_ptr.hpp"
#include "spdlog/fmt/bundled/compile.h"
@ -27,6 +28,7 @@ namespace Hazel
OpenGLShader::OpenGLShader(const std::string& filepath)
{
HZ_PROFILE_FUNCTION();
std::string shaderSrc = ReadFile(filepath);
auto shaderSources = PreProcess(shaderSrc);
Compile(shaderSources);
@ -48,6 +50,7 @@ namespace Hazel
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc): m_Name(name)
{
HZ_PROFILE_FUNCTION();
std::unordered_map<GLenum, std::string> shaderSources;
shaderSources[GL_VERTEX_SHADER] = vertexSrc;
shaderSources[GL_FRAGMENT_SHADER] = fragmentSrc;
@ -57,40 +60,70 @@ namespace Hazel
OpenGLShader::~OpenGLShader()
{
HZ_PROFILE_FUNCTION();
glDeleteProgram(m_RendererID);
}
void OpenGLShader::Bind() const
{
HZ_PROFILE_FUNCTION();
glUseProgram(m_RendererID);
}
void OpenGLShader::Unbind() const
{
HZ_PROFILE_FUNCTION();
glUseProgram(0);
}
void OpenGLShader::UploadUniformFloat3(const std::string& name, const glm::vec3& value) const
void OpenGLShader::SetFloat(const std::string& name, const float value)
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform4fv(location, 1, glm::value_ptr(value));
HZ_PROFILE_FUNCTION();
UploadUniformFloat(name, value);
}
void OpenGLShader::UploadUniformFloat4(const std::string& name, const glm::vec4& value) const
void OpenGLShader::SetFloat3(const std::string& name, const glm::vec3& value)
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform4fv(location, 1, glm::value_ptr(value));
HZ_PROFILE_FUNCTION();
UploadUniformFloat3(name, value);
}
void OpenGLShader::UploadUniformMat4(const std::string& name, const glm::mat4& matrix) const
void OpenGLShader::SetFloat4(const std::string& name, const glm::vec4& value)
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
HZ_PROFILE_FUNCTION();
UploadUniformFloat4(name, value);
}
void OpenGLShader::SetMat3(const std::string& name, const glm::mat3& value)
{
HZ_PROFILE_FUNCTION();
UploadUniformMat3(name, value);
}
void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value)
{
HZ_PROFILE_FUNCTION();
UploadUniformMat4(name, value);
}
void OpenGLShader::SetInt(const std::string& name, int value)
{
HZ_PROFILE_FUNCTION();
UploadUniformInt(name, value);
}
void OpenGLShader::SetIntv(const std::string& name, int* values, uint32_t count)
{
HZ_PROFILE_FUNCTION();
UploadUniformIntv(name, values, count);
}
std::string OpenGLShader::ReadFile(const std::string& filepath)
{
std::ifstream in(filepath, std::ios::in, std::ios::binary); // window platform api
HZ_PROFILE_FUNCTION();
std::ifstream in(filepath, std::ios::in | std::ios::binary);
// std::ifstream in(filepath, std::ios::in, std::ios::binary); // window platform api
if (!in.is_open())
{
HZ_CORE_ERROR("Failed to open shader file {0}", filepath);
@ -109,6 +142,7 @@ namespace Hazel
std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& source)
{
HZ_PROFILE_FUNCTION();
std::unordered_map<GLenum, std::string> shaderSource;
const char* typeToken = "#type";
size_t typeTokenLength = strlen(typeToken);
@ -141,7 +175,7 @@ namespace Hazel
void OpenGLShader::Compile(std::unordered_map<GLenum, std::string>& shaderSource)
{
HZ_PROFILE_FUNCTION();
GLuint program = glCreateProgram();
// std::vector<GLenum> glShaderIDs;
// glShaderIDs.reserve(shaderSource.size());
@ -215,9 +249,45 @@ namespace Hazel
m_RendererID = program;
}
void OpenGLShader::UploadUniformInt(const char* str, const int value) const
void OpenGLShader::UploadUniformFloat3(const std::string& name, const glm::vec3& value) const
{
const GLint location = glGetUniformLocation(m_RendererID, str);
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform4fv(location, 1, glm::value_ptr(value));
}
void OpenGLShader::UploadUniformFloat4(const std::string& name, const glm::vec4& value) const
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform4fv(location, 1, glm::value_ptr(value));
}
void OpenGLShader::UploadUniformMat3(const std::string& name, const glm::mat3& matrix) const
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
}
void OpenGLShader::UploadUniformMat4(const std::string& name, const glm::mat4& matrix) const
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
}
void OpenGLShader::UploadUniformInt(const std::string& name, const int value) const
{
const GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform1i(location, value);
}
void OpenGLShader::UploadUniformIntv(const std::string& name, int* values, uint32_t count) const
{
const GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform1iv(location, count, values);
}
void OpenGLShader::UploadUniformFloat(const std::string& name, const float value) const
{
const GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform1f(location, value);
}
}

View File

@ -25,10 +25,21 @@ namespace Hazel
virtual const std::string& GetName() const override {return m_Name;}
void UploadUniformInt(const char* str, int value) const;
virtual void SetFloat(const std::string& name, float value) override;
virtual void SetFloat3(const std::string& name, const glm::vec3& value) override;
virtual void SetFloat4(const std::string& name, const glm::vec4& value) override;
virtual void SetMat3(const std::string& name, const glm::mat3& value) override;
virtual void SetMat4(const std::string& name, const glm::mat4& value) override;
virtual void SetInt(const std::string& name, int value) override;
virtual void SetIntv(const std::string& name, int* values, uint32_t count) override;
void UploadUniformInt(const std::string& name, int value) const;
void UploadUniformIntv(const std::string& name, int* values, uint32_t count) const;
void UploadUniformFloat(const std::string& name, float value) const;
void UploadUniformFloat3(const std::string& name, const glm::vec3& value) const;
void UploadUniformFloat4(const std::string& name, const glm::vec4& value) const;
void UploadUniformMat3(const std::string& name, const glm::mat3& matrix) const;
void UploadUniformMat4(const std::string& name, const glm::mat4& matrix) const;
private:

View File

@ -4,19 +4,40 @@
#include "OpenGLTexture.h"
#include <glad/glad.h>
#include <Hazel/Log.h>
#include <Hazel/Core/Log.h>
#include <Hazel/Debug/Instrumentor.h>
#include "stb_image.h"
namespace Hazel
{
OpenGLTexture2D::OpenGLTexture2D(uint32_t width, uint32_t height) : m_Width(width), m_Height(height)
{
HZ_PROFILE_FUNCTION();
m_InternalFormat = GL_RGBA8;
m_DataFormat = GL_RGBA;
glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID);
glTextureStorage2D(m_RendererID, 1, m_InternalFormat, m_Width, m_Height);
glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
OpenGLTexture2D::OpenGLTexture2D(const std::string& path) : m_Path(path)
{
HZ_PROFILE_FUNCTION();
int width, height, channels;
stbi_set_flip_vertically_on_load(1);
stbi_uc* data = stbi_load(path.c_str(), &width, &height, &channels, 0);
stbi_uc* data = nullptr;
{
HZ_PROFILE_SCOPE("stbi_load OpenGLTexture2D::OpenGlTexture2D(const std::string&)");
data = stbi_load(path.c_str(), &width, &height, &channels, 0);
}
if (!data)
{
HZ_CORE_ERROR("Failed to load texture {0}", path);
@ -33,6 +54,9 @@ namespace Hazel
dataFormat = GL_RGB;
}
m_InternalFormat = internalFormat;
m_DataFormat = dataFormat;
HZ_CORE_TRACE("Texture Info: {0}", path);
HZ_CORE_TRACE(" Width: {0}, Height: {1}, Channel: {2}", m_Width, m_Height, channels);
@ -43,6 +67,8 @@ namespace Hazel
glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, dataFormat, GL_UNSIGNED_BYTE, data);
@ -52,11 +78,24 @@ namespace Hazel
OpenGLTexture2D::~OpenGLTexture2D()
{
HZ_PROFILE_FUNCTION();
glDeleteTextures(1, &m_RendererID);
}
void OpenGLTexture2D::Bind(uint32_t slot) const
{
HZ_PROFILE_FUNCTION();
glBindTextureUnit(slot, m_RendererID);
}
void OpenGLTexture2D::SetData(void* data, uint32_t size)
{
HZ_PROFILE_FUNCTION();
uint32_t bpc = m_DataFormat == GL_RGBA ? 4 : 3;
if (!size == (m_Width * m_Height * bpc))
{
HZ_CORE_ERROR("data must be entire texture!");
}
glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_DataFormat, GL_UNSIGNED_BYTE, data);
}
}

View File

@ -5,29 +5,35 @@
#ifndef OPENGLTEXTURE_H
#define OPENGLTEXTURE_H
#include <Hazel/Renderer/Texture.h>
#include <glad/glad.h>
namespace Hazel
{
class OpenGLTexture2D : public Hazel::Texture2D
{
public:
OpenGLTexture2D(uint32_t width, uint32_t height);
OpenGLTexture2D(const std::string& path);
virtual ~OpenGLTexture2D();
virtual const uint32_t GetWidth() const override {return m_Width; }
virtual const uint32_t GetHeight() const override { return m_Height; }
virtual void Bind(uint32_t slot) const override;
virtual void Bind(uint32_t slot = 0) const override;
uint32_t GetRendererID() const { return m_RendererID; }
virtual void SetData(void* data, uint32_t size) override;
const uint32_t GetRendererID() const override { return m_RendererID; }
virtual bool operator==(const Texture& other) const override
{
return m_RendererID == ((OpenGLTexture2D&)other).m_RendererID;
}
private:
std::string m_Path;
uint32_t m_Width, m_Height;
uint32_t m_RendererID;
GLenum m_InternalFormat, m_DataFormat;
};
}

View File

@ -5,6 +5,7 @@
#include "OpenGLVertexArray.h"
#include <glad/glad.h>
#include <Hazel/Debug/Instrumentor.h>
namespace Hazel
{
@ -31,26 +32,31 @@ namespace Hazel
OpenGLVertexArray::OpenGLVertexArray()
{
HZ_PROFILE_FUNCTION();
glCreateVertexArrays(1, &m_RendererID);
}
OpenGLVertexArray::~OpenGLVertexArray()
{
HZ_PROFILE_FUNCTION();
glDeleteVertexArrays(1, &m_RendererID);
}
void OpenGLVertexArray::Bind() const
{
HZ_PROFILE_FUNCTION();
glBindVertexArray(m_RendererID);
}
void OpenGLVertexArray::Unbind() const
{
HZ_PROFILE_FUNCTION();
glBindVertexArray(0);
}
void OpenGLVertexArray::AddVertexBuffer(const std::shared_ptr<VertexBuffer>& vertexBuffer)
{
HZ_PROFILE_FUNCTION();
glBindVertexArray(m_RendererID);
vertexBuffer->Bind();

View File

@ -5,11 +5,10 @@
#include "WindowsWindow.h"
#include <iostream>
#include <Hazel/Log.h>
#include <Hazel/Core/Log.h>
#include <Platform/OpenGL/OpenGLContext.h>
#include <glad/glad.h>
#include "glm/gtc/constants.hpp"
#include <Hazel/Debug/Instrumentor.h>
namespace Hazel
@ -18,6 +17,7 @@ namespace Hazel
WindowsWindow::WindowsWindow(const WindowProps& props)
{
HZ_PROFILE_FUNCTION();
Init(props);
}
@ -28,11 +28,13 @@ namespace Hazel
WindowsWindow::~WindowsWindow()
{
HZ_PROFILE_FUNCTION();
Shutdown();
}
void WindowsWindow::Init(const WindowProps& props)
{
HZ_PROFILE_FUNCTION();
m_Data.title = props.title;
m_Data.width = props.width;
m_Data.height = props.height;
@ -58,13 +60,15 @@ namespace Hazel
exit(EXIT_FAILURE);
}
m_Context = new OpenGLContext(m_Window);
m_Context->Init();
m_windowID = SDL_GetWindowID(m_Window);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
m_Context = new OpenGLContext(m_Window);
m_Context->Init();
HZ_CORE_INFO("Initing GLAD...");
if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(SDL_GL_GetProcAddress)))
@ -79,17 +83,19 @@ namespace Hazel
void WindowsWindow::Shutdown()
{
HZ_PROFILE_FUNCTION();
SDL_DestroyWindow(m_Window);
SDL_Quit();
}
void WindowsWindow::OnUpdate()
{
HZ_PROFILE_FUNCTION();
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_EVENT_WINDOW_RESIZED)
if (event.type == SDL_EVENT_WINDOW_RESIZED && event.window.windowID == m_windowID)
{
m_Data.width = event.window.data1;
m_Data.height = event.window.data2;
@ -110,6 +116,7 @@ namespace Hazel
void WindowsWindow::SetVSync(bool enabled)
{
HZ_PROFILE_FUNCTION();
if (enabled)
{
SDL_GL_SetSwapInterval(enabled);

View File

@ -7,7 +7,7 @@
#include <Hazel/Renderer/GraphicsContext.h>
#include "Hazel/Window.h"
#include "Hazel/Core/Window.h"
#include <SDL3/SDL.h>
@ -28,12 +28,13 @@ namespace Hazel
inline unsigned int GetHeight() const override { return m_Data.height; }
// Window attributes
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.eventCallback = callback; }
inline void SetWindowResizeEventCallback(const WindowsResizeCallbackFn& callback) override {OnWindowResize = callback;}
void SetVSync(bool enabled) override;
bool IsVSync() const override;
virtual Uint32 GetMainWindowID() const override {return m_windowID; }
void* GetNativeWindow() const override {return m_Window;}
void* GetNativeGLContext() const override {return m_Context->GetGLContext();}
@ -43,6 +44,7 @@ namespace Hazel
private:
SDL_Window* m_Window;
Uint32 m_windowID;
GraphicsContext* m_Context;
struct WindowData

View File

@ -1,9 +1,23 @@
set(PROJECT_NAME "Sandbox")
project(${PROJECT_NAME})
file(GLOB_RECURSE SOURCES "src/*.cpp")
# SandBox
project(${PROJECT_NAME})
file(GLOB_RECURSE SOURCES
src/SandboxApp.cpp
src/SandBox2D/*.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} PRIVATE Hazel)
# demo App
set(DEMO_PROJECT "${PROJECT_NAME}-Demo")
file(GLOB_RECURSE DEMO_SOURCES
src/SandboxApp.cpp
src/DemoBox/*.cpp)
add_executable(${DEMO_PROJECT} ${DEMO_SOURCES})
target_link_libraries(${DEMO_PROJECT} PRIVATE Hazel)

View File

@ -0,0 +1,26 @@
// Flat Color Shader
#type vertex
#version 460 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoord;
uniform mat4 u_ViewProjection;
uniform mat4 u_Transform;
void main() {
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f);
}
#type fragment
#version 460 core
layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main() {
color = u_Color;
}

View File

@ -2,16 +2,23 @@
#version 460 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoord;
layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec2 a_TexCoord;
layout(location = 3) in float a_TexIndex;
uniform mat4 u_ViewProjection;
uniform mat4 u_Transform;
//uniform mat4 u_Transform;
out vec2 v_TexCoord;
out vec4 v_Color;
out float v_TexIndex;
void main() {
v_TexCoord = a_TexCoord;
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f);
v_Color = a_Color;
v_TexIndex = a_TexIndex;
gl_Position = u_ViewProjection * vec4(a_Position, 1.0f);
}
#type fragment
@ -20,19 +27,15 @@ void main() {
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
in vec4 v_Color;
in float v_TexIndex;
uniform sampler2D u_Texture;
uniform float u_TilingFactor;
uniform vec4 u_Color;
uniform sampler2D u_Textures[32];
void main() {
vec4 tmpColor = texture(u_Texture, v_TexCoord);
if(gl_FragCoord.x < 635){
color = tmpColor;
}
else{
if(tmpColor.a < 0.1){
discard;
}else{
color = vec4(v_TexCoord, 0.0f, 1.0f);
}
}
color = texture(u_Textures[int(v_TexIndex)], v_TexCoord * u_TilingFactor) * v_Color;
// color = v_Color;
}

View File

@ -0,0 +1,59 @@
//
// Created by sfd on 25-5-18.
//
#include "GameLayer.h"
#include <imgui_internal.h>
#include <Hazel/Core/Application.h>
GameLayer::GameLayer() : Layer("GameLayer")
{
auto& window = Application::Get().GetWindow();
CreateCamera(window.GetWidth(), window.GetHeight());
Random::Init();
}
void GameLayer::OnAttach()
{
m_Level.Init();
ImGuiIO& io = ImGui::GetIO();
}
void GameLayer::OnDetech()
{
}
void GameLayer::OnUpdate(TimeStep& ts)
{
m_Time += ts;
}
void GameLayer::OnEvent(SDL_Event& e)
{
if (const auto& window = Application::Get().GetWindow(); e.type == SDL_EVENT_WINDOW_RESIZED && e.window.windowID == window.GetMainWindowID())
{
CreateCamera(window.GetWidth(), window.GetHeight());
}
}
void GameLayer::OnImGuiRender()
{
}
void GameLayer::CreateCamera(uint32_t width, uint32_t height)
{
const float aspect = static_cast<float>(width) / static_cast<float>(height);
const float camWidth = 8.0f;
const float bottom = -camWidth;
const float top = camWidth;
const float left = bottom * aspect;
const float right = top * aspect;
m_Camera = OrthographicCamera(left, right, bottom, top);
}

View File

@ -0,0 +1,43 @@
//
// Created by sfd on 25-5-18.
//
#ifndef GAMELAYER_H
#define GAMELAYER_H
#include <Hazel/Core/Layer.h>
#include <Hazel/Renderer/OrthographicCamera.h>
#include "Random.h"
using namespace Hazel;
class GameLayer : public Layer{
public:
GameLayer();
~GameLayer() = default;
void OnAttach() override;
void OnDetech() override;
void OnUpdate(TimeStep& ts) override;
void OnEvent(SDL_Event& e) override;
void OnImGuiRender() override;
void CreateCamera(uint32_t width, uint32_t height);
private:
std::unique_ptr<OrthographicCamera> m_Camera;
float m_Time = 0.0f;
bool m_Blink = false;
enum class GameState
{
Play = 0, MainMenu, GameOver
};
GameState m_GameState = GameState::MainMenu;
};
#endif //GAMELAYER_H

View File

@ -0,0 +1,5 @@
//
// Created by sfd on 25-5-18.
//
#include "Random.h"

View File

@ -0,0 +1,28 @@
//
// Created by sfd on 25-5-18.
//
#ifndef RANDOM_H
#define RANDOM_H
#include <random>
class Random {
public:
static void Init() {
s_RandomEngine.seed(std::random_device()());
}
static float Float()
{
return (float)s_Distribution(s_RandomEngine) / (float)std::numeric_limits<uint32_t>::max();
}
private:
static std::mt19937 s_RandomEngine;
static std::uniform_int_distribution<std::mt19937::result_type> s_Distribution;
};
#endif //RANDOM_H

View File

@ -0,0 +1,99 @@
//
// Created by sfd on 25-5-17.
//
#include "SandBox2D.h"
#include <imgui.h>
#include "glm/gtc/type_ptr.hpp"
SandBox2D::SandBox2D()
: Layer("SandBox2D"), m_CameraController(1280.f /720.f)
{
}
void SandBox2D::OnAttach()
{
HZ_PROFILE_FUNCTION();
m_LogoTexture = Hazel::Texture2D::Create("assets/textures/iceLogo.png");
}
void SandBox2D::OnDetech()
{
HZ_PROFILE_FUNCTION();
}
void SandBox2D::OnUpdate(Hazel::TimeStep& ts)
{
// PROFILE_SCOPE("SandBox2D::OnUpdate");
HZ_PROFILE_FUNCTION();
m_CameraController.OnUpdate(ts);
{
HZ_PROFILE_SCOPE("Renderer Prep");
Hazel::RendererCommand::SetClearColor({0.2f, 0.2f, 0.2f, 1.0f});
Hazel::RendererCommand::Clear();
}
{
HZ_PROFILE_SCOPE("Renderer Draw");
Hazel::Renderer2D::BeginScene(m_CameraController.GetCamera());
// Hazel::Renderer2D::DrawQuad({0.0f, 0.0f}, {0.31f, 0.31f}, {0.2f, 0.3f, 0.8f, 1.0f});
Hazel::Renderer2D::DrawQuad({-1.0f, 0.0f}, {0.7f, 0.7f}, {0.2f, 0.3f, 0.8f, 1.0f});
Hazel::Renderer2D::DrawQuad({0.5f, 0.5f}, {0.5f, 0.7f}, {0.8f, 0.2f, 0.3f, 1.0f});
// Hazel::Renderer2D::DrawQuad({0.0f, 0.0f, -0.1f}, {2.0f, 2.0f}, m_LogoTexture, 10.0f);
// Hazel::Renderer2D::DrawRotateQuad({0.0f, 0.0f, 0.1f}, {2.0f, 2.0f}, glm::radians(45.f), m_LogoTexture, 10.0f, glm::vec4(1.0f, 1.0f, 1.0f, 1.f));
Hazel::Renderer2D::DrawQuad({0.0f, 0.0f, -0.1f}, {2.0f, 2.0f}, m_LogoTexture, 10.0f);
Hazel::Renderer2D::EndScene();
}
/*
std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_FlatColorShader)->Bind();
std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_FlatColorShader)->UploadUniformFloat4("u_Color", m_SquareColor);
Hazel::Renderer::Submit(m_FlatColorShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
*/
}
void SandBox2D::OnImGuiRender()
{
const auto cameraRotation = m_CameraController.GetCamera().GetRotation();
const auto cameraPosition = m_CameraController.GetCamera().GetPosition();
const auto windowWidth = Hazel::Application::Get().GetWindow().GetWidth();
const auto windowHeight = Hazel::Application::Get().GetWindow().GetHeight();
ImGui::Begin("Hazel Layer");
ImGui::Text("WindowSize: (%u, %u)", windowWidth, windowHeight);
ImGui::Text("Camera");
ImGui::Text("Rotation: %f", cameraRotation);
ImGui::Text("Position: ( %.2f, %.2f, %.2f)", cameraPosition.x, cameraPosition.y, cameraPosition.z);
ImGui::NewLine();
ImGui::Text("frame: %.3f", ImGui::GetIO().Framerate);
ImGui::ColorEdit3("Square Color", glm::value_ptr(m_SquareColor));
ImGui::NewLine();
for (auto& profileResult : m_ProfileResults)
{
ImGui::Text("%s: %.3fms", profileResult.Name, profileResult.Time);
}
m_ProfileResults.clear();
ImGui::NewLine();
static bool isSync = Hazel::Application::Get().GetWindow().IsVSync();
bool laststate = isSync;
ImGui::Checkbox("isVSync", &isSync);
if (isSync != laststate)
{
Hazel::Application::Get().GetWindow().SetVSync(isSync);
}
ImGui::End();
}
void SandBox2D::OnEvent(SDL_Event& e)
{
m_CameraController.OnEvent(e);
}

View File

@ -0,0 +1,40 @@
//
// Created by sfd on 25-5-17.
//
#ifndef SANDBOX2D_H
#define SANDBOX2D_H
#include <Hazel.h>
class SandBox2D : public Hazel::Layer{
public:
SandBox2D();
virtual ~SandBox2D() = default;
virtual void OnAttach() override;
virtual void OnDetech() override;
void OnUpdate(Hazel::TimeStep& ts) override;
virtual void OnImGuiRender() override;
void OnEvent(SDL_Event& e) override;
private:
Hazel::OrthographicCameraController m_CameraController;
Hazel::Ref<Hazel::VertexArray> m_SquareVA;
Hazel::Ref<Hazel::Shader> m_FlatColorShader;
Hazel::Ref<Hazel::Texture2D> m_Texture;
Hazel::Ref<Hazel::Texture2D> m_LogoTexture;
glm::vec4 m_SquareColor = {0.2f, 0.3f, 0.8f, 1.0f};
struct ProfileResult
{
const char* Name;
float Time;
};
std::vector<ProfileResult> m_ProfileResults;
};
#endif //SANDBOX2D_H

View File

@ -1,27 +1,20 @@
#include <Hazel.h>
#include "Hazel/Core/EntryPoint.h"
#include "imgui.h"
#define GLM_ENABLE_EXPERIMENTAL
#include <Hazel/OrthographicCameraController.h>
#include <Platform/OpenGL/OpenGLShader.h>
#include <Platform/OpenGL/OpenGLTexture.h>
#include "glm/gtc/type_ptr.hpp"
#include "glm/gtx/transform.hpp"
// #include "SandBox2D/SandBox2D.h"
// #include "DemoBox/GameLayer.h"
#include "SandBox2D/SandBox2D.h"
/*
class ExampleLayer : public Hazel::Layer
{
public:
// ExampleLayer() : Layer("ExampleLayer"), m_Camera(-1.0f, 1.0f, -1.0f, 1.0f), m_CameraPosition(0.0f)
ExampleLayer() : Layer("ExampleLayer"), m_CameraController(1280.0f / 720.0f), m_SquarePosition(glm::vec3(0.0f))
{
// ------------------------------------------------------------test------------------------------------------------------------
// Vertex Array
m_VertexArray.reset(Hazel::VertexArray::Create());
m_VertexArray = Hazel::VertexArray::Create();
// Vertex Buffer
float vertices[3 * 7] = {
@ -79,7 +72,7 @@ public:
m_Shader = Hazel::Shader::Create("demoShader", vertexSrc, fragmentSrc);
m_SquareVA.reset(Hazel::VertexArray::Create());
m_SquareVA = Hazel::VertexArray::Create();
float squareVertices[5 * 4] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
@ -233,6 +226,8 @@ private:
glm::vec4 m_ScreenClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
};
*/
class Sandbox : public Hazel::Application
@ -240,7 +235,8 @@ class Sandbox : public Hazel::Application
public:
Sandbox()
{
PushLayer(new ExampleLayer());
// PushLayer(new ExampleLayer());
PushLayer(new SandBox2D());
}
~Sandbox();