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})
target_link_libraries(${PROJECT_NAME} PUBLIC Eigen3::Eigen spdlog::spdlog glfw aorii_core)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(${PROJECT_NAME} PRIVATE NOMINMAX)
add_os_definitions(${PROJECT_NAME})
configure_glfw_native(${PROJECT_NAME})

View File

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

View File

@ -27,7 +27,7 @@ void dx_pipeline::draw() {
constexpr UINT stride = sizeof(aorii_vertex_type);
constexpr UINT offset = 0;
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());
d3d_context->IASetVertexBuffers(0, 1, &v_buffer, &stride, &offset);
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,
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();
std::ranges::copy(in_vertexes, v_buffer);
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();
std::ranges::copy(in_triangles, i_buffer);
triangle_buffer->unlock();

View File

@ -3,9 +3,10 @@
#include <spdlog/spdlog.h>
#include "dx_renderer.h"
#include "core/renderer/renderer_context.h"
#include "misc/scope_exit.h"
#include <math.h>
using namespace aorii;
dx_pipeline pipeline;
@ -96,26 +97,58 @@ void dx_window::begin_frame() {
{
static std::chrono::duration<double> timer = {};
static linear_color random_color = { 0, 0, 0, 0 };
auto delta_time = get_delta_time();
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 linear_color random_color = { 0, 0, 0, 1 };
static bool is_white = false;
static float pos_x = 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) {
pos_x = 0;
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());
}

View File

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

View File

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

View File

@ -16,6 +16,26 @@ public:
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:
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;
};