#include "brush.h" #include "baseentity.h" #include "cglm/mat4.h" #include "physics.h" #include "rendering.h" #include "tier0/platform.h" #include "tier1/utlbuffer.h" #include "tier1/utlvector.h" #include "math3d.h" CUtlVector g_BrushVertices; void CBrushEntity::Precache() { } void CBrushEntity::Spawn() { /* physics don't support unindexed meshes, so generate indicies */ CUtlBuffer indicies(m_mesh.GetSize()*3); for (uint32_t i = 0;i> triangles(m_mesh.GetSize()*3); uint32_t i = 0; for (auto tri: m_mesh) { V_memcpy(&triangles[i],tri.location,36); i+=3; } /* use them */ px_collider_params params = {}; params.friction = 0.0; m_collider = px_trimesh((Point*)triangles.GetMemory(), triangles.GetSize(), (uint32_t(*)[3])indicies.GetMemory(), indicies.GetSize()/3 ,params); px_fixedbody(px, m_collider); }; void CBrushEntity::Destroy() { } void CBrushEntity::Think( float fDelta ) { }; void CBrushEntity::Sync( void *pData, uint32_t nDataSize ) { }; void CBrushEntity::ReadParameter( const char *szName, const char *szValue ) { CBaseEntity::ReadParameter(szName, szValue); }; void C_BrushEntity::Precache() { CBrushEntity* pBrushEntity = dynamic_cast(pEntity); if (!pBrushEntity) Plat_FatalErrorFunc("pEntity is not a CBrushEntity"); } void C_BrushEntity::Spawn() { struct Vertex_t { float position[3]; float uv[2]; }; CBrushEntity* pBrushEntity = (CBrushEntity*)pEntity; uint32_t numVertices = pBrushEntity->m_mesh.GetSize(); vertexBuffer = IRenderer::CreateVertexBuffer(numVertices*60); Vertex_t *pTriangles = (Vertex_t*)vertexBuffer->Map(); uint32_t i = 0; for (auto &triangle: pBrushEntity->m_mesh) { pTriangles[i].position[0] = triangle.location[0]; pTriangles[i].position[1] = triangle.location[1]; pTriangles[i].position[2] = triangle.location[2]; pTriangles[i].uv[0] = triangle.uv[0]; pTriangles[i].uv[1] = triangle.uv[1]; pTriangles[i+1].position[0] = triangle.location[3]; pTriangles[i+1].position[1] = triangle.location[4]; pTriangles[i+1].position[2] = triangle.location[5]; pTriangles[i+1].uv[0] = triangle.uv[2]; pTriangles[i+1].uv[1] = triangle.uv[3]; pTriangles[i+2].position[0] = triangle.location[6]; pTriangles[i+2].position[1] = triangle.location[7]; pTriangles[i+2].position[2] = triangle.location[8]; pTriangles[i+2].uv[0] = triangle.uv[4]; pTriangles[i+2].uv[1] = triangle.uv[5]; i+=3; } vertexBuffer->Unmap(); }; void C_BrushEntity::Destroy() { } void C_BrushEntity::Think( float fDelta ) { g_BrushVertices.AppendTail(vertexBuffer); }; class CBrushRendering: public IRenderingPipelineStep { public: virtual void Init() override; virtual void Frame( float fDelta ) override; virtual void Deinit() override; private: }; DECLARE_MESH_RENDERING_STAGE(CBrushRendering, brush_rasterizer); IGraphicsPipeline *g_BrushPipeline; ITexture *bricks; void CBrushRendering::Init() { g_BrushPipeline = IRenderer::CreateGraphicsPipeline( { {"gfx/mesh_vert.shader", SHADER_TYPE_VERTEX}, {"gfx/mesh_frag.shader", SHADER_TYPE_FRAGMENT}, }, { {SHADER_INPUT_TYPE_UNIFORM_BUFFER,0}, {SHADER_INPUT_TYPE_TEXTURES,1}, }, 80, 20, {{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32Z32}, {12,1,EVertexFormat::VERTEX_FORMAT_X32Y32}}, {EImageFormat::IMAGE_FORMAT_R8G8B8A8}, true ); bricks = ITextureManager::LoadTexture("textures/bricks.png"); }; void CBrushRendering::Frame( float fDelta ) { IRenderer::ResetState(); IRenderer::SetDepthMode(DEPTH_MODE_LESS); IRenderer::BindPipeline(g_BrushPipeline); struct { mat4 i; uint32_t a = ITextureManager::GetTextureID(bricks); uint32_t b = 0; uint32_t c = 0; } constants; glm_mat4_identity(constants.i); IRenderer::SetConstants(sizeof(constants), &constants); IRenderer::BindData(0, IRenderer::GetCameraMatrix(), 0); IRenderer::PushBindings(); for (auto &v: g_BrushVertices) { IRenderer::Draw(v, 0); } g_BrushVertices = {}; }; void CBrushRendering::Deinit() { };