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 :
#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 :
#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 :
//------------------------------------------------------
// 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 :
#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 :
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.

