增加窗口自由缩放

This commit is contained in:
2025-05-16 15:55:00 +08:00
parent 6b3f6fc521
commit f6ccb823c7
23 changed files with 549 additions and 185 deletions

View File

@ -24,6 +24,7 @@ namespace Hazel {
m_Window = std::unique_ptr<Window>(Window::Create());
m_Window->SetEventCallback(std::bind(&Application::OnEvent, this, std::placeholders::_1));
m_Window->SetWindowResizeEventCallback(std::bind(&Application::OnWindowResize, this, std::placeholders::_1));
Renderer::Init();
@ -44,6 +45,8 @@ namespace Hazel {
m_lastFrameTime = currentTime;
if (!m_Minimized)
{
for (Layer* layer : m_layerStack)
{
layer->OnUpdate(timestep);
@ -55,9 +58,7 @@ namespace Hazel {
layer->OnImGuiRender();
}
m_imguiLayer->End();
// HZ_CORE_INFO("{}", Input::IsKeyPressed(HZ_KEY_0));
}
m_Window->OnUpdate();
}
@ -71,12 +72,29 @@ namespace Hazel {
(*--it)->OnEvent(e);
}
if (e.type == SDL_EVENT_QUIT)
switch (e.type)
{
case SDL_EVENT_QUIT:
m_Running = false;
break;
case SDL_EVENT_WINDOW_MINIMIZED:
m_Minimized = true;
break;
case SDL_EVENT_WINDOW_RESTORED:
m_Minimized = false;
break;
default:
break;
}
}
void Application::OnWindowResize(SDL_Event& e)
{
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)
{
m_layerStack.PushLayer(layer);

View File

@ -19,6 +19,7 @@ namespace Hazel {
void Run();
void OnEvent(SDL_Event& e);
void OnWindowResize(SDL_Event& e);
void PushLayer(Layer* layer);
void PushOverlay(Layer* layer);
inline Window& GetWindow() { return *m_Window; }
@ -34,6 +35,7 @@ namespace Hazel {
TimeStep m_TimeStep;
float m_lastFrameTime = 0.0f;
bool m_Minimized = false;
private:
static Application* s_Instance;
};

View File

@ -63,7 +63,6 @@ namespace Hazel
void ImGuiLayer::OnImGuiRender()
{
ImGui::ShowDemoWindow();
}
void ImGuiLayer::Begin()

View File

@ -2,6 +2,11 @@
#include <spdlog/sinks/stdout_color_sinks.h>
#ifdef _DEBUG
#define LOG_LEVEL spdlog::level::trace
#else
#define LOG_LEVEL spdlog::level::debug
#endif
namespace Hazel {
@ -11,10 +16,10 @@ namespace Hazel {
void Log::init() {
spdlog::set_pattern("%^[%T] %n: %v%$");
s_CoreLogger = spdlog::stdout_color_mt("Hazel");
s_CoreLogger->set_level(spdlog::level::trace);
s_CoreLogger->set_level(LOG_LEVEL);
s_ClientLogger = spdlog::stdout_color_mt("App");
s_ClientLogger->set_level(spdlog::level::trace);
s_ClientLogger->set_level(LOG_LEVEL);
}
}

View File

@ -0,0 +1,82 @@
//
// Created by sfd on 25-5-12.
//
#include "OrthographicCameraController.h"
namespace Hazel
{
OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool isRotation) : m_AspectRatio(aspectRatio), m_Camera(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel), m_isRotation(isRotation)
{
}
void OrthographicCameraController::OnUpdate(TimeStep ts)
{
const bool* state = SDL_GetKeyboardState(NULL);
float time = ts;
if (state[SDL_SCANCODE_A])
{
m_CameraPosition.x -= m_CameraTranslationSpeed * time;
}
else if (state[SDL_SCANCODE_D])
{
m_CameraPosition.x += m_CameraTranslationSpeed * time;
}
if (state[SDL_SCANCODE_W])
{
m_CameraPosition.y += m_CameraTranslationSpeed * time;
}
else if (state[SDL_SCANCODE_S])
{
m_CameraPosition.y -= m_CameraTranslationSpeed * time;
}
if (m_isRotation)
{
if (state[SDL_SCANCODE_Q])
{
m_CameraRotation += m_CameraRotationSpeed * time;
}
else if (state[SDL_SCANCODE_E])
{
m_CameraRotation -= m_CameraRotationSpeed * time;
}
m_Camera.SetRotation(m_CameraRotation);
}
m_Camera.SetPosition(m_CameraPosition);
m_CameraTranslationSpeed = m_ZoomLevel;
}
void OrthographicCameraController::OnEvent(SDL_Event& e)
{
OnMouseScrolled(e);
OnWindowResized(e);
}
bool OrthographicCameraController::OnMouseScrolled(SDL_Event& e)
{
if (e.type == SDL_EVENT_MOUSE_WHEEL)
{
m_ZoomLevel += e.wheel.y * 0.25f;
m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
return false;
}
return true;
}
bool OrthographicCameraController::OnWindowResized(SDL_Event& e)
{
if (e.type == SDL_EVENT_WINDOW_RESIZED)
{
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);
return false;
}
return true;
}
}

View File

@ -0,0 +1,49 @@
//
// Created by sfd on 25-5-12.
//
#ifndef ORTHOGRAPHICCAMERACONTROLLER_H
#define ORTHOGRAPHICCAMERACONTROLLER_H
#include <SDL3/SDL_events.h>
#include "Core.h"
#include "Core/TimeStep.h"
#include "Renderer/OrthographicCamera.h"
namespace Hazel
{
class HAZEL_API OrthographicCameraController
{
public:
OrthographicCameraController(float aspectRatio, bool isRotation = false);
void SetProjection(float left, float right, float bottom, float top);
void OnUpdate(TimeStep ts);
void OnEvent(SDL_Event& e);
OrthographicCamera& GetCamera() {return m_Camera;}
const OrthographicCamera& GetCamera() const {return m_Camera;}
private:
bool OnMouseScrolled(SDL_Event& e);
bool OnWindowResized(SDL_Event& e);
private:
float m_AspectRatio;
float m_ZoomLevel = 1.0f;
OrthographicCamera m_Camera;
bool m_isRotation;
glm::vec3 m_CameraPosition = { 0.0f, 0.0f, 0.0f };
float m_CameraRotation = 0.0f;
float m_CameraTranslationSpeed = 20.0f, m_CameraRotationSpeed = 30.0f;
};
}
#endif //ORTHOGRAPHICCAMERACONTROLLER_H

View File

@ -16,6 +16,12 @@ namespace Hazel
}
void OrthographicCamera::SetProjection(float left, float right, float bottom, float top)
{
m_ProjectionMatrix = glm::ortho(left, right, bottom, top, -1.0f, 1.0f);
m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
}
void OrthographicCamera::RecalculateViewMatrix()
{
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));

View File

@ -14,7 +14,7 @@ namespace Hazel
{
public:
OrthographicCamera(float left, float right, float bottom, float top);
void SetProjection(float left, float right, float bottom, float top);
const glm::vec3& GetPosition() const { return m_Position; }

View File

@ -4,7 +4,6 @@
#include "Renderer.h"
#include <SDL3/SDL_opengl.h>
#include "Platform/OpenGL/OpenGLShader.h"
#include "RendererCommand.h"
@ -19,6 +18,11 @@ namespace Hazel
RendererCommand::Init();
}
void Renderer::OnWindowResize(uint32_t width, uint32_t height)
{
RendererCommand::SetViewPort(0, 0, width, height);
}
void Renderer::BeginScene(OrthographicCamera& camera)
{
m_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix();

View File

@ -19,6 +19,7 @@ namespace Hazel
{
public:
static void Init();
static void OnWindowResize(uint32_t width, uint32_t height);
static void BeginScene(OrthographicCamera& camera);
static void EndScene();

View File

@ -25,6 +25,7 @@ namespace Hazel
public:
virtual void Init() = 0;
virtual void SetClearColor(const glm::vec4& color) = 0;
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;

View File

@ -20,15 +20,24 @@ namespace Hazel {
{
s_RendererAPI->SetClearColor(color);
}
inline static void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
{
s_RendererAPI->SetViewPort(x, y, width, height);
}
inline static void Clear()
{
s_RendererAPI->Clear();
}
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray) {
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray)
{
s_RendererAPI->DrawIndexed(vertexArray);
}
private:
static RendererAPI* s_RendererAPI;
};

View File

@ -9,16 +9,72 @@
namespace Hazel
{
Shader* Shader::Create(const std::string& vertexSrc, const std::string& fragmentSrc)
Ref<Shader> Shader::Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::NONE: return nullptr;
case RendererAPI::API::OPENGL: return new OpenGLShader(vertexSrc, fragmentSrc);
case RendererAPI::API::OPENGL: return std::make_shared<OpenGLShader>(name, vertexSrc, fragmentSrc);
}
HZ_CORE_ERROR("Unknown RendererAPI");
return nullptr;
}
Ref<Shader> Shader::Create(const std::string& filepath)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::NONE: return nullptr;
case RendererAPI::API::OPENGL: return std::make_shared<OpenGLShader>(filepath);
}
HZ_CORE_ERROR("Unknown RendererAPI");
return nullptr;
}
void ShaderLibrary::Add(const std::string& name, const Ref<Shader>& shader)
{
if (Exists(name))
{
HZ_CORE_ERROR("Shader already exists");
return;
}
m_Shaders[name] = shader;
}
void ShaderLibrary::Add(const Ref<Shader>& shader)
{
auto& name = shader->GetName();
Add(name, shader);
}
Ref<Shader> ShaderLibrary::Load(const std::string& filepath)
{
auto shader = std::make_shared<OpenGLShader>(filepath);
Add(shader);
return shader;
}
Ref<Shader> ShaderLibrary::Load(const std::string& name, const std::string& filepath)
{
auto shader = std::make_shared<OpenGLShader>(filepath);
Add(name, shader);
return shader;
}
Ref<Shader> ShaderLibrary::Get(const std::string& name)
{
if (!Exists(name))
{
HZ_CORE_ERROR("Shader not found");
return nullptr;
}
return m_Shaders[name];
}
bool ShaderLibrary::Exists(const std::string& name) const
{
return m_Shaders.contains(name);
}
}

View File

@ -5,6 +5,7 @@
#ifndef SHADER_H
#define SHADER_H
#include <string>
#include <unordered_map>
#include <Hazel/Core.h>
@ -18,10 +19,30 @@ namespace Hazel
virtual void Bind() const = 0;
virtual void Unbind() const = 0;
static Shader* Create(const std::string& vertexSrc, const std::string& fragmentSrc);
virtual const std::string& GetName() const = 0;
static Ref<Shader> Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc);
static Ref<Shader> Create(const std::string& filepath);
private:
uint32_t m_RendererID;
};
class HAZEL_API ShaderLibrary
{
public:
void Add(const Ref<Shader>& shader);
void Add(const std::string& name, const Ref<Shader>& shader);
Ref<Shader> Load(const std::string& filepath); // example: texture.glsl
Ref<Shader> Load(const std::string& name, const std::string& filepath);
Ref<Shader> Get(const std::string& name);
bool Exists(const std::string& name) const;
private:
std::unordered_map<std::string, Ref<Shader>> m_Shaders;
};
}

View File

@ -28,6 +28,7 @@ namespace Hazel
{
public:
using EventCallbackFn = std::function<void(SDL_Event&)>;
using WindowsResizeCallbackFn = std::function<void(SDL_Event&)>;
virtual ~Window() = default;
@ -38,6 +39,7 @@ namespace Hazel
// Window attributes
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
virtual void SetWindowResizeEventCallback(const WindowsResizeCallbackFn& callback) = 0;
virtual void SetVSync(bool enabled) = 0;
virtual bool IsVSync() const = 0;

View File

@ -11,7 +11,6 @@ namespace Hazel
void OpenGLRendererAPI::Init()
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
@ -20,6 +19,12 @@ namespace Hazel
glClearColor(color.x, color.y, color.z, color.w);
}
void OpenGLRendererAPI::SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
{
HZ_CORE_INFO("Setting viewport to ({0}, {1}), ({2}, {3})", x, y, width, height);
glViewport(x, y, width, height);
}
void OpenGLRendererAPI::Clear()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

View File

@ -14,6 +14,7 @@ namespace Hazel
public:
virtual void Init() override;
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;
};

View File

@ -3,81 +3,55 @@
//
#include "OpenGLShader.h"
#include <fstream>
#include <vector>
#include <glad/glad.h>
#include <array>
#include <Hazel/Log.h>
#include "glm/gtc/type_ptr.hpp"
#include "spdlog/fmt/bundled/compile.h"
namespace Hazel
{
OpenGLShader::OpenGLShader(const std::string& vertexSrc, const std::string& fragmentSrc)
static GLenum ShaderTypeFromString(const std::string& type)
{
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const char* vertexShaderSrc = vertexSrc.c_str();
glShaderSource(vertexShader, 1, &vertexShaderSrc, 0);
glCompileShader(vertexShader);
GLint compileSuccess = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE)
{
int length = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &length);
std::vector<GLchar> infoLog(length);
glGetShaderInfoLog(vertexShader, length, &length, &infoLog[0]);
glDeleteShader(vertexShader);
HZ_CORE_ERROR("Vertex shader compilation failed!");
HZ_CORE_ERROR("{0}", infoLog.data());
return;
if (type == "vertex") return GL_VERTEX_SHADER;
if (type == "fragment" || type == "pixel") return GL_FRAGMENT_SHADER;
if (type == "geometry") return GL_GEOMETRY_SHADER;
if (type == "compute") return GL_COMPUTE_SHADER;
HZ_CORE_ERROR("Unknown Shader Type");
return 0;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fragmentShaderSrc = fragmentSrc.c_str();
glShaderSource(fragmentShader, 1, &fragmentShaderSrc, 0);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE)
OpenGLShader::OpenGLShader(const std::string& filepath)
{
int length = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &length);
std::vector<GLchar> infoLog(length);
glGetShaderInfoLog(fragmentShader, length, &length, &infoLog[0]);
glDeleteShader(fragmentShader);
std::string shaderSrc = ReadFile(filepath);
auto shaderSources = PreProcess(shaderSrc);
Compile(shaderSources);
HZ_CORE_ERROR("[{0}:{1}]: Fragment shader compilation failed!", __FILE__, __LINE__);
HZ_CORE_ERROR("{0}", infoLog.data());
// example: /assets/shaders/Texture.glsl
auto lastSlash = filepath.find_last_of("\\/");
auto lastDot = filepath.find_last_of(".");
m_Name = filepath.substr(lastSlash + 1, lastDot - lastSlash - 1);
return;
/*
auto lastSlash = filepath.find_last_of("\\/");
lastSlash = lastSlash == std::string::npos ? 0 : lastSlash + 1;
auto lastDot = filepath.rfind(".");
auto count = lastDot == std::string::npos ? filepath.size() - lastSlash : lastDot - lastSlash;
m_Name = filepath.substr(lastSlash, count);
*/
}
m_RendererID = glCreateProgram();
glAttachShader(m_RendererID, vertexShader);
glAttachShader(m_RendererID, fragmentShader);
glLinkProgram(m_RendererID);
glGetProgramiv(m_RendererID, GL_LINK_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE)
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc): m_Name(name)
{
int length = 0;
glGetProgramiv(m_RendererID, GL_INFO_LOG_LENGTH, &length);
std::vector<GLchar> infoLog(length);
glGetProgramInfoLog(m_RendererID, length, &length, &infoLog[0]);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteProgram(m_RendererID);
HZ_CORE_ERROR("shaderProgram link failed!");
HZ_CORE_ERROR("{0}", infoLog.data());
return;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
std::unordered_map<GLenum, std::string> shaderSources;
shaderSources[GL_VERTEX_SHADER] = vertexSrc;
shaderSources[GL_FRAGMENT_SHADER] = fragmentSrc;
Compile(shaderSources);
}
@ -114,6 +88,133 @@ namespace Hazel
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
}
std::string OpenGLShader::ReadFile(const std::string& filepath)
{
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);
return "";
}
std::string result;
in.seekg(0, std::ios::end);
result.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&result[0], result.size());
in.close();
return result;
}
std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& source)
{
std::unordered_map<GLenum, std::string> shaderSource;
const char* typeToken = "#type";
size_t typeTokenLength = strlen(typeToken);
size_t pos = source.find(typeToken, 0);
while (pos != std::string::npos)
{
size_t eol = source.find_first_of("\r\n", pos);
if (eol == std::string::npos)
{
HZ_CORE_ERROR("[{0}:{1}]: Failed to parse shader source", __FILE__, __LINE__);
return shaderSource;
}
size_t start = pos + typeTokenLength + 1;
std::string type = source.substr(start, eol - start);
if (!ShaderTypeFromString(type))
{
HZ_CORE_ERROR("[{0}:{1}]: Unsupported shader type", __FILE__, __LINE__);
return shaderSource;
}
size_t nextLinePos = source.find_first_of("\r\n", eol);
pos = source.find(typeToken, nextLinePos);
shaderSource[ShaderTypeFromString(type)] = source.substr(nextLinePos, pos - (nextLinePos == std::string::npos ? source.size() - 1 : nextLinePos));
}
return shaderSource;
}
void OpenGLShader::Compile(std::unordered_map<GLenum, std::string>& shaderSource)
{
GLuint program = glCreateProgram();
// std::vector<GLenum> glShaderIDs;
// glShaderIDs.reserve(shaderSource.size());
if (shaderSource.size() > 2)
{
HZ_CORE_ERROR("Only support 2 shaders Now!");
}
std::array<GLenum, 2> glShaderIDs;
int glShaderIDIndex = 0;
for (auto& shaderSource : shaderSource)
{
GLenum type = shaderSource.first;
const std::string source = shaderSource.second;
GLuint shader = glCreateShader(type);
const char* shaderSrc = source.c_str();
glShaderSource(shader, 1, &shaderSrc, 0);
glCompileShader(shader);
GLint compileSuccess = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE)
{
int length = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
std::vector<GLchar> infoLog(length);
glGetShaderInfoLog(shader, length, &length, &infoLog[0]);
glDeleteShader(shader);
HZ_CORE_ERROR("shader compilation failed!");
HZ_CORE_ERROR("{0}", infoLog.data());
return;
}
glAttachShader(program, shader);
glShaderIDs[glShaderIDIndex++] = shader;
}
glLinkProgram(program);
GLint compileSuccess = 0;
glGetProgramiv(program, GL_LINK_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE)
{
int length = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
std::vector<GLchar> infoLog(length);
glGetProgramInfoLog(program, length, &length, &infoLog[0]);
for (const auto id : glShaderIDs)
{
glDeleteShader(id);
}
HZ_CORE_ERROR("shaderProgram link failed!");
HZ_CORE_ERROR("{0}", infoLog.data());
return;
}
for (const auto id : glShaderIDs)
{
glDetachShader(program, id);
glDeleteShader(id);
}
m_RendererID = program;
}
void OpenGLShader::UploadUniformInt(const char* str, const int value) const
{
const GLint location = glGetUniformLocation(m_RendererID, str);

View File

@ -8,6 +8,7 @@
#include "glm/fwd.hpp"
#include "glm/vec4.hpp"
#include <glad/glad.h>
namespace Hazel
@ -15,20 +16,29 @@ namespace Hazel
class HAZEL_API OpenGLShader : public Shader
{
public:
OpenGLShader(const std::string& vertexSrc, const std::string& fragmentSrc);
OpenGLShader(const std::string& filepath);
OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc);
virtual ~OpenGLShader() override;
void Bind() const override;
void Unbind() const override;
virtual const std::string& GetName() const override {return m_Name;}
void UploadUniformInt(const char* str, int 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 UploadUniformMat4(const std::string& name, const glm::mat4& matrix) const;
private:
std::string ReadFile(const std::string& filepath);
std::unordered_map<GLenum, std::string> PreProcess(const std::string& source);
void Compile(std::unordered_map<GLenum, std::string>& shaderSource);
private:
uint32_t m_RendererID;
std::string m_Name;
};
}

View File

@ -9,6 +9,8 @@
#include <Platform/OpenGL/OpenGLContext.h>
#include <glad/glad.h>
#include "glm/gtc/constants.hpp"
namespace Hazel
{
@ -65,7 +67,7 @@ namespace Hazel
HZ_CORE_INFO("Initing GLAD...");
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(SDL_GL_GetProcAddress)))
{
HZ_CORE_ERROR("Could not initialize GLAD context!");
}
@ -87,6 +89,16 @@ namespace Hazel
while (SDL_PollEvent(&event))
{
if (event.type == SDL_EVENT_WINDOW_RESIZED)
{
m_Data.width = event.window.data1;
m_Data.height = event.window.data2;
if (this->OnWindowResize != nullptr)
{
OnWindowResize(event);
}
}
if (m_Data.eventCallback != nullptr)
{
m_Data.eventCallback(event);

View File

@ -13,6 +13,7 @@
namespace Hazel
{
class GraphicsContext;
class WindowsWindow : public Window
@ -29,6 +30,7 @@ namespace Hazel
// 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;
@ -52,6 +54,7 @@ namespace Hazel
EventCallbackFn eventCallback;
};
WindowsResizeCallbackFn OnWindowResize;
WindowData m_Data;
};
}

View File

@ -0,0 +1,38 @@
#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;
out vec2 v_TexCoord;
void main() {
v_TexCoord = a_TexCoord;
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f);
}
#type fragment
#version 460 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
uniform sampler2D u_Texture;
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);
}
}
}

View File

@ -4,7 +4,7 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glad/glad.h>
#include <Hazel/OrthographicCameraController.h>
#include <Platform/OpenGL/OpenGLShader.h>
#include <Platform/OpenGL/OpenGLTexture.h>
@ -17,7 +17,7 @@ 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_Camera(-1.6f, 1.6f, -0.9f, 0.9f), m_CameraPosition(0.0f), m_SquarePosition(glm::vec3(0.0f))
ExampleLayer() : Layer("ExampleLayer"), m_CameraController(1280.0f / 720.0f), m_SquarePosition(glm::vec3(0.0f))
{
// ------------------------------------------------------------test------------------------------------------------------------
// Vertex Array
@ -76,7 +76,7 @@ public:
color = vec4(v_Color, 1.0f);
}
)";
m_Shader.reset(Hazel::Shader::Create(vertexSrc, fragmentSrc));
m_Shader = Hazel::Shader::Create("demoShader", vertexSrc, fragmentSrc);
m_SquareVA.reset(Hazel::VertexArray::Create());
@ -103,7 +103,7 @@ public:
squareIB.reset(Hazel::IndexBuffer::Create(squareIndice, sizeof(squareIndice) / sizeof(uint32_t)));
m_SquareVA->SetIndexBuffer(squareIB);
std::string bluevertexSrc = R"(
std::string coloeVertexSrc = R"(
#version 460 core
layout(location = 0) in vec3 a_Position;
@ -119,7 +119,7 @@ public:
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f);
}
)";
std::string bluefragmentSrc = R"(
std::string colorFragmentSrc = R"(
#version 460 core
layout(location = 0) out vec4 color;
@ -131,168 +131,107 @@ public:
color = u_Color;
}
)";
m_colorShader.reset(Hazel::Shader::Create(bluevertexSrc, bluefragmentSrc));
m_colorShader = Hazel::Shader::Create("ColorShader", coloeVertexSrc, colorFragmentSrc);
std::string textureVertexSrc = R"(
#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;
out vec2 v_TexCoord;
void main() {
v_TexCoord = a_TexCoord;
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f);
}
)";
std::string textureFragmentSrc = R"(
#version 460 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
uniform sampler2D u_Texture;
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);
}
}
}
)";
m_TextureShader.reset(Hazel::Shader::Create(textureVertexSrc, textureFragmentSrc));
// Texture.Shader
// m_TextureShader = Hazel::Shader::Create("assets/shaders/Texture.glsl");
auto textureShader = m_ShaderLibrary.Load("assets/shaders/Texture.glsl");
// Texture
m_Texture = Hazel::Texture2D::Create("assets/textures/Checkerboard.png");
m_logoTexture = Hazel::Texture2D::Create("assets/textures/iceLogo.png");
std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_TextureShader)->Bind();
std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_TextureShader)->UploadUniformInt("u_Texture", 0);
std::dynamic_pointer_cast<Hazel::OpenGLShader>(textureShader)->Bind();
std::dynamic_pointer_cast<Hazel::OpenGLShader>(textureShader)->UploadUniformInt("u_Texture", 0);
}
void OnUpdate(Hazel::TimeStep& ts) override
{
m_CameraController.OnUpdate(ts);
// key event
{
float time = ts;
const bool* state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_A])
{
m_CameraPosition.x -= m_CameraSpeed * time;
}
else if (state[SDL_SCANCODE_D])
{
m_CameraPosition.x += m_CameraSpeed * time;
}
if (state[SDL_SCANCODE_W])
{
m_CameraPosition.y += m_CameraSpeed * time;
}
else if (state[SDL_SCANCODE_S])
{
m_CameraPosition.y -= m_CameraSpeed * time;
}
if (state[SDL_SCANCODE_Q])
{
m_CameraRotation += m_CameraRotationSpeed * time;
}
else if (state[SDL_SCANCODE_E])
{
m_CameraRotation -= m_CameraRotationSpeed * time;
}
if (state[SDL_SCANCODE_I])
{
m_SquarePosition.y += m_CameraSpeed * time;
m_SquarePosition.y += 5 * time;
}
else if (state[SDL_SCANCODE_K])
{
m_SquarePosition.y -= m_CameraSpeed * time;
m_SquarePosition.y -= 5 * time;
}
if (state[SDL_SCANCODE_J])
{
m_SquarePosition.x -= m_CameraSpeed * time;
m_SquarePosition.x -= 5 * time;
}
else if (state[SDL_SCANCODE_L])
{
m_SquarePosition.x += m_CameraSpeed * time;
m_SquarePosition.x += 5 * time;
}
}
Hazel::RendererCommand::SetClearColor({0.1f, 0.1f, 0.1f, 1.0f});
Hazel::RendererCommand::SetClearColor(m_ScreenClearColor);
Hazel::RendererCommand::Clear();
m_Camera.SetPosition(m_CameraPosition);
m_Camera.SetRotation(m_CameraRotation);
Hazel::Renderer::BeginScene(m_Camera);
Hazel::Renderer::BeginScene(m_CameraController.GetCamera());
auto transform = glm::translate(glm::mat4(1.0f), m_SquarePosition);
auto textureShader = m_ShaderLibrary.Get("Texture");
m_Texture->Bind();
Hazel::Renderer::Submit(m_TextureShader, m_SquareVA, transform);
Hazel::Renderer::Submit(textureShader, m_SquareVA, transform);
m_logoTexture->Bind();
Hazel::Renderer::Submit(m_TextureShader, m_SquareVA);
Hazel::Renderer::Submit(textureShader, m_SquareVA);
Hazel::Renderer::EndScene();
}
void OnEvent(SDL_Event& event) override
{
m_CameraController.OnEvent(event);
}
void OnImGuiRender() override
{
ImGui::ShowDemoWindow();
const auto cameraRotation = m_CameraController.GetCamera().GetRotation();
const auto cameraPosition = m_CameraController.GetCamera().GetPosition();
ImGui::Begin("Hazel Layer");
ImGui::Text("Rotation: %f", m_CameraRotation);
ImGui::Text("Position: ( %.2f, %.2f, %.2f)", m_CameraPosition.x, m_CameraPosition.y, m_CameraPosition.z);
ImGui::Text("Rotation: %f", cameraRotation);
ImGui::Text("Position: ( %.2f, %.2f, %.2f)", cameraPosition.x, cameraPosition.y, cameraPosition.z);
ImGui::Text("frame: %.3f", ImGui::GetIO().Framerate);
ImGui::ColorEdit3("Square Color", glm::value_ptr(m_SquareColor));
ImGui::NewLine();
ImGui::ColorEdit4("Screen Clear Color", glm::value_ptr(m_ScreenClearColor));
ImGui::End();
}
private:
Hazel::ShaderLibrary m_ShaderLibrary;
Hazel::Ref<Hazel::Shader> m_Shader;
Hazel::Ref<Hazel::VertexArray> m_VertexArray;
Hazel::Ref<Hazel::VertexArray> m_SquareVA;
Hazel::Ref<Hazel::Shader> m_colorShader, m_TextureShader;
Hazel::Ref<Hazel::Shader> m_colorShader;
Hazel::Ref<Hazel::Texture2D> m_Texture, m_logoTexture;
Hazel::OrthographicCamera m_Camera;
glm::vec3 m_CameraPosition;
float m_CameraSpeed = 1.0f;
float m_CameraRotation = 0.0f;
float m_CameraRotationSpeed = 30.f;
Hazel::OrthographicCameraController m_CameraController;
glm::vec3 m_SquarePosition;
float m_SquareMoveSpeed = 1.0f;
glm::vec3 m_SquareColor = {0.2f, 0.3f, 0.8f};
glm::vec4 m_ScreenClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
};