新增dx_pipeline

This commit is contained in:
2024-10-20 17:29:11 +08:00
parent f6382ca361
commit 6333cb4f73
11 changed files with 122 additions and 39 deletions

View File

@@ -11,7 +11,6 @@ int main(int argc, char* argv[]) {
auto window = aorii::create_window({128, 128}, "hello world");
auto glfw_window = window->get_glfw_window();
while (!glfwWindowShouldClose(glfw_window)) {
glfwMakeContextCurrent(glfw_window);
glfwPollEvents();
aorii::s_renderer->render(0.01f);
}

View File

@@ -1,19 +1,22 @@
struct VSInput {
float3 position : POSITION;
float4 color : COLOR;
};
struct PSInput {
float4 position : SV_POSITION;
float4 color : COLOR;
};
PSInput vertex_main(VSInput input)
{
PSInput output;
output.position = float4(input.position, 1.0f);
output.color = input.color;
return output;
}
float4 pixel_main(PSInput input) : SV_TARGET
{
return float4(1.0f, 0.0f, 0.0f, 1.0f); // Red color
return input.color;
}

View File

@@ -11,6 +11,7 @@ endif()
set(RENDERER_SOURCES "")
retrieve_files(core RENDERER_SOURCES)
retrieve_files(misc RENDERER_SOURCES)
if (GL_BACKEND)
retrieve_files(backend/gl RENDERER_SOURCES)
endif()

View File

@@ -26,6 +26,21 @@ void dx_pipeline::use() {
d3d_context->IASetInputLayout(input_layout);
}
void dx_pipeline::draw() {
auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context();
// 设置顶点缓冲区
constexpr UINT stride = sizeof(vertex_type);
constexpr UINT offset = 0;
d3d_context->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
// 设置图元拓扑
d3d_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
// 绘制矩形
d3d_context->Draw(4, 0);
}
void dx_pipeline::set_pixel_shader(const std::string& shader_name) {
const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device();
const auto& shader_code = load_shader(shader_name);
@@ -38,15 +53,49 @@ void dx_pipeline::set_pixel_shader(const std::string& shader_name) {
void dx_pipeline::set_vertex_shader(const std::string& shader_name) {
const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device();
const auto& shader_code = load_shader(shader_name);
const auto hr = d3d_device->CreateVertexShader(shader_code.data(), shader_code.size(), nullptr, &vertex_shader);
auto hr = d3d_device->CreateVertexShader(shader_code.data(), shader_code.size(), nullptr, &vertex_shader);
if (FAILED(hr)) {
spdlog::critical("无法创建顶点着色器: {0}", hr);
return;
}
D3D11_INPUT_ELEMENT_DESC layout_desc[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
d3d_device->CreateInputLayout(layout_desc, 1, shader_code.data(), shader_code.size(), &input_layout);
hr = d3d_device->CreateInputLayout(layout_desc, 2, shader_code.data(), shader_code.size(), &input_layout);
if (FAILED(hr)) {
spdlog::critical("无法创建输入布局: {0}", hr);
return;
}
D3D11_BUFFER_DESC buffer_desc = {0};
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
buffer_desc.ByteWidth = sizeof(vertex_type) * 4;
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
hr = d3d_device->CreateBuffer(&buffer_desc, nullptr, &vertex_buffer);
if (FAILED(hr)) {
spdlog::critical("无法创建顶点缓冲区: {0}", hr);
}
}
std::span<vertex_type> dx_pipeline::lock_vertex_buffer() {
const auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context();
D3D11_MAPPED_SUBRESOURCE mapped_resource;
HRESULT hr = d3d_context->Map(vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource);
if (SUCCEEDED(hr)) {
// 更新顶点数据
vertex_data = static_cast<vertex_type*>(mapped_resource.pData);
// 这里更新顶点数据
return {vertex_data, 4};
}
return {};
}
void dx_pipeline::unlock_vertex_buffer() const {
const auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context();
d3d_context->Unmap(vertex_buffer, 0);
}
// void dx_pipeline::set_compute_shader(const std::string& shader_name) {

View File

@@ -4,16 +4,20 @@
#include <vector>
#include "core/pipeline/pipeline.h"
#include <span>
class dx_pipeline : public pipeline {
public:
~dx_pipeline() override;
void use() override;
void draw() override;
void set_pixel_shader(const std::string& shader_name) override;
void set_vertex_shader(const std::string& shader_name) override;
// void set_compute_shader(const std::string& shader_name) override;
std::span<vertex_type> lock_vertex_buffer();
void unlock_vertex_buffer() const;
private:
static std::vector<char> load_shader(const std::string& shader_name);
@@ -21,4 +25,7 @@ private:
ID3D11PixelShader* pixel_shader = nullptr;
// ID3D11ComputeShader* compute_shader = nullptr;
ID3D11InputLayout* input_layout = nullptr;
ID3D11Buffer* vertex_buffer = nullptr;
vertex_type* vertex_data = nullptr;
};

View File

@@ -67,26 +67,11 @@ bool dx_window::create_surface(GLFWwindow* in_window) {
pipeline.set_pixel_shader("default_shader_pixel");
pipeline.set_vertex_shader("default_shader_vertex");
Eigen::Vector3f vertices[] = {
{-0.5f, -0.5f, 0.0f},
{0.5f, -0.5f, 0.0f},
{0.5f, 0.5f, 0.0f},
{-0.5f, 0.5f, 0.0f}
};
D3D11_BUFFER_DESC buffer_desc = {0};
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
buffer_desc.ByteWidth = sizeof(vertex_data) * 4;
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA subresource_data = {};
subresource_data.pSysMem = vertices;
d3d_device->CreateBuffer(&buffer_desc, &subresource_data, &vertex_buffer);
return true;
}
void dx_window::begin_frame() {
glfwMakeContextCurrent(get_glfw_window());
const auto render = aorii::get_renderer<dx_renderer>();
const auto d3d_context = render->get_d3d_context();
@@ -95,16 +80,24 @@ void dx_window::begin_frame() {
pipeline.use();
// 设置顶点缓冲区
UINT stride = sizeof(Eigen::Vector3f);
UINT offset = 0;
d3d_context->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
float random_r = static_cast<float>(rand()) / RAND_MAX;
float random_g = static_cast<float>(rand()) / RAND_MAX;
float random_b = static_cast<float>(rand()) / RAND_MAX;
linear_color random_color = {random_r, random_g, random_b, 1.0f};
// 设置图元拓扑
d3d_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
const vertex_type v1 {{-0.5f, 0.5f, 0.0f}, random_color };
const vertex_type v2 {{0.5f, 0.5f, 0.0f}, random_color };
const vertex_type v3 {{-0.5f, -0.5f, 0.0f}, random_color };
const vertex_type v4 {{0.5f, -0.5f, 0.0f}, random_color };
const vertex_type vertices[] = {
v1, v2, v3, v4
};
// 绘制矩形
d3d_context->Draw(4, 0);
auto vertex_buffer = pipeline.lock_vertex_buffer();
std::ranges::copy(vertices, vertex_buffer.begin());
pipeline.unlock_vertex_buffer();
pipeline.draw();
swap_chain->Present(1, 0);
}

View File

@@ -19,6 +19,4 @@ private:
ID3D11RenderTargetView* render_target_view = nullptr;
dx_pipeline pipeline;
ID3D11Buffer* vertex_buffer;
};

View File

@@ -1,11 +1,23 @@
#pragma once
#include <string>
#include <Eigen/Eigen>
#include "misc/color.h"
struct aorii_vertex {
Eigen::Vector3f position;
linear_color color;
};
using vertex_type = aorii_vertex;
class pipeline {
public:
virtual ~pipeline() = default;
virtual void use() = 0;
virtual void draw() = 0;
virtual void set_vertex_shader(const std::string& shader_name) = 0;
virtual void set_pixel_shader(const std::string& shader_name) = 0;

View File

@@ -44,7 +44,7 @@ namespace aorii {
bool create_renderer(renderer_api api);
void destroy_renderer();
inline std::filesystem::path s_shader_relative_path = "resource/shaders";
inline std::filesystem::path s_shader_relative_path = "resource/shader";
inline void set_shader_relative_path(const std::filesystem::path& path) { s_shader_relative_path = path; }
inline std::filesystem::path get_shader_path(const std::string& shader_name) { return std::filesystem::current_path() / s_shader_relative_path / shader_name; }
}

View File

@@ -19,20 +19,20 @@ public:
on_resize(in_size);
}
Eigen::Vector2i get_window_size() const {
[[nodiscard]] Eigen::Vector2i get_window_size() const {
int w, h;
glfwGetWindowSize(window, &w, &h);
return Eigen::Vector2i(w, h);
return { w, h };
}
Eigen::Vector2i get_framebuffer_size() const {
[[nodiscard]] Eigen::Vector2i get_framebuffer_size() const {
int w, h;
glfwGetFramebufferSize(window, &w, &h);
return Eigen::Vector2i(w, h);
return { w, h };
}
void* get_window_handle() const;
GLFWwindow* get_glfw_window() const { return window; }
[[nodiscard]] void* get_window_handle() const;
[[nodiscard]] GLFWwindow* get_glfw_window() const { return window; }
protected:
virtual bool create_surface(GLFWwindow* in_window) = 0;
virtual void on_resize(const Eigen::Vector2i& in_size) = 0;

21
src/renderer/misc/color.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <complex>
class linear_color {
public:
linear_color(float in_r, float in_g, float in_b, float in_a = 1.0f) : r(in_r), g(in_g), b(in_b), a(in_a) {}
static linear_color from_srgb(float in_r, float in_g, float in_b, float in_a = 1.0f) {
return linear_color(
in_r <= 0.04045f ? in_r / 12.92f : std::pow((in_r + 0.055f) / 1.055f, 2.4f),
in_g <= 0.04045f ? in_g / 12.92f : std::pow((in_g + 0.055f) / 1.055f, 2.4f),
in_b <= 0.04045f ? in_b / 12.92f : std::pow((in_b + 0.055f) / 1.055f, 2.4f),
in_a
);
}
static linear_color from_srgb(const linear_color& in_color) {
return from_srgb(in_color.r, in_color.g, in_color.b, in_color.a);
}
private:
float r, g, b, a;
};