main
anulax1225 ago%!(EXTRA string=6 months)
parent b2ebd91bec
commit 7a6c7d58c6
  1. 2
      premake5.lua
  2. 5
      src/bakara.h
  3. 30
      src/bakara/core/application.cpp
  4. 3
      src/bakara/core/application.h
  5. 9
      src/bakara/core/window.h
  6. 10
      src/bakara/events/mouse_event.h
  7. 11
      src/bakara/events/window_event.h
  8. 2
      src/bakara/math/types.h
  9. 18
      src/bakara/renderer/cameras/ortho_camera.cpp
  10. 27
      src/bakara/renderer/cameras/ortho_camera.h
  11. 76
      src/bakara/renderer/cameras/ortho_camera_controller.cpp
  12. 39
      src/bakara/renderer/cameras/ortho_camera_controller.h
  13. 18
      src/bakara/renderer/graphics_context.cpp
  14. 4
      src/bakara/renderer/graphics_context.h
  15. 2
      src/bakara/renderer/render_command.h
  16. 20
      src/bakara/renderer/renderer.cpp
  17. 12
      src/bakara/renderer/renderer.h
  18. 81
      src/bakara/renderer/renderer2D.cpp
  19. 33
      src/bakara/renderer/renderer2D.h
  20. 3
      src/bakara/renderer/renderer_api.h
  21. 46
      src/bakara/renderer/shader.cpp
  22. 22
      src/bakara/renderer/shader.h
  23. 2
      src/bakara/renderer/texture.h
  24. 47
      src/platforms/glfw/glfw_window.cpp
  25. 16
      src/platforms/glfw/glfw_window.h
  26. 9
      src/platforms/opengl/opengl_context.cpp
  27. 3
      src/platforms/opengl/opengl_context.h
  28. 12
      src/platforms/opengl/opengl_renderer_api.cpp
  29. 3
      src/platforms/opengl/opengl_renderer_api.h
  30. 124
      src/platforms/opengl/opengl_shader.cpp
  31. 11
      src/platforms/opengl/opengl_shader.h
  32. 32
      src/platforms/opengl/opengl_texture.cpp
  33. 2
      src/platforms/opengl/opengl_texture.h

@ -33,7 +33,7 @@ project "bakara"
"%{IncludeDirs.glfw}",
"%{IncludeDirs.imgui}",
"%{IncludeDirs.bakatools}",
"%{InlcudeDirs.stb}"
"%{IncludeDirs.stb}"
}
links

@ -14,8 +14,6 @@ Plaform namespace doc
*/
namespace Bk::Plaform {}
namespace Baka = Bk;
#include <bakara/math/types.h>
#include <bakara/io/io_codes.h>
@ -26,10 +24,13 @@ namespace Baka = Bk;
#include <bakara/core/layer.h>
#include <bakara/renderer/cameras/ortho_camera.h>
#include <bakara/renderer/cameras/ortho_camera_controller.h>
#include <bakara/renderer/render_command.h>
#include <bakara/renderer/renderer.h>
#include <bakara/renderer/renderer2D.h>
#include <bakara/renderer/texture.h>
#include <bakara/renderer/buffer.h>
#include <bakara/renderer/buffer_layout.h>
#include <bakara/renderer/shader.h>

@ -1,5 +1,7 @@
#include "application.h"
#include "bakara/core/window.h"
#include "bakara/events/window_event.h"
#include "bakara/renderer/renderer.h"
#include "bakatools/logging/assert.h"
#include "bakara/events/dispacher.h"
@ -10,11 +12,14 @@ namespace Bk {
{
BK_CORE_MSG_ASSERT(p_instance == nullptr, "Application already exists, can not create two application.")
Application::p_instance = this;
h_window = std::unique_ptr<Window>(Window::CreateWindow(WindowProps(title, width, height)));
h_window->SetEventCallback(BK_BIND_EVENT_FN(OnEvent));
Renderer::Init();
imgui_layer = new ImguiLayer();
PushOverlay(imgui_layer);
h_window->SetEventCallback(BK_BIND_EVENT_FN(OnEvent));
p_running = true;
}
Application::~Application() { }
@ -22,9 +27,9 @@ namespace Bk {
void Application::OnEvent(Event& e)
{
EventDispatcher dispatcher(e);
if (!(dispatcher.dispatch<WindowCloseEvent>(BK_BIND_DISPACHER_FN(WindowCloseEvent, OnWindowClose))
|| dispatcher.dispatch<WindowResizeEvent>(BK_BIND_DISPACHER_FN(WindowResizeEvent, OnWindowResize))))
if (!dispatcher.dispatch<WindowCloseEvent>(BK_BIND_DISPACHER_FN(WindowCloseEvent, OnWindowClose)))
{
dispatcher.dispatch<WindowResizeEvent>(BK_BIND_DISPACHER_FN(WindowResizeEvent, OnWindowResize));
for(auto it = p_layer_stack.ReverseBegin(); it != p_layer_stack.ReverseEnd(); it++)
{
(*it)->OnEvent(e);
@ -34,18 +39,19 @@ namespace Bk {
void Application::Close()
{
h_window->Close();
p_running = false;
}
bool Application::OnWindowClose(WindowCloseEvent& e)
bool Application::OnWindowResize(WindowResizeEvent& e)
{
Close();
return true;
isMinimized = !e.GetWidth() && !e.GetHeight();
Renderer::ResizeFrame(e.GetWidth(), e.GetHeight());
return false;
}
bool Application::OnWindowResize(WindowResizeEvent& e)
bool Application::OnWindowClose(WindowCloseEvent& e)
{
Close();
return true;
}
@ -53,8 +59,10 @@ namespace Bk {
{
while (p_running)
{
for (Layer* layer : p_layer_stack)
layer->OnUpdate(h_window->GetTime());
if (!isMinimized)
for (Layer* layer : p_layer_stack)
layer->OnUpdate(h_window->GetTime());
imgui_layer->Begin();
for (Layer* layer : p_layer_stack)
layer->ImguiRender();

@ -83,7 +83,8 @@ namespace Bk {
private:
LayerStack p_layer_stack; //!< Layer stack of the application
bool p_running; //!< Flag that indicates if the update loop should stop or not
bool p_running = true; //!< Flag that indicates if the update loop should stop or not
bool isMinimized = false;
static Application* p_instance;
};
/*! \fn std::unique_ptr<Application> Bk::CreateApp()

@ -84,15 +84,6 @@ namespace Bk {
Closes the window
*/
virtual void Close() = 0;
/*! \fn Bk::Window::Open
Opens and Initializes the window
*/
virtual void Open() = 0;
/*! \fn Bk::Window::IsOpen
Indicates if the window is Opened
@return Open flag
*/
virtual bool IsOpen() = 0;
virtual void* GetNativeWindow() = 0;

@ -12,8 +12,8 @@ namespace Bk
MouseMoveEvent(const float x, const float y)
: p_mouse_x(x), p_mouse_y(y) {}
float get_x() const { return p_mouse_x; }
float get_y() const { return p_mouse_y; }
float GetX() const { return p_mouse_x; }
float GetY() const { return p_mouse_y; }
Vec2 get_pos() const { return Vec2(p_mouse_x, p_mouse_y); }
@ -33,8 +33,8 @@ namespace Bk
MouseScrollEvent(const float x, const float y)
: p_dx(x), p_dy(y) {}
float get_dx() const { return p_dx; }
float get_dy() const { return p_dy; }
float GetDx() const { return p_dx; }
float GetDY() const { return p_dy; }
EVENT_STRINGIFY("MouseScrollEvent : (%f, %f)", p_dx, p_dy)
@ -48,7 +48,7 @@ namespace Bk
class MouseButtonEvent : public Event
{
public:
Code get_btn() { return m_btn; }
Code GetBtn() { return m_btn; }
EVENT_CLASS_CATEGORY(MouseCategory | InputCategory)
protected:

@ -1,16 +1,17 @@
#pragma once
#include "bakatools/container/types.h"
#include "event.h"
namespace Bk {
class WindowResizeEvent : public Event
{
public:
WindowResizeEvent(uint width, uint height)
WindowResizeEvent(u32 width, u32 height)
: p_width(width), p_height(height) {};
uint GetWidth() const { return p_width; }
uint GetHeight() const { return p_height; }
u32 GetWidth() const { return p_width; }
u32 GetHeight() const { return p_height; }
EVENT_STRINGIFY("WindowResizeEvent : %d %d", p_width, p_height)
@ -18,8 +19,8 @@ namespace Bk {
EVENT_CLASS_CATEGORY(AppCategory)
private:
uint p_width;
uint p_height;
u32 p_width;
u32 p_height;
};
class WindowCloseEvent : public Event

@ -15,6 +15,8 @@ namespace Bk
namespace Math = glm;
using Quaterion = glm::quat;
using Color = glm::vec4;
/*! \typedef Bk::Vec2
Wrapper around glm::vec2

@ -7,17 +7,23 @@
namespace Bk
{
OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top)
: projectionMatrix(Math::ortho(left, right, bottom, top, -1.0f, 1.0f))
OrthoCamera::OrthoCamera(float left, float right, float bottom, float top)
: projection(Math::ortho(left, right, bottom, top, -1.0f, 1.0f))
{
RecalculViewMatrix();
RecalculateView();
}
void OrthographicCamera::RecalculViewMatrix()
void OrthoCamera::SetProjection(float left, float right, float bottom, float top)
{
projection = Math::ortho(left, right, bottom, top, -1.0f, 1.0f);
viewProjection = projection * view;
}
void OrthoCamera::RecalculateView()
{
Mat4 transform = Math::translate(Mat4(1.0f), position);
transform = Math::rotate(transform, Math::radians(rotation) , Vec3(0.0f, 0.0f, 1.0f));
viewMatrix = Math::inverse(transform);
viewProjectionMatrix = projectionMatrix * viewMatrix;
view = Math::inverse(transform);
viewProjection = projection * view;
}
}

@ -4,25 +4,26 @@
namespace Bk
{
class OrthographicCamera
class OrthoCamera
{
public:
OrthographicCamera(float left, float right, float bottom, float top);
OrthoCamera(float left, float right, float bottom, float top);
void SetPosition(Vec3 position) { this->position = position; RecalculViewMatrix(); }
Vec3 GetPosition() { return position; }
void SetRotation(float rotation) { this->rotation = rotation; RecalculViewMatrix(); }
float GetRotaion() { return rotation; }
void SetPosition(Vec3 position) { this->position = position; RecalculateView(); }
const Vec3& GetPosition() const { return position; }
void SetRotation(float rotation) { this->rotation = rotation; RecalculateView(); }
float GetRotaion() const { return rotation; }
Mat4 GetViewMatrix() { return viewMatrix; }
Mat4 GetProjectionMatrix() { return projectionMatrix; }
Mat4 GetViewProjectionMatrix() { return viewProjectionMatrix; }
const Mat4 GetView() const { return view; }
void SetProjection(float left, float right, float bottom, float top);
const Mat4 GetProjection() const { return projection; }
const Mat4 GetViewProjection() const { return viewProjection; }
private:
void RecalculViewMatrix();
Mat4 viewMatrix;
Mat4 projectionMatrix;
Mat4 viewProjectionMatrix;
void RecalculateView();
Mat4 view;
Mat4 projection;
Mat4 viewProjection;
Vec3 position = { 0.0f, 0.0f, 0.0f };
float rotation = 0.0f;

@ -0,0 +1,76 @@
#include "ortho_camera_controller.h"
#include "bakara/events/dispacher.h"
#include "bakara/events/event.h"
#include "bakara/events/window_event.h"
#include "bakara/io/keyboard.h"
#include "glm/trigonometric.hpp"
#include <cmath>
namespace Bk
{
OrthoCameraController::OrthoCameraController(float aspectRatio, bool rotation, bool zoom)
: aspectRatio(aspectRatio),
camera(-aspectRatio * zoomLevel, aspectRatio * zoomLevel, -zoomLevel, zoomLevel),
rotation(rotation), zoom(zoom) {}
void OrthoCameraController::OnEvent(Event& e)
{
EventDispatcher dispatcher(e);
dispatcher.dispatch<WindowResizeEvent>(BK_BIND_DISPACHER_FN(WindowResizeEvent, OnWindowResize));
dispatcher.dispatch<MouseScrollEvent>(BK_BIND_DISPACHER_FN(MouseScrollEvent, OnMouseScroll));
}
void OrthoCameraController::OnUpdate(DeltaTime dt)
{
if (rotation)
{
if(Keyboard::KeyDown(KeyCode::Q))
cameraRotation -= rotationSpeed * dt;
if(Keyboard::KeyDown(KeyCode::E))
cameraRotation += rotationSpeed * dt;
camera.SetRotation(cameraRotation);
}
if(Keyboard::KeyDown(KeyCode::W))
{
cameraPosition.x += -std::sin(Math::radians(cameraRotation)) * moveSpeed * dt;
cameraPosition.y += std::cos(Math::radians(cameraRotation)) * moveSpeed * dt;
}
if(Keyboard::KeyDown(KeyCode::S))
{
cameraPosition.x -= -std::sin(Math::radians(cameraRotation)) * moveSpeed * dt;
cameraPosition.y -= std::cos(Math::radians(cameraRotation)) * moveSpeed * dt;
}
if(Keyboard::KeyDown(KeyCode::D))
{
cameraPosition.x += std::cos(Math::radians(cameraRotation)) * moveSpeed * dt;
cameraPosition.y += std::sin(Math::radians(cameraRotation)) * moveSpeed * dt;
}
if(Keyboard::KeyDown(KeyCode::A))
{
cameraPosition.x -= std::cos(Math::radians(cameraRotation)) * moveSpeed * dt;
cameraPosition.y -= std::sin(Math::radians(cameraRotation)) * moveSpeed * dt;
}
camera.SetPosition(cameraPosition);
}
bool OrthoCameraController::OnMouseScroll(MouseScrollEvent& e)
{
if (zoom)
{
zoomLevel -= e.GetDY() * 0.01;
zoomLevel = std::max(zoomLevel, 0.5f);
zoomLevel = std::min(zoomLevel, 10.0f);
camera.SetProjection(-aspectRatio * zoomLevel, aspectRatio * zoomLevel, -zoomLevel, zoomLevel);
return true;
}
return false;
}
bool OrthoCameraController::OnWindowResize(WindowResizeEvent& e)
{
aspectRatio = (float)e.GetWidth() / (float)e.GetHeight();
camera.SetProjection(-aspectRatio * zoomLevel, aspectRatio * zoomLevel, -zoomLevel, zoomLevel);
return false;
}
}

@ -0,0 +1,39 @@
#pragma once
#include "bakara/core/deltatime.h"
#include "bakara/events/event.h"
#include "bakara/events/mouse_event.h"
#include "bakara/events/window_event.h"
#include "ortho_camera.h"
namespace Bk
{
class OrthoCameraController
{
public:
OrthoCameraController(float aspectRatio, bool rotation = false, bool zoom = false);
void OnUpdate(DeltaTime dt);
void OnEvent(Event& e);
const OrthoCamera& GetCamera() { return camera; }
void SetMoveSpeed(float moveSpeed) { this->moveSpeed = moveSpeed; }
void SetRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; }
private:
float aspectRatio;
float zoomLevel = 1.0f;
bool rotation, zoom;
float cameraRotation = 0.0f;
Vec3 cameraPosition = { 0, 0, 0 };
float moveSpeed = 1.0f;
float rotationSpeed = 1.0f;
OrthoCamera camera;
bool OnMouseScroll(MouseScrollEvent& e);
bool OnWindowResize(WindowResizeEvent& e);
};
}

@ -0,0 +1,18 @@
#include "graphics_context.h"
#include "bakara/renderer/renderer.h"
#include "bakatools/logging/assert.h"
#include "platforms/opengl/opengl_context.h"
namespace Bk
{
Scope<GraphicsContext> GraphicsContext::Create(void *window_handle)
{
switch (Renderer::GetAPI())
{
case Renderer::API::None: BK_MSG_ASSERT(false, "API not supported"); return nullptr;
case Renderer::API::Opengl: return CreateScope<Platform::OpenglContext>(window_handle);
}
BK_MSG_ASSERT(false, "API not supported");
return nullptr;
}
}

@ -1,5 +1,6 @@
#pragma once
#include "bakatools/container/types.h"
namespace Bk
{
class GraphicsContext
@ -8,6 +9,7 @@ namespace Bk
virtual ~GraphicsContext() {}
virtual void Init() = 0;
virtual void SwapBuffers() = 0;
virtual void SetViewport(int width, int height) = 0;
static Scope<GraphicsContext> Create(void* window_handle);
};
}

@ -9,8 +9,10 @@ namespace Bk
class RenderCommand
{
public:
static inline void Init() { rendererAPI->Init(); }
static inline void Clear(Vec4 color) { rendererAPI->Clear(color.r, color.g, color.b, color.a); }
static inline void Clear(float red, float green, float blue, float alpha) { rendererAPI->Clear(red, green, blue, alpha); }
static inline void SetViewport(u32 width, u32 height) { rendererAPI->SetViewport(width, height); }
static inline void DrawIndexed(Ref<VertexArray> va) { rendererAPI->DrawIndexed(va); }
private:
static RendererAPI* rendererAPI;

@ -1,14 +1,26 @@
#include "renderer.h"
#include "bakara/renderer/cameras/ortho_camera.h"
#include "bakara/renderer/render_command.h"
#include "bakara/renderer/renderer2D.h"
namespace Bk
{
Renderer::API Renderer::s_RenderAPI = Renderer::API::Opengl;
Renderer::SceneData* Renderer::sceneData = new Renderer::SceneData();
Renderer::Storage* Renderer::data = new Renderer::Storage();
void Renderer::BeginScene(OrthographicCamera camera)
void Renderer::Init()
{
sceneData->VPMatrix = camera.GetViewProjectionMatrix();
RenderCommand::Init();
Renderer2D::Init();
}
void Renderer::ResizeFrame(u32 width, u32 height)
{
RenderCommand::SetViewport(width, height);
}
void Renderer::BeginScene(const OrthoCamera& camera)
{
data->viewProjection = camera.GetViewProjection();
}
void Renderer::EndScene()
@ -20,7 +32,7 @@ namespace Bk
{
va->Bind();
shader->Bind();
shader->Set("u_ViewProjection", sceneData->VPMatrix);
shader->Set("u_ViewProjection", data->viewProjection);
shader->Set("u_Transform", transform);
RenderCommand::DrawIndexed(va);
}

@ -19,16 +19,20 @@ namespace Bk
static API GetAPI() { return s_RenderAPI; }
static void BeginScene(OrthographicCamera camera);
static void Init();
static void ResizeFrame(u32 width, u32 height);
static void BeginScene(const OrthoCamera& camera);
static void EndScene();
static void Submit(Ref<VertexArray> va, Ref<Shader> shader, Mat4 transform = Mat4(1.0f));
private:
struct SceneData
struct Storage
{
Mat4 VPMatrix;
Mat4 viewProjection;
};
static SceneData* sceneData;
static Storage* data;
static API s_RenderAPI;
};
}

@ -0,0 +1,81 @@
#include "renderer2D.h"
#include "bakara/renderer/buffer.h"
#include "bakara/renderer/buffer_layout.h"
#include "bakara/renderer/render_command.h"
#include "bakara/renderer/texture.h"
namespace Bk
{
Renderer2D::Storage* Renderer2D::data = new Renderer2D::Storage();
void Renderer2D::Init()
{
data->shaderLib.Load("assets/shaders/flatColor.glsl");
data->shaderLib.Load("assets/shaders/texture.glsl");
data->squareVA = VertexArray::Create();
float squareVertices[5 * 4] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
Ref<VertexBuffer> squareVB = VertexBuffer::Create(squareVertices, sizeof(squareVertices));
squareVB->SetLayout({
{ ShaderType::Float3, "a_Position" },
{ ShaderType::Float2, "a_TextCord" }
});
data->squareVA->AddVertexBuffer(squareVB);
u32 squareIndices[6] = { 0, 1, 2, 0, 2, 3 };
data->squareVA->SetIndexbuffer(IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(u32)));
}
void Renderer2D::Shutdown()
{
delete data;
}
void Renderer2D::BeginScene(const OrthoCamera &camera)
{
data->viewProjection = camera.GetViewProjection();
}
void Renderer2D::EndScene()
{
}
void Renderer2D::DrawQuad(const Vec2& position, const Vec2& size, const Color& color)
{
Renderer2D::DrawQuad(Vec3(position, 0), size, color);
}
void Renderer2D::DrawQuad(const Vec3& position, const Vec2& size, const Color& color)
{
Ref<Shader> shader = data->shaderLib["flatColor"];
data->squareVA->Bind();
shader->Bind();
shader->Set("u_FlatColor", color);
shader->Set("u_ViewProjection", data->viewProjection);
shader->Set("u_Transform", Math::scale(Math::translate(Mat4(1.0f), position), Vec3(size, 0)));
RenderCommand::DrawIndexed(data->squareVA);
}
void Renderer2D::DrawQuad(const Vec2& position, const Vec2& size, const Ref<Texture2D>& texture)
{
Renderer2D::DrawQuad(Vec3(position, 0), size, texture);
}
void Renderer2D::DrawQuad(const Vec3& position, const Vec2& size, const Ref<Texture2D>& texture)
{
Ref<Shader> shader = data->shaderLib["texture"];
data->squareVA->Bind();
texture->Bind();
shader->Bind();
shader->Set("u_Texture", 0);
shader->Set("u_ViewProjection", data->viewProjection);
shader->Set("u_Transform", Math::scale(Math::translate(Mat4(1.0f), position), Vec3(size, 0)));
RenderCommand::DrawIndexed(data->squareVA);
}
}

@ -0,0 +1,33 @@
#pragma once
#include "bakara/renderer/shader.h"
#include "bakara/renderer/texture.h"
#include "bakara/renderer/vertex_array.h"
#include "cameras/ortho_camera.h"
namespace Bk
{
class Renderer2D
{
public:
static void Init();
static void Shutdown();
static void BeginScene(const OrthoCamera& camera);
static void EndScene();
static void DrawQuad(const Vec2& position, const Vec2& size, const Color& color);
static void DrawQuad(const Vec3& position, const Vec2& size, const Color& color);
static void DrawQuad(const Vec2& position, const Vec2& size, const Ref<Texture2D>& texture);
static void DrawQuad(const Vec3& position, const Vec2& size, const Ref<Texture2D>& texture);
private:
struct Storage
{
Mat4 viewProjection;
Ref<VertexArray> squareVA;
ShaderLibrary shaderLib;
};
static Storage* data;
};
}

@ -8,7 +8,10 @@ namespace Bk
{
public:
virtual ~RendererAPI() {}
virtual void Init() = 0;
virtual void Clear(float red, float green, float blue, float alpha) = 0;
virtual void SetViewport(u32 width, u32 height) = 0;
virtual void DrawIndexed(Ref<VertexArray> va) = 0;
};
}

@ -5,14 +5,56 @@
namespace Bk
{
Ref<Shader> Shader::Create(std::string vertexSrc, std::string fragSrc)
Ref<Shader> Shader::Create(const std::string& name, const std::string& vertexSrc, const std::string& fragSrc)
{
switch(Renderer::GetAPI())
{
case Renderer::API::None: BK_MSG_ASSERT(false, "API not supported"); return nullptr;
case Renderer::API::Opengl: return CreateRef<Platform::OpenglShader>(vertexSrc, fragSrc);
case Renderer::API::Opengl: return CreateRef<Platform::OpenglShader>(name, vertexSrc, fragSrc);
}
BK_MSG_ASSERT(false, "API not supported");
return nullptr;
}
Ref<Shader> Shader::Create(const std::string& filePath)
{
switch(Renderer::GetAPI())
{
case Renderer::API::None: BK_MSG_ASSERT(false, "API not supported"); return nullptr;
case Renderer::API::Opengl: return CreateRef<Platform::OpenglShader>(filePath);
}
BK_MSG_ASSERT(false, "API not supported");
return nullptr;
}
void ShaderLibrary::Add(const std::string& name, const Ref<Shader>& shader)
{
BK_CORE_MSG_ASSERT(!Exists(name), "Shader already exists in library")
shaders[name] = shader;
}
void ShaderLibrary::Add(const Ref<Shader>& shader)
{
const auto& name = shader->GetName();
Add(shader->GetName(), shader);
}
Ref<Shader> ShaderLibrary::Load(const std::string& filePath)
{
Ref<Shader> shader = Shader::Create(filePath);
Add(shader);
return shader;
}
Ref<Shader> ShaderLibrary::Load(const std::string& name, const std::string filePath)
{
Ref<Shader> shader = Shader::Create(filePath);
Add(name, shader);
return shader;
}
Ref<Shader> ShaderLibrary::Get(const std::string& name)
{
BK_CORE_MSG_ASSERT(Exists(name), "Shader not found")
return shaders[name];
}
}

@ -3,6 +3,7 @@
#include "bakara/math/types.h"
#include "bakatools/container/types.h"
#include <string>
#include <unordered_map>
namespace Bk
{
@ -11,6 +12,8 @@ namespace Bk
public:
virtual ~Shader() {}
virtual const std::string& GetName() = 0;
virtual void Bind() = 0;
virtual void Unbind() = 0;
@ -24,6 +27,23 @@ namespace Bk
virtual void Set(const std::string name, Mat3 val) = 0;
virtual void Set(const std::string name, Mat4 val) = 0;
static Ref<Shader> Create(std::string vertexSrc, std::string fragSrc);
static Ref<Shader> Create(const std::string& name, const std::string& vertexSrc, const std::string& fragSrc);
static Ref<Shader> Create(const std::string& filePath);
};
class ShaderLibrary
{
public:
inline bool Exists(const std::string& name) { return shaders.find(name) != shaders.end(); }
void Add(const std::string& name, const Ref<Shader>& shader);
void Add(const Ref<Shader>& shader);
Ref<Shader> Load(const std::string& filePath);
Ref<Shader> Load(const std::string& name, const std::string filePath);
Ref<Shader> Get(const std::string& name);
inline Ref<Shader> operator[](const std::string& name) { return Get(name); }
private:
std::unordered_map<std::string, Ref<Shader>> shaders;
};
}

@ -11,7 +11,7 @@ namespace Bk
virtual ~Texture() {}
virtual u32 GetWidth() = 0;
virtual u32 GetHeight() = 0;
virtual void Bind() = 0;
virtual void Bind(u32 slot = 0) = 0;
};
class Texture2D : public Texture

@ -3,6 +3,7 @@
#include "bakara/events/key_event.h"
#include "bakara/events/mouse_event.h"
#include "bakara/events/window_event.h"
#include "bakara/renderer/graphics_context.h"
#include "bakatools/logging/assert.h"
#include <GLFW/glfw3.h>
@ -14,11 +15,6 @@ namespace Bk {
}
namespace Platform {
GlfwWindowData::~GlfwWindowData()
{
delete context;
}
static uint p_glfw_Initialized = 0;
static void glfw_error_callback(int error, const char* description)
@ -41,7 +37,6 @@ namespace Bk {
void GlfwWindow::Init()
{
h_IsOpen = true;
BK_CORE_INFO("Creating window '{0}' ({1}, {2})", p_data.title, p_data.width, p_data.height);
if (!p_glfw_Initialized++)
{
@ -50,12 +45,10 @@ namespace Bk {
glfwSetErrorCallback(glfw_error_callback);
}
p_window = glfwCreateWindow((int)p_data.width, (int)p_data.height, p_data.title.c_str(), nullptr, nullptr);
p_data.context = new OpenglContext(p_window);
p_data.context->Init();
p_data.context->SetViewport(p_data.width, p_data.height);
context = GraphicsContext::Create((void*)p_window);
context->Init();
glfwSetWindowUserPointer(p_window, &p_data);
SetVsync(true);
InitEventCallbacks();
}
@ -64,7 +57,6 @@ namespace Bk {
glfwSetFramebufferSizeCallback(p_window, [](GLFWwindow* window, int width, int height)
{
GlfwWindowData& data = *(GlfwWindowData*)glfwGetWindowUserPointer(window);
data.context->SetViewport(width, height);
WindowResizeEvent e(data.width = (uint)width, data.height = (uint)height);
data.callback(e);
});
@ -139,11 +131,7 @@ namespace Bk {
dt = DeltaTime(time - lastFrameTime);
lastFrameTime = time;
glfwPollEvents();
p_data.context->SwapBuffers();
if (h_IsOpen)
{
if (p_Shutdown && h_IsOpen) { Shutdown(); }
}
context->SwapBuffers();
}
void GlfwWindow::SetEventCallback(const EventCallback callback)
@ -153,38 +141,19 @@ namespace Bk {
void GlfwWindow::SetVsync(bool enable)
{
if (h_IsOpen)
{
if (enable) { glfwSwapInterval(1); }
else { glfwSwapInterval(0); }
p_data.vsync = enable;
}
if (enable) { glfwSwapInterval(1); }
else { glfwSwapInterval(0); }
p_data.vsync = enable;
}
bool GlfwWindow::IsVsync() const
{
return p_data.vsync;
}
void GlfwWindow::Shutdown()
{
h_IsOpen = false;
p_Shutdown = false;
glfwDestroyWindow(p_window);
}
void GlfwWindow::Close()
{
p_Shutdown = true;
}
void GlfwWindow::Open()
{
if (!h_IsOpen)
{
Init();
}
glfwDestroyWindow(p_window);
}
}
}

@ -2,7 +2,7 @@
#include "bakara/core/deltatime.h"
#include "bakara/core/window.h"
#include "platforms/opengl/opengl_context.h"
#include "bakara/renderer/graphics_context.h"
struct GLFWwindow;
@ -14,8 +14,6 @@ namespace Bk::Platform {
uint height;
bool vsync;
EventCallback callback;
GraphicsContext* context;
~GlfwWindowData();
};
class GlfwWindow : public Window
@ -34,28 +32,20 @@ namespace Bk::Platform {
bool IsVsync() const override;
void Close() override;
void Open() override;
void* GetNativeWindow() override { return p_window; }
/*! \fn Bk::Window::IsOpen
Indicates if the window is Opened
@return Open flag
*/
bool IsOpen() override { return h_IsOpen; }
virtual DeltaTime GetTime() override { return dt; }
private:
bool h_IsOpen; //!< indicaste if the window is Opened or not
bool p_Shutdown;
GLFWwindow* p_window;
GlfwWindowData p_data;
Scope<GraphicsContext> context;
float lastFrameTime = 0.0f;
DeltaTime dt = { 0.0f };
void InitEventCallbacks();
void Init();
void Shutdown();
};
}

@ -6,8 +6,8 @@
namespace Bk::Platform
{
OpenglContext::OpenglContext(GLFWwindow* window_handle)
: window_handle(window_handle) {}
OpenglContext::OpenglContext(void* window_handle)
: window_handle((GLFWwindow*)window_handle) {}
void OpenglContext::Init()
{
@ -30,9 +30,4 @@ namespace Bk::Platform
{
glfwSwapBuffers(window_handle);
}
void OpenglContext::SetViewport(int width, int height)
{
glViewport(0, 0, width, height);
}
}

@ -10,11 +10,10 @@ namespace Bk::Platform
class OpenglContext : public GraphicsContext
{
public:
OpenglContext(GLFWwindow* window_handle);
OpenglContext(void* window_handle);
virtual ~OpenglContext() override { }
void Init() override;
void SwapBuffers() override;
void SetViewport(int width, int height) override;
private:
GLFWwindow* window_handle;
};

@ -3,12 +3,24 @@
namespace Bk
{
void OpenglRendererAPI::Init()
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
}
void OpenglRendererAPI::Clear(float red, float green, float blue, float alpha)
{
glClearColor(red, green, blue, alpha);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void OpenglRendererAPI::SetViewport(u32 width, u32 height)
{
glViewport(0, 0, width, height);
}
void OpenglRendererAPI::DrawIndexed(Ref<VertexArray> va)
{
glDrawElements(GL_TRIANGLES, va->GetIndexbuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);

@ -2,13 +2,16 @@
#include "bakara/renderer/renderer_api.h"
#include "bakara/renderer/vertex_array.h"
#include "bakatools/container/types.h"
namespace Bk
{
class OpenglRendererAPI : public RendererAPI
{
public:
virtual void Init() override;
virtual void Clear(float red, float green, float blue, float alpha) override;
virtual void SetViewport(u32 width, u32 height) override;
virtual void DrawIndexed(Ref<VertexArray> va) override;
};
}

@ -1,48 +1,98 @@
#include "opengl_shader.h"
#include "bakatools/logging/log.h"
#include "bakatools/file_system/file.h"
#include "bakatools/logging/assert.h"
#include "bakara/math/types.h"
#include <glad/glad.h>
#include "bakatools/logging/log.h"
#include <unordered_map>
namespace Bk::Platform
{
OpenglShader::OpenglShader(std::string vertexSrc, std::string fragSrc)
{
static GLenum ShaderTypeFromString(std::string type)
{
int success;
char infoLog[512];
//Creating a shader program
id = glCreateProgram();
//Compile shader
GLuint ret = glCreateShader(GL_VERTEX_SHADER);
const GLchar* shader = vertexSrc.c_str();
glShaderSource(ret, 1, &shader, NULL);
glCompileShader(ret);
glGetShaderiv(ret, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(ret, 512, NULL, infoLog);
BK_INFO("Error with fragment shader compilating : {0}", infoLog);
if (type == "vertex") return GL_VERTEX_SHADER;
else if (type == "fragment" || type == "pixel") return GL_FRAGMENT_SHADER;
BK_CORE_MSG_ASSERT(false, "An known shader type")
return 0;
}
OpenglShader::OpenglShader(const std::string& filePath)
{
File file = File(filePath);
BK_CORE_MSG_ASSERT(file.exists(), "Shader file not found")
std::string filename = file.name();
size_t pos = filename.find_last_of(".");
name = pos == std::string::npos ? filename : filename.substr(0, pos);
std::string source = file.read();
auto sources = PreProcess(source);
Compile(sources);
}
OpenglShader::OpenglShader(const std::string& name, const std::string& vertexSrc, const std::string& fragSrc)
: name(name)
{
Compile({
{ GL_VERTEX_SHADER, vertexSrc },
{ GL_FRAGMENT_SHADER, fragSrc }
});
}
std::unordered_map<GLenum, std::string> OpenglShader::PreProcess(std::string source)
{
std::unordered_map<GLenum, std::string> sources;
const std::string token("#type");
size_t pos = source.find(token, 0);
BK_CORE_MSG_ASSERT(pos != std::string::npos, "Not shader found in file")
while (pos != std::string::npos)
{
size_t eol = source.find_first_of("\n", pos);
BK_CORE_MSG_ASSERT(eol != std::string::npos, "Syntax Error in shader file");
size_t begin = pos + token.length() + 1;
std::string type = source.substr(begin, eol - begin);
GLenum glType = ShaderTypeFromString(type);
size_t nextLine = source.find_first_not_of("\n", eol);
pos = source.find(token, nextLine);
sources[glType] = (pos == std::string::npos) ? source.substr(nextLine) : source.substr(nextLine, pos - nextLine);
}
glAttachShader(id, ret);
GLuint ret1 = glCreateShader(GL_FRAGMENT_SHADER);
shader = fragSrc.c_str();
glShaderSource(ret1, 1, &shader, NULL);
glCompileShader(ret1);
glGetShaderiv(ret1, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(ret1, 512, NULL, infoLog);
BK_INFO("Error with fragment shader compilating : {0}", infoLog);
return sources;
}
void OpenglShader::Compile(std::unordered_map<GLenum, std::string> sources)
{
std::vector<GLuint> shaders;
id = glCreateProgram();
for(auto& kv : sources)
{
GLenum type = kv.first;
const GLchar* shaderSrc = kv.second.c_str();
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &shaderSrc, NULL);
glCompileShader(shader);
int info;
glGetShaderiv(shader, GL_COMPILE_STATUS, &info);
if(!info) {
std::vector<char> infoLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info);
infoLog.resize(info);
glGetShaderInfoLog(shader, infoLog.size(), NULL, infoLog.data());
BK_CORE_ERROR("Shader Error : {0}", std::string(infoLog.data(),infoLog.size()));
BK_MSG_ASSERT(false, "Error with shader compilation")
}
glAttachShader(id, shader);
shaders.push_back(shader);
}
glAttachShader(id, ret1);
glLinkProgram(id);
glGetProgramiv(id, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(id, 512, NULL, infoLog);
BK_INFO("Error when link sharder in a program : {0}", infoLog);
int info;
glGetProgramiv(id, GL_LINK_STATUS, &info);
if(!info) {
std::vector<char> infoLog;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info);
infoLog.resize(info);
glGetProgramInfoLog(id, infoLog.size(), NULL, infoLog.data());
BK_CORE_ERROR("Shader Error : {0}", std::string(infoLog.data(),infoLog.size()));
BK_MSG_ASSERT(false, "Error when link sharder in a program")
}
glDeleteShader(ret);
glDeleteShader(ret1);
for(auto shader : shaders) glDeleteShader(shader);
}
OpenglShader::~OpenglShader()
@ -92,7 +142,7 @@ namespace Bk::Platform
void OpenglShader::Set(const std::string name, Vec4 v)
{
glUniformMatrix3fv(glGetUniformLocation(this->id, name.c_str()), 1, GL_FALSE, Math::value_ptr(v));
this->Set(name, v.x, v.y, v.z, v.w);
}
void OpenglShader::Set(const std::string name, Mat3 val)

@ -1,15 +1,21 @@
#pragma once
#include "bakara/renderer/shader.h"
#include <glad/glad.h>
#include <string>
#include <unordered_map>
namespace Bk::Platform
{
class OpenglShader : public Shader
{
public:
OpenglShader(std::string vertexSrc, std::string fragSrc);
OpenglShader(const std::string& filePath);
OpenglShader(const std::string& name, const std::string& vertexSrc, const std::string& fragSrc);
virtual ~OpenglShader();
virtual const std::string& GetName() override { return name; }
virtual void Bind() override;
virtual void Unbind() override;
@ -25,5 +31,8 @@ namespace Bk::Platform
private:
unsigned int id;
std::string name;
std::unordered_map<GLenum, std::string> PreProcess(std::string source);
void Compile(std::unordered_map<GLenum, std::string> sources);
};
}

@ -1,4 +1,6 @@
#include "opengl_texture.h"
#include "bakatools/logging/assert.h"
#include "bakatools/logging/log.h"
#include <stb_image.h>
#include <glad/glad.h>
@ -7,16 +9,40 @@ namespace Bk::Platform
{
OpenglTexture2D::OpenglTexture2D(const std::string& filePath)
{
stbi_set_flip_vertically_on_load(true);
int width, height, channels;
stbi_uc* data = stbi_load(filePath.c_str(), &width, &height, &channels, 0);
BK_CORE_MSG_ASSERT(data, "Coudn't load image data")
BK_CORE_MSG_ASSERT(channels >= 3 && channels <= 4, "Image format not supported")
this->width = (u32)width;
this->height = (u32)height;
GLenum internalFormat = 0, format = 0;
if(channels == 4) { internalFormat = GL_RGBA8; format = GL_RGBA; }
else { internalFormat = GL_RGB8; format = GL_RGB; }
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, this->width, this->height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->width, this->height, format, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
OpenglTexture2D::~OpenglTexture2D()
{
glDeleteTextures(1, &id);
}
void OpenglTexture2D::Bind()
void OpenglTexture2D::Bind(u32 slot)
{
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, id);
}
}

@ -12,7 +12,7 @@ namespace Bk::Platform
virtual u32 GetWidth() override { return width; }
virtual u32 GetHeight() override { return height; }
virtual void Bind() override;
virtual void Bind(u32 slot = 0) override;
private:
u32 id;
u32 width, height;

Loading…
Cancel
Save