void Mesh::DrawGeometry() { auto device = Device::GetInstance(); auto meshShader = ShaderStock::GetInstance()->GetMeshShader(); if (this->vertices.size() > 0 && this->triangles.size() > 0) { //TODO : add support for more vertex and material formats if (this->changed) { std::vector<VertexFormatItem> vfitems; vfitems.push_back(VertexFormatItem(0, DataType::FLOAT3, "POSITION", 0, 0)); vfitems.push_back(VertexFormatItem(sizeof(float) * 3, DataType::FLOAT3, "NORMAL", 0, 0)); vfitems.push_back(VertexFormatItem(sizeof(float) * 6, DataType::FLOAT2, "TEXCOORD", 0, 0)); this->vertexFormat = device->CreateVertexFormat(vfitems, meshShader, "Mesh", 0); std::vector<MeshVertex> data(this->vertices.size()); for (size_t i = 0; i < this->vertices.size(); i++) { data[i].x = this->vertices[i].x; data[i].y = this->vertices[i].y; data[i].z = this->vertices[i].z; data[i].nx = this->normals[i].x; data[i].ny = this->normals[i].y; data[i].nz = this->normals[i].z; data[i].u = this->uv[0][i].x; data[i].v = this->uv[0][i].y; } if (this->isDynamic == false) { this->vertexBuffer = device->CreateStaticVertexBuffer(sizeof(MeshVertex) * data.size(), &data[0]).Get(); this->indexBuffer = device->CreateStaticIndexBuffer(sizeof(uint32_t) * triangles.size(), &triangles[0]).Get(); } this->changed = false; } device->SetVertexFormat(this->vertexFormat); device->SetVertexBuffer(this->vertexBuffer, sizeof(MeshVertex), 0); device->SetIndexBuffer(this->indexBuffer); if (this->material.texture) { meshShader->SetTexture("g_texture", this->material.texture); meshShader->SetBoolean("g_hasTexture", true); } else { meshShader->SetBoolean("g_hasTexture", false); } meshShader->SetValue("g_material", &this->material, sizeof(Material) - sizeof(Texture*)); meshShader->CommitChanges(); device->DrawIndexed(PrimitiveType::TRIANGLE_LIST, this->triangles.size(), 0, 0); } for (size_t i = 0; i < this->subMeshes.size(); i++) this->subMeshes[i]->DrawGeometry(); }
void Terrain::GenerateBuffers() { auto device = Device::GetInstance(); std::vector<TerrainVertex> vertices(this->xResolution * this->yResolution); float left = -this->xWidth / 2; float bottom = -this->yWidth / 2; float xWidthPerCell = this->xWidth / (this->xResolution - 1); float yWidthPerCell = this->yWidth / (this->yResolution - 1); float du = 1.0f / (this->xResolution - 1); float dv = 1.0f / (this->yResolution - 1); for (size_t i = 0; i < this->xResolution; i++) { for (size_t j = 0; j < this->yResolution; j++) { size_t index = i * xResolution + j; vertices[index].x = left + xWidthPerCell * i; vertices[index].y = 0; vertices[index].z = bottom + yWidthPerCell * j; vertices[index].u = du * i; vertices[index].v = dv * j; } } this->vb = device->CreateStaticVertexBuffer(sizeof(TerrainVertex) * vertices.size(), &vertices[0]); std::vector<uint32_t> indices; for (size_t i = 0; i < this->xResolution - 1; i++) { for (size_t j = 0; j < this->yResolution - 1; j++) { size_t a = i * this->xResolution + j; size_t b = a + 1; size_t c = (i + 1)*this->xResolution + j; size_t d = c + 1; indices.push_back(a); indices.push_back(b); indices.push_back(c); indices.push_back(b); indices.push_back(d); indices.push_back(c); } } this->ib = device->CreateStaticIndexBuffer(sizeof(uint32_t) * indices.size(), &indices[0]); this->cellSize.x = xWidthPerCell; this->cellSize.y = yWidthPerCell; this->dTexCoord.x = du; this->dTexCoord.y = dv; }
void CGUIFontTTFDX::LastEnd() { ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); if (!pContext) return; typedef CGUIFontTTFBase::CTranslatedVertices trans; bool transIsEmpty = std::all_of(m_vertexTrans.begin(), m_vertexTrans.end(), [](trans& _) { return _.vertexBuffer->size <= 0; }); // no chars to render if (m_vertex.empty() && transIsEmpty) return; CreateStaticIndexBuffer(); unsigned int offset = 0; unsigned int stride = sizeof(SVertex); CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader(); // Set font texture as shader resource ID3D11ShaderResourceView* resources[] = { m_speedupTexture->GetShaderResource() }; pGUIShader->SetShaderViews(1, resources); // Enable alpha blend g_Windowing.SetAlphaBlendEnable(true); // Set our static index buffer pContext->IASetIndexBuffer(m_staticIndexBuffer, DXGI_FORMAT_R16_UINT, 0); // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); if (!m_vertex.empty()) { // Deal with vertices that had to use software clipping if (!UpdateDynamicVertexBuffer(&m_vertex[0], m_vertex.size())) return; // Set the dynamic vertex buffer to active in the input assembler pContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset); // Do the actual drawing operation, split into groups of characters no // larger than the pre-determined size of the element array size_t size = m_vertex.size() / 4; for (size_t character = 0; size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) { size_t count = size - character; count = std::min<size_t>(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); // 6 indices and 4 vertices per character pGUIShader->DrawIndexed(count * 6, 0, character * 4); } } if (!transIsEmpty) { // Deal with the vertices that can be hardware clipped and therefore translated // Store current GPU transform XMMATRIX view = pGUIShader->GetView(); // Store current scissor CRect scissor = g_graphicsContext.StereoCorrection(g_graphicsContext.GetScissors()); for (size_t i = 0; i < m_vertexTrans.size(); i++) { // ignore empty buffers if (m_vertexTrans[i].vertexBuffer->size == 0) continue; // Apply the clip rectangle CRect clip = g_Windowing.ClipRectToScissorRect(m_vertexTrans[i].clip); // Intersect with current scissors clip.Intersect(scissor); // skip empty clip, a little improvement to not render invisible text if (clip.IsEmpty()) continue; g_Windowing.SetScissors(clip); // Apply the translation to the model view matrix XMMATRIX translation = XMMatrixTranslation(m_vertexTrans[i].translateX, m_vertexTrans[i].translateY, m_vertexTrans[i].translateZ); pGUIShader->SetView(XMMatrixMultiply(translation, view)); CD3DBuffer* vbuffer = reinterpret_cast<CD3DBuffer*>(m_vertexTrans[i].vertexBuffer->bufferHandle); // Set the static vertex buffer to active in the input assembler ID3D11Buffer* buffers[1] = { vbuffer->Get() }; pContext->IASetVertexBuffers(0, 1, buffers, &stride, &offset); // Do the actual drawing operation, split into groups of characters no // larger than the pre-determined size of the element array for (size_t character = 0; m_vertexTrans[i].vertexBuffer->size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) { size_t count = m_vertexTrans[i].vertexBuffer->size - character; count = std::min<size_t>(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); // 6 indices and 4 vertices per character pGUIShader->DrawIndexed(count * 6, 0, character * 4); } } // restore scissor g_Windowing.SetScissors(scissor); // Restore the original transform pGUIShader->SetView(view); } pGUIShader->RestoreBuffers(); }