color新增部分运算符

修复dx_buffer在resize时可能会复制越界问题
修复dx_pipeline使用了错误的index_buffer
测试渐变颜色绘制
This commit is contained in:
Nanako 2024-11-04 21:22:45 +08:00
parent be2486563f
commit 498a75c95f
7 changed files with 89 additions and 28 deletions

View File

@ -28,6 +28,7 @@ endif ()
add_library(${PROJECT_NAME} STATIC ${RENDERER_SOURCES}) add_library(${PROJECT_NAME} STATIC ${RENDERER_SOURCES})
target_link_libraries(${PROJECT_NAME} PUBLIC Eigen3::Eigen spdlog::spdlog glfw aorii_core) target_link_libraries(${PROJECT_NAME} PUBLIC Eigen3::Eigen spdlog::spdlog glfw aorii_core)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(${PROJECT_NAME} PRIVATE NOMINMAX)
add_os_definitions(${PROJECT_NAME}) add_os_definitions(${PROJECT_NAME})
configure_glfw_native(${PROJECT_NAME}) configure_glfw_native(${PROJECT_NAME})

View File

@ -39,7 +39,6 @@ private:
template<typename DataType> template<typename DataType>
dx_buffer<DataType>::dx_buffer(buffer_type in_type, const int in_count): renderer_buffer<DataType>(in_type, in_count) { dx_buffer<DataType>::dx_buffer(buffer_type in_type, const int in_count): renderer_buffer<DataType>(in_type, in_count) {
const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device(); const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device();
const auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context();
D3D11_BUFFER_DESC buffer_desc = {}; D3D11_BUFFER_DESC buffer_desc = {};
buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
@ -81,30 +80,34 @@ template<typename DataType>
void dx_buffer<DataType>::on_resize(int new_count) { void dx_buffer<DataType>::on_resize(int new_count) {
const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device(); const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device();
const auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context(); const auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context();
// 获取原始缓冲区的描述
D3D11_BUFFER_DESC old_desc = {};
if (buffer) {
buffer->GetDesc(&old_desc);
}
D3D11_BUFFER_DESC buffer_desc = {}; D3D11_BUFFER_DESC buffer_desc = old_desc;
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
buffer_desc.ByteWidth = sizeof(DataType) * new_count; buffer_desc.ByteWidth = sizeof(DataType) * new_count;
buffer_desc.BindFlags = get_dx_buffer_type();
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
ID3D11Buffer* new_buffer = nullptr; ID3D11Buffer* new_buffer = nullptr;
auto hr = d3d_device->CreateBuffer(&buffer_desc, nullptr, &new_buffer); auto hr = d3d_device->CreateBuffer(&buffer_desc, nullptr, &new_buffer);
if (FAILED(hr)) { if (FAILED(hr)) {
spdlog::critical("无法创建缓冲区: {0}", hr); spdlog::critical("无法创建缓冲区: {0}", hr);
return; return;
} }
if (new_buffer) { if (new_buffer && buffer) {
// 计算要复制的实际大小(取原始大小和新大小的较小值)
const auto copy_size = std::min(old_desc.ByteWidth, buffer_desc.ByteWidth);
// 复制旧数据到新缓冲区 // 复制旧数据到新缓冲区
D3D11_BOX source_region; D3D11_BOX source_region;
source_region.left = 0; source_region.left = 0;
source_region.right = sizeof(DataType) * new_count; source_region.right = copy_size;
source_region.top = 0; source_region.top = 0;
source_region.bottom = 1; source_region.bottom = 1;
source_region.front = 0; source_region.front = 0;
source_region.back = 1; source_region.back = 1;
d3d_context->CopySubresourceRegion(new_buffer, 0, 0, 0, 0, buffer, 0, &source_region); d3d_context->CopySubresourceRegion(new_buffer, 0, 0, 0, 0, buffer, 0, &source_region);
buffer->Release();
} }
if (buffer)
buffer->Release();
buffer = new_buffer; buffer = new_buffer;
} }

View File

@ -27,7 +27,7 @@ void dx_pipeline::draw() {
constexpr UINT stride = sizeof(aorii_vertex_type); constexpr UINT stride = sizeof(aorii_vertex_type);
constexpr UINT offset = 0; constexpr UINT offset = 0;
auto* v_buffer = static_cast<ID3D11Buffer*>(vertex_buffer->get_native_handle()); auto* v_buffer = static_cast<ID3D11Buffer*>(vertex_buffer->get_native_handle());
auto* i_buffer = static_cast<ID3D11Buffer*>(constant_buffer->get_native_handle()); auto* i_buffer = static_cast<ID3D11Buffer*>(triangle_buffer->get_native_handle());
auto* c_buffer = static_cast<ID3D11Buffer*>(constant_buffer->get_native_handle()); auto* c_buffer = static_cast<ID3D11Buffer*>(constant_buffer->get_native_handle());
d3d_context->IASetVertexBuffers(0, 1, &v_buffer, &stride, &offset); d3d_context->IASetVertexBuffers(0, 1, &v_buffer, &stride, &offset);
d3d_context->IASetIndexBuffer(i_buffer, DXGI_FORMAT_R32_UINT, 0); d3d_context->IASetIndexBuffer(i_buffer, DXGI_FORMAT_R32_UINT, 0);
@ -82,12 +82,12 @@ void dx_pipeline::build_constant_buffer() {
void dx_pipeline::set_triangle(const std::span<const aorii_vertex_type>& in_vertexes, void dx_pipeline::set_triangle(const std::span<const aorii_vertex_type>& in_vertexes,
const std::span<const aorii_triangle_type>& in_triangles) { const std::span<const aorii_triangle_type>& in_triangles) {
if (vertex_buffer->get_size() > in_vertexes.size()) { vertex_buffer->resize(in_vertexes.size()); } if (vertex_buffer->get_size() < in_vertexes.size()) { vertex_buffer->resize(in_vertexes.size()); }
aorii_vertex_type* v_buffer = vertex_buffer->lock(); aorii_vertex_type* v_buffer = vertex_buffer->lock();
std::ranges::copy(in_vertexes, v_buffer); std::ranges::copy(in_vertexes, v_buffer);
vertex_buffer->unlock(); vertex_buffer->unlock();
if (triangle_buffer->get_size() > in_triangles.size()) { triangle_buffer->resize(in_triangles.size()); } if (triangle_buffer->get_size() < in_triangles.size()) { triangle_buffer->resize(in_triangles.size()); }
aorii_triangle_type* i_buffer = triangle_buffer->lock(); aorii_triangle_type* i_buffer = triangle_buffer->lock();
std::ranges::copy(in_triangles, i_buffer); std::ranges::copy(in_triangles, i_buffer);
triangle_buffer->unlock(); triangle_buffer->unlock();

View File

@ -3,9 +3,10 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include "dx_renderer.h" #include "dx_renderer.h"
#include "core/renderer/renderer_context.h"
#include "misc/scope_exit.h" #include "misc/scope_exit.h"
#include <math.h>
using namespace aorii; using namespace aorii;
dx_pipeline pipeline; dx_pipeline pipeline;
@ -96,26 +97,58 @@ void dx_window::begin_frame() {
{ {
static std::chrono::duration<double> timer = {}; static std::chrono::duration<double> timer = {};
static linear_color random_color = { 0, 0, 0, 0 }; static linear_color random_color = { 0, 0, 0, 1 };
auto delta_time = get_delta_time(); static bool is_white = false;
timer += delta_time;
if (timer.count() >= 1) {
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;
random_color = { random_r, random_g, random_b, 1.0f };
timer -= std::chrono::seconds(1);
}
static float pos_x = 0; static float pos_x = 0;
static float pos_y = 0; static float pos_y = 0;
static bool draw_test = true;
pos_x += delta_time.count() * 1000; auto delta_time = get_delta_time();
timer += delta_time;
if (draw_test && timer.count() >= 0.01) {
// 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;
// random_color = { random_r, random_g, random_b, 1.0f };
// 生成渐变色
if (is_white) {
if (random_color.r > 0) {
random_color.r -= 0.01f;
} else if (random_color.b > 0) {
random_color.b -= 0.01f;
} else if (random_color.g > 0) {
random_color.g -= 0.01f;
} else {
is_white = false;
random_color = {0.0f, 0.0f, 0.0f, 1.0f};
}
}
else {
if (random_color.r < 1) {
random_color.r += 0.01f;
} else if (random_color.b < 1) {
random_color.b += 0.01f;
} else if (random_color.g < 1) {
random_color.g += 0.01f;
} else {
is_white = true;
random_color = {1.0f, 1.0f, 1.0f, 1.0f};
}
}
timer -= std::chrono::duration<double>(0.01);
context.draw_rectangle({pos_x, pos_y}, {1, 1000}, random_color);
}
pos_x += delta_time.count() * 100;
if (pos_x >= 1000) { if (pos_x >= 1000) {
pos_x = 0; pos_x = 0;
pos_y += 1; pos_y += 1;
draw_test = false;
} }
renderer_context context;
context.draw_rectangle({pos_x, pos_y}, {100, 1000}, random_color);
pipeline.set_triangle(context.get_vertices(), context.get_triangles()); pipeline.set_triangle(context.get_vertices(), context.get_triangles());
} }

View File

@ -3,6 +3,7 @@
#include <dxgi1_2.h> #include <dxgi1_2.h>
#include "dx_pipeline.h" #include "dx_pipeline.h"
#include "core/renderer/renderer_context.h"
#include "core/window/renderer_window.h" #include "core/window/renderer_window.h"
class dx_window : public renderer_window { class dx_window : public renderer_window {
@ -15,7 +16,7 @@ protected:
HRESULT build_render_target_view(); HRESULT build_render_target_view();
private: private:
renderer_context context;
IDXGISwapChain1* swap_chain = nullptr; IDXGISwapChain1* swap_chain = nullptr;
ID3D11RenderTargetView* render_target_view = nullptr; ID3D11RenderTargetView* render_target_view = nullptr;
Eigen::Matrix4f projection_matrix; Eigen::Matrix4f projection_matrix;

View File

@ -19,6 +19,9 @@ public:
void resize(const int new_size) { void resize(const int new_size) {
if (new_size == size) if (new_size == size)
return; return;
if (new_size < 1) {
return;
}
size = new_size; size = new_size;
on_resize(new_size); on_resize(new_size);
} }

View File

@ -16,6 +16,26 @@ public:
static linear_color from_srgb(const linear_color& in_color) { 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); return from_srgb(in_color.r, in_color.g, in_color.b, in_color.a);
} }
private:
linear_color& operator+=(const linear_color& in_color) {
r += in_color.r;
g += in_color.g;
b += in_color.b;
a += in_color.a;
return *this;
}
linear_color& operator-=(const linear_color& in_color) {
r -= in_color.r;
g -= in_color.g;
b -= in_color.b;
a -= in_color.a;
return *this;
}
linear_color operator+(const linear_color& in_color) const {
return { r + in_color.r, g + in_color.g, b + in_color.b, a + in_color.a };
}
linear_color operator-(const linear_color& in_color) const {
return { r - in_color.r, g - in_color.g, b - in_color.b, a - in_color.a };
}
float r, g, b, a; float r, g, b, a;
}; };