Intro :
Il peut être utile d’afficher des lignes dans la surface de rendu ; par exemple pour représenter des normales, des trajectoires, un repère, etc…
Prérequis :
– Savoir lire du C++
– Savoir utiliser la classe MeshSceneNode
– Savoir utiliser la classe ShaderTechnique et les déclarations de vertices.
Explications :
Voici le fichier Vertex3DLine.h :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#ifndef MESH_3D_LINE_H #define MESH_3D_LINE_H class Vertex3DLine : public MeshSceneNode { public: Vertex3DLine(unsigned int bufferBytesSize); virtual ~Vertex3DLine(); bool Initialize(); void AddLine(D3DXVECTOR3 startPoint, D3DXVECTOR3 endPoint, D3DXCOLOR color); private: void ResizeVertexBuffer(unsigned int iNewBytesSize); private: std::vector<PCVertex> m_vertices; unsigned int m_bufferBytesSize; }; #endif |
Voici le fichier Vertex3DLine.cpp :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
#include "Vertex3DLine.h" Vertex3DLine::Vertex3DLine(unsigned int bufferBytesSize) : m_bufferBytesSize(bufferBytesSize) { SetVertexType(VertexLayoutType::PC_VERTEX); SetDrawMethod(DrawMethod::DRAW_NORMAL); SetTopology(D3D10_PRIMITIVE_TOPOLOGY_LINELIST); SetShaderTechnique( SHADER_MANAGER->GetShader("Vertex3DLine") ); } Vertex3DLine::~Vertex3DLine() { m_vertices.clear(); } bool Vertex3DLine::Initialize() { HRESULT hr; D3D10_BUFFER_DESC bd; bd.Usage = D3D10_USAGE_DYNAMIC; bd.ByteWidth = sizeof(PCVertex) * m_bufferBytesSize; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; hr = D3D10_RENDERER->GetDevice()->CreateBuffer(&bd, 0, &m_pVertexBuffer); if (FAILED(hr)) { ShowMessageBoxDXError(hr); return false; } return true; } void Vertex3DLine::AddLine(D3DXVECTOR3 startPoint, D3DXVECTOR3 endPoint, D3DXCOLOR color) { if (!m_pVertexBuffer) { return; } D3D10_BUFFER_DESC bd; m_pVertexBuffer->GetDesc(&bd); unsigned int iActualBufferBytesSize = bd.ByteWidth; unsigned int iNewBufferBytesSize = (m_vertices.size() + 2) * sizeof(PCVertex); // Si la taille du buffer est trop petite pour ajouter de nouveaux éléments // => on redimensionne if (iNewBufferBytesSize > iActualBufferBytesSize) { ResizeVertexBuffer(iActualBufferBytesSize + 2); } PCVertex* data = nullptr; PCVertex vert1; PCVertex vert2; vert1.position = startPoint; vert1.color = color; vert2.position = endPoint; vert2.color = color; m_vertices.push_back(vert1); m_vertices.push_back(vert2); m_pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&data); memcpy(data, m_vertices.data(), sizeof(PCVertex) * m_vertices.size()); m_pVertexBuffer->Unmap(); m_iVerticesCount = m_vertices.size(); } void Vertex3DLine::ResizeVertexBuffer(unsigned int iNewBytesSize) { SAFE_RELEASE(m_pVertexBuffer); HRESULT hr; D3D10_BUFFER_DESC bd; bd.Usage = D3D10_USAGE_DYNAMIC; bd.ByteWidth = sizeof(PCVertex) * iNewBytesSize; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; hr = D3D10_RENDERER->GetDevice()->CreateBuffer(&bd, nullptr, &m_pVertexBuffer); if (FAILED(hr)) { ShowMessageBoxDXError(hr); } } |
Voici le fichier ShaderTechnique_Vertex3DLine.h :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//------------------------------------------------------ // Shader d'affichage de lignes 3D //------------------------------------------------------ class Vertex3DShaderTechnique : public ShaderTechnique { public: Vertex3DShaderTechnique(); virtual ~Vertex3DShaderTechnique(); virtual bool Initialize(); virtual void SetupShaderVariables(); virtual void Update(float fTimeSinceLastFrame); }; |
Voici le fichier ShaderTechnique_Vertex3DLine.cpp :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include "ShaderTechnique_Vertex3DLine.h" Vertex3DShaderTechnique::Vertex3DShaderTechnique() : ShaderTechnique("3DLine.fx", "Render", VertexLayoutType::PC_VERTEX) { } Vertex3DShaderTechnique::~Vertex3DShaderTechnique() { } bool Vertex3DShaderTechnique::Initialize() { ShaderTechnique::Initialize(); SetupShaderVariables(); return true; } void Vertex3DShaderTechnique::SetupShaderVariables() { RegisterMatrixVariable("World", ShaderVariableType::WORLD); RegisterMatrixVariable("View", ShaderVariableType::VIEW); RegisterMatrixVariable("Projection", ShaderVariableType::PROJECTION); } void Vertex3DShaderTechnique::Update(float fTimeSinceLastFrame) { SetAutoMatrix(ShaderVariableType::WORLD); SetAutoMatrix(ShaderVariableType::VIEW); SetAutoMatrix(ShaderVariableType::PROJECTION); } |
Voici le fichier 3DLine.fx correspondant :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
matrix World; matrix View; matrix Projection; struct VS_INPUT { float4 Pos : POSITION; float4 Color : COLOR0; }; struct PS_INPUT { float4 Pos : SV_POSITION; float4 Color : COLOR0; }; PS_INPUT VS( VS_INPUT input ) { PS_INPUT output = (PS_INPUT)0; output.Pos = mul( input.Pos, World ); output.Pos = mul( output.Pos, View ); output.Pos = mul( output.Pos, Projection ); output.Color = input.Color; return output; } float4 PS( PS_INPUT input) : SV_Target { return input.Color; } technique10 Render { pass P0 { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); } } |
Résumé :
Nous avons présenté un système permettant d’afficher des lignes dans la surface de rendu tout en pouvant spécifier leur couleur.


