#include "instanced_test.h" #include #include #include #include #include #include namespace extra2d { InstancedTestNode::InstancedTestNode() { setName("InstancedTest"); } InstancedTestNode::~InstancedTestNode() { instanceBuffer_.shutdown(); } bool InstancedTestNode::initialize(uint32_t instanceCount) { instanceCount_ = instanceCount; // 获取资源模块 auto* assets = getModule(); if (!assets) { E2D_LOG_ERROR("InstancedTestNode: AssetsModule not available"); return false; } // 使用默认网格(四边形) mesh_ = assets->getDefaultQuad(); if (!mesh_.isValid()) { E2D_LOG_ERROR("InstancedTestNode: Failed to get default quad mesh"); return false; } // 使用默认纹理 texture_ = assets->getDefaultTexture(); // 获取实例化渲染材质 material_ = assets->getInstancedMaterial(); if (!material_.isValid()) { E2D_LOG_ERROR("InstancedTestNode: Failed to get instanced material"); return false; } // 初始化实例缓冲区 if (!instanceBuffer_.initialize(instanceCount)) { E2D_LOG_ERROR("InstancedTestNode: Failed to initialize instance buffer"); return false; } // 预分配实例数据 instanceData_.resize(instanceCount); // 初始化实例数据 updateInstances(); E2D_LOG_INFO("InstancedTestNode initialized with {} instances", instanceCount); return true; } void InstancedTestNode::update(float dt) { time_ += dt; // 更新实例变换 updateInstances(); // 更新GPU缓冲区 if (!instanceData_.empty()) { instanceBuffer_.updateInstances(instanceData_.data(), instanceCount_); } } void InstancedTestNode::updateInstances() { // 创建螺旋分布的实例 float radius = 200.0f; float centerX = 640.0f; float centerY = 360.0f; for (uint32_t i = 0; i < instanceCount_; ++i) { float t = static_cast(i) / instanceCount_; float angle = t * 6.28318f * 3.0f + time_; // 3圈螺旋 float r = radius * (0.2f + 0.8f * t); // 位置 instanceData_[i].position.x = centerX + r * std::cos(angle); instanceData_[i].position.y = centerY + r * std::sin(angle); // 旋转(朝向中心) instanceData_[i].rotation = angle + 1.5708f; // 缩放(随距离变化) float scale = 0.5f + 0.5f * t; instanceData_[i].scale.x = scale * 32.0f; instanceData_[i].scale.y = scale * 32.0f; // 颜色(彩虹色) float hue = t + time_ * 0.1f; float r_color = std::abs(std::fmod(hue * 6.0f, 2.0f) - 1.0f); float g_color = std::abs(std::fmod(hue * 6.0f + 2.0f, 2.0f) - 1.0f); float b_color = std::abs(std::fmod(hue * 6.0f + 4.0f, 2.0f) - 1.0f); instanceData_[i].color.r = r_color; instanceData_[i].color.g = g_color; instanceData_[i].color.b = b_color; instanceData_[i].color.a = 1.0f; // UV坐标(使用完整纹理) instanceData_[i].uvX = 0.0f; instanceData_[i].uvY = 0.0f; instanceData_[i].uvWidth = 1.0f; instanceData_[i].uvHeight = 1.0f; } } void InstancedTestNode::render() { if (!isVisible() || instanceCount_ == 0) { return; } // 检查资源有效性 if (!mesh_.isValid() || !material_.isValid() || !instanceBuffer_.isValid()) { return; } // 提交实例化渲染命令 RenderCommand cmd; cmd.type = RenderCommandType::DrawMeshInstanced; cmd.sortKey = 0; cmd.drawInstanced.mesh = mesh_; cmd.drawInstanced.material = material_; cmd.drawInstanced.instanceBuffer = &instanceBuffer_; cmd.drawInstanced.instanceCount = instanceCount_; cmd.drawInstanced.instanceOffset = 0; events::OnRenderSubmit::emit(cmd); } } // namespace extra2d