WE GOT TEXTURES BABY
This commit is contained in:
@@ -34,6 +34,7 @@ protected:
|
||||
|
||||
CPUMesh testMesh{};
|
||||
MeshID testMeshID;
|
||||
MaterialID testMaterialID;
|
||||
|
||||
GfxDevice gfxDevice;
|
||||
GameRenderer renderer;
|
||||
@@ -41,8 +42,7 @@ protected:
|
||||
Camera camera{glm::vec3(0.f, 0.f, -5.f), glm::vec3(0, 1, 0)};
|
||||
|
||||
MeshCache meshCache;
|
||||
|
||||
InputManager inputManager;
|
||||
MaterialCache materialCache;
|
||||
|
||||
bool isRunning{false};
|
||||
bool gamePaused{false};
|
||||
|
||||
33
destrum/include/destrum/Graphics/BindlessSetManager.h
Normal file
33
destrum/include/destrum/Graphics/BindlessSetManager.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef BINDLESSSETMANAGER_H
|
||||
#define BINDLESSSETMANAGER_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
struct GPUImage;
|
||||
|
||||
class BindlessSetManager {
|
||||
public:
|
||||
void init(VkDevice device, float maxAnisotropy);
|
||||
void cleanup(VkDevice device);
|
||||
|
||||
VkDescriptorSetLayout getDescSetLayout() const { return descSetLayout; }
|
||||
const VkDescriptorSet& getDescSet() const { return descSet; }
|
||||
|
||||
void addImage(VkDevice device, std::uint32_t id, const VkImageView imageView);
|
||||
void addSampler(VkDevice device, std::uint32_t id, VkSampler sampler);
|
||||
|
||||
private:
|
||||
void initDefaultSamplers(VkDevice device, float maxAnisotropy);
|
||||
|
||||
VkDescriptorPool descPool;
|
||||
VkDescriptorSetLayout descSetLayout;
|
||||
VkDescriptorSet descSet;
|
||||
|
||||
VkSampler nearestSampler;
|
||||
VkSampler linearSampler;
|
||||
VkSampler shadowMapSampler;
|
||||
};
|
||||
|
||||
#endif //BINDLESSSETMANAGER_H
|
||||
@@ -57,6 +57,11 @@ public:
|
||||
|
||||
void waitIdle();
|
||||
|
||||
BindlessSetManager& getBindlessSetManager();
|
||||
VkDescriptorSetLayout getBindlessDescSetLayout() const;
|
||||
const VkDescriptorSet& getBindlessDescSet() const;
|
||||
void bindBindlessDescSet(VkCommandBuffer cmd, VkPipelineLayout layout) const;
|
||||
|
||||
void immediateSubmit(ImmediateExecuteFunction&& f) const;
|
||||
|
||||
vkb::Device getDevice() const { return device; }
|
||||
@@ -96,6 +101,8 @@ public:
|
||||
GPUImage loadImageFromFileRaw(const std::filesystem::path& path, VkFormat format, VkImageUsageFlags usage, bool mipMap) const;
|
||||
void destroyImage(const GPUImage& image) const;
|
||||
|
||||
ImageID getWhiteTextureID() { return whiteImageId; }
|
||||
|
||||
private:
|
||||
vkb::Instance instance;
|
||||
vkb::PhysicalDevice physicalDevice;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <destrum/Graphics/ids.h>
|
||||
#include <destrum/Graphics/GPUImage.h>
|
||||
#include <destrum/Graphics/BindlessSetManager.h>
|
||||
|
||||
// #include <destrum/Graphics/Vulkan/BindlessSetManager.h>
|
||||
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
|
||||
void destroyImages();
|
||||
|
||||
// BindlessSetManager bindlessSetManager;
|
||||
BindlessSetManager bindlessSetManager;
|
||||
|
||||
void setErrorImageId(ImageID id) { errorImageId = id; }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct MaterialData {
|
||||
glm::vec3 baseColor;
|
||||
glm::vec4 baseColor;
|
||||
glm::vec4 metalRoughnessEmissive;
|
||||
std::uint32_t diffuseTex;
|
||||
std::uint32_t normalTex;
|
||||
|
||||
@@ -17,11 +17,11 @@ public:
|
||||
void init(GfxDevice& gfxDevice);
|
||||
void cleanup(GfxDevice& gfxDevice);
|
||||
|
||||
MaterialId addMaterial(GfxDevice& gfxDevice, Material material);
|
||||
const Material& getMaterial(MaterialId id) const;
|
||||
MaterialID addMaterial(GfxDevice& gfxDevice, Material material);
|
||||
const Material& getMaterial(MaterialID id) const;
|
||||
|
||||
MaterialId getFreeMaterialId() const;
|
||||
MaterialId getPlaceholderMaterialId() const;
|
||||
MaterialID getFreeMaterialId() const;
|
||||
MaterialID getPlaceholderMaterialId() const;
|
||||
|
||||
const GPUBuffer& getMaterialDataBuffer() const { return materialDataBuffer; }
|
||||
VkDeviceAddress getMaterialDataBufferAddress() const { return materialDataBuffer.address; }
|
||||
@@ -33,7 +33,7 @@ private:
|
||||
GPUBuffer materialDataBuffer;
|
||||
|
||||
// material which is used for meshes without materials
|
||||
MaterialId placeholderMaterialId{NULL_MATERIAL_ID};
|
||||
MaterialID placeholderMaterialId{NULL_MATERIAL_ID};
|
||||
|
||||
ImageID defaultNormalMapTextureID{NULL_IMAGE_ID};
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ struct MeshDrawCommand {
|
||||
|
||||
// If set - mesh will be drawn with overrideMaterialId
|
||||
// instead of whatever material the mesh has
|
||||
MaterialId materialId{NULL_MATERIAL_ID};
|
||||
MaterialID materialId{NULL_MATERIAL_ID};
|
||||
|
||||
bool castShadow{true};
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
float fogDensity;
|
||||
};
|
||||
|
||||
explicit GameRenderer(MeshCache& meshCache);
|
||||
explicit GameRenderer(MeshCache& meshCache, MaterialCache& matCache);
|
||||
|
||||
void init(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize);
|
||||
void beginDrawing(GfxDevice& gfxDevice);
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
void draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera& camera, const SceneData& sceneData);
|
||||
void cleanup();
|
||||
|
||||
void drawMesh(MeshID id, const glm::mat4& transform, MaterialId materialId);
|
||||
void drawMesh(MeshID id, const glm::mat4& transform, MaterialID materialId);
|
||||
const GPUImage& getDrawImage(const GfxDevice& gfx_device) const;
|
||||
|
||||
void resize(GfxDevice& gfxDevice, const glm::ivec2& newSize) {
|
||||
@@ -43,7 +43,7 @@ private:
|
||||
void createDrawImage(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize, bool firstCreate);
|
||||
|
||||
MeshCache& meshCache;
|
||||
// MaterialCache& materialCache;
|
||||
MaterialCache& materialCache;
|
||||
|
||||
std::vector<MeshDrawCommand> meshDrawCommands;
|
||||
std::vector<std::size_t> sortedMeshDrawCommands;
|
||||
@@ -77,8 +77,6 @@ private:
|
||||
|
||||
NBuffer sceneDataBuffer;
|
||||
|
||||
MaterialCache materialCache;
|
||||
|
||||
|
||||
std::unique_ptr<MeshPipeline> meshPipeline;
|
||||
};
|
||||
|
||||
@@ -94,12 +94,12 @@ static std::vector<CPUMesh::Vertex> vertices = {
|
||||
};
|
||||
|
||||
static std::vector<uint32_t> indices = {
|
||||
0, 1, 2, 2, 3, 0, // Front
|
||||
4, 5, 6, 6, 7, 4, // Back
|
||||
8, 9,10, 10,11, 8, // Right
|
||||
12,13,14, 14,15,12, // Left
|
||||
16,17,18, 18,19,16, // Top
|
||||
20,21,22, 22,23,20 // Bottom
|
||||
0, 1, 2, 2, 3, 0, // Front (+Z)
|
||||
4, 7, 6, 6, 5, 4, // Back (-Z)
|
||||
8, 9,10, 10,11, 8, // Right (+X)
|
||||
12,13,14, 14,15,12, // Left (-X)
|
||||
16,17,18, 18,19,16, // Top (+Y)
|
||||
20,21,22, 22,23,20 // Bottom(-Y)
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ constexpr MeshID NULL_MESH_ID = std::numeric_limits<std::size_t>::max();
|
||||
using ImageID = std::uint16_t;
|
||||
constexpr ImageID NULL_IMAGE_ID = std::numeric_limits<std::uint16_t>::max();
|
||||
|
||||
using MaterialId = std::uint32_t;
|
||||
constexpr MaterialId NULL_MATERIAL_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
using MaterialID = std::uint32_t;
|
||||
constexpr MaterialID NULL_MATERIAL_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
using BindlessID = std::uint32_t;
|
||||
constexpr BindlessID NULL_BINDLESS_ID = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
@@ -6,59 +6,81 @@
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
class InputManager {
|
||||
#include <destrum/Singleton.h>
|
||||
|
||||
class InputManager: public Singleton<InputManager> {
|
||||
public:
|
||||
// Call once at startup (optional, but convenient)
|
||||
friend class Singleton<InputManager>;
|
||||
|
||||
void Init();
|
||||
|
||||
// Call at the start of every frame
|
||||
void BeginFrame();
|
||||
|
||||
// Feed SDL events into this (call for each SDL_PollEvent)
|
||||
void ProcessEvent(const SDL_Event& e);
|
||||
|
||||
// Call at end of frame if you want (not required)
|
||||
void EndFrame() {}
|
||||
|
||||
// ---- Queries ----
|
||||
bool IsKeyDown(SDL_Scancode sc) const; // held
|
||||
bool WasKeyPressed(SDL_Scancode sc) const; // pressed this frame
|
||||
bool WasKeyReleased(SDL_Scancode sc) const; // released this frame
|
||||
bool IsKeyDown(SDL_Scancode sc) const;
|
||||
bool WasKeyPressed(SDL_Scancode sc) const;
|
||||
bool WasKeyReleased(SDL_Scancode sc) const;
|
||||
|
||||
bool IsMouseDown(Uint8 button) const; // held (SDL_BUTTON_LEFT etc.)
|
||||
bool WasMousePressed(Uint8 button) const; // pressed this frame
|
||||
bool WasMouseReleased(Uint8 button) const; // released this frame
|
||||
bool IsMouseDown(Uint8 button) const;
|
||||
bool WasMousePressed(Uint8 button) const;
|
||||
bool WasMouseReleased(Uint8 button) const;
|
||||
|
||||
// Mouse position (window space)
|
||||
int MouseX() const { return m_mouseX; }
|
||||
int MouseY() const { return m_mouseY; }
|
||||
int MouseDeltaX() const { return m_mouseDX; }
|
||||
int MouseDeltaY() const { return m_mouseDY; }
|
||||
|
||||
// Mouse wheel (accumulated per frame)
|
||||
int WheelX() const { return m_wheelX; }
|
||||
int WheelY() const { return m_wheelY; }
|
||||
|
||||
// ---- Text input ----
|
||||
void StartTextInput();
|
||||
void StopTextInput();
|
||||
bool IsTextInputActive() const { return m_textInputActive; }
|
||||
const std::string& GetTextInput() const { return m_textInput; } // captured this frame
|
||||
const std::string& GetTextInput() const { return m_textInput; }
|
||||
|
||||
// ---- Action mapping ----
|
||||
enum class Device { Keyboard, MouseButton, MouseWheel };
|
||||
bool IsPadButtonDown(SDL_JoystickID id, SDL_GameControllerButton btn) const;
|
||||
bool WasPadButtonPressed(SDL_JoystickID id, SDL_GameControllerButton btn) const;
|
||||
bool WasPadButtonReleased(SDL_JoystickID id, SDL_GameControllerButton btn) const;
|
||||
|
||||
// axis in [-1..1]
|
||||
float GetPadAxis(SDL_JoystickID id, SDL_GameControllerAxis axis) const;
|
||||
|
||||
enum class Device { Keyboard, MouseButton, MouseWheel, GamepadButton, GamepadAxis };
|
||||
enum class ButtonState { Down, Pressed, Released };
|
||||
|
||||
struct Binding {
|
||||
Device device;
|
||||
int code; // SDL_Scancode for keyboard, Uint8 for mouse button, wheel axis sign encoding
|
||||
// For MouseWheel: code = +1/-1 for Y, +2/-2 for X (simple encoding)
|
||||
|
||||
// Keyboard: code = SDL_Scancode
|
||||
// MouseButton: code = Uint8
|
||||
// MouseWheel: code = +1/-1 => Y, +2/-2 => X
|
||||
//
|
||||
// GamepadButton: code = (padIndex<<8) | button (padIndex: 0..255)
|
||||
// GamepadAxis: code = (padIndex<<8) | axis (axis: SDL_GameControllerAxis)
|
||||
int code = 0;
|
||||
|
||||
// For GamepadAxis "button-like" checks:
|
||||
// sign: -1 means negative direction, +1 positive direction
|
||||
// threshold: absolute value in [0..1] that must be exceeded
|
||||
int sign = 0; // only used for GamepadAxis
|
||||
float threshold = 0.5f; // only used for GamepadAxis
|
||||
};
|
||||
|
||||
void BindAction(const std::string& action, const Binding& binding);
|
||||
bool GetAction(const std::string& action, ButtonState state) const;
|
||||
|
||||
// Convenience helpers to build controller bindings
|
||||
static Binding PadButton(uint8_t padIndex, SDL_GameControllerButton btn);
|
||||
static Binding PadAxis(uint8_t padIndex, SDL_GameControllerAxis axis, int sign, float threshold = 0.5f);
|
||||
|
||||
// Which controller is "padIndex 0/1/2..."? (based on connection order)
|
||||
SDL_JoystickID GetPadInstanceId(uint8_t padIndex) const;
|
||||
|
||||
void SetAxisDeadzone(int deadzone) { m_axisDeadzone = deadzone; } // 0..32767
|
||||
|
||||
private:
|
||||
// Key states
|
||||
std::unordered_set<SDL_Scancode> m_keysDown;
|
||||
@@ -75,18 +97,42 @@ private:
|
||||
int m_prevMouseX = 0, m_prevMouseY = 0;
|
||||
int m_mouseDX = 0, m_mouseDY = 0;
|
||||
|
||||
// Wheel (per-frame)
|
||||
int m_wheelX = 0, m_wheelY = 0;
|
||||
|
||||
// Text input (per-frame)
|
||||
bool m_textInputActive = false;
|
||||
std::string m_textInput;
|
||||
|
||||
// Action bindings
|
||||
std::unordered_map<std::string, std::vector<Binding>> m_bindings;
|
||||
|
||||
struct PadState {
|
||||
SDL_GameController* controller = nullptr;
|
||||
SDL_JoystickID instanceId = -1;
|
||||
|
||||
std::unordered_set<uint8_t> buttonsDown;
|
||||
std::unordered_set<uint8_t> buttonsPressed;
|
||||
std::unordered_set<uint8_t> buttonsReleased;
|
||||
|
||||
// raw s16 axes (SDL gives Sint16)
|
||||
std::array<Sint16, SDL_CONTROLLER_AXIS_MAX> axes{};
|
||||
std::array<Sint16, SDL_CONTROLLER_AXIS_MAX> prevAxes{};
|
||||
};
|
||||
|
||||
// Map instanceId -> PadState
|
||||
std::unordered_map<SDL_JoystickID, PadState> m_pads;
|
||||
|
||||
// padIndex -> instanceId (connection order list)
|
||||
std::vector<SDL_JoystickID> m_padOrder;
|
||||
|
||||
int m_axisDeadzone = 8000; // typical deadzone
|
||||
|
||||
private:
|
||||
bool QueryBinding(const Binding& b, ButtonState state) const;
|
||||
|
||||
void AddController(int deviceIndex);
|
||||
void RemoveController(SDL_JoystickID instanceId);
|
||||
|
||||
uint8_t GetPadIndexFromCode(int code) const { return static_cast<uint8_t>((code >> 8) & 0xFF); }
|
||||
uint8_t GetLow8FromCode(int code) const { return static_cast<uint8_t>(code & 0xFF); }
|
||||
};
|
||||
|
||||
#endif //INPUTMANAGER_H
|
||||
|
||||
Reference in New Issue
Block a user