18 #include "precompiled.h"
42 const int streamFlags = shader->GetStreamFlags();
44 shader->BindTexture(str_baseTex, line.
m_TextureBase->GetHandle());
45 shader->BindTexture(str_maskTex, line.
m_TextureMask->GetHandle());
46 shader->Uniform(str_objectColor, line.
m_Color);
52 shader->VertexPointer(3, GL_FLOAT, stride, &vertexBase->
m_Position[0]);
55 shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, &vertexBase->
m_UVs[0]);
58 shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, &vertexBase->
m_UVs[0]);
62 shader->AssertPointersBound();
84 debug_warn(L
"[TexturedLineRData] No SimContext set for textured overlay line, cannot render (no terrain data)");
92 std::vector<SVertex> vertices;
93 std::vector<u16> indices;
116 bool p1floating =
false;
117 bool p2floating =
false;
143 for (
size_t i = 0; i < n; ++i)
155 CVector3D b = ((p1 - p0).Normalized() + (p2 - p1).Normalized()).Cross(norm);
158 float l = b.
Dot((p2 - p1).Normalized().Cross(norm));
159 if (fabs(l) > 0.000001f)
165 SVertex vertex2(p1 - b + norm*OverlayRenderer::OVERLAY_VOFFSET, 1.f, v);
166 vertices.push_back(vertex1);
167 vertices.push_back(vertex2);
169 u16 index1 = vertices.size() - 2;
170 u16 index2 = vertices.size() - 1;
175 indices.push_back(index1);
176 indices.push_back(index2);
180 u16 index1Prev = vertices.size() - 4;
181 u16 index2Prev = vertices.size() - 3;
182 ENSURE(index1Prev < vertices.size());
183 ENSURE(index2Prev < vertices.size());
188 indices.push_back(index1Prev);
189 indices.push_back(index2Prev);
191 indices.push_back(index1);
194 indices.push_back(index1);
195 indices.push_back(index2Prev);
196 indices.push_back(index2);
205 p1floating = p2floating;
208 if (!closed && i == n-2)
227 indices.push_back(vertices.size()-2);
228 indices.push_back(vertices.size()-1);
229 indices.push_back(0);
231 indices.push_back(0);
232 indices.push_back(vertices.size()-1);
233 indices.push_back(1);
240 std::vector<u16> capIndices;
241 std::vector<SVertex> capVertices;
247 vertices[vertices.size()-2].m_Position,
248 vertices[vertices.size()-1].m_Position,
250 (
Centroid(vertices[vertices.size()-2], vertices[vertices.size()-1]) -
Centroid(vertices[vertices.size()-4], vertices[vertices.size()-3])).Normalized(),
256 for (
unsigned i = 0; i < capIndices.size(); i++)
257 capIndices[i] += vertices.size();
259 vertices.insert(vertices.end(), capVertices.begin(), capVertices.end());
260 indices.insert(indices.end(), capIndices.begin(), capIndices.end());
270 vertices[0].m_Position,
272 (
Centroid(vertices[1], vertices[0]) -
Centroid(vertices[3], vertices[2])).Normalized(),
278 for (
unsigned i = 0; i < capIndices.size(); i++)
279 capIndices[i] += vertices.size();
281 vertices.insert(vertices.end(), capVertices.begin(), capVertices.end());
282 indices.insert(indices.end(), capIndices.begin(), capIndices.end());
285 ENSURE(indices.size() % 3 == 0);
292 for (
size_t k = 0; k < indices.size(); ++k)
293 indices[k] += m_VB->m_Index;
304 std::vector<u16>& indicesOut)
321 int roundCapPoints = 8;
324 CVector3D centerPoint = (corner1 + corner2) * 0.5f;
325 SVertex centerVertex(centerPoint, 0.5f, 0.5f);
326 u16 indexOffset = verticesOut.size();
334 centerVertex.
m_UVs[0] = 0.480f;
348 float stepAngle = -(float)(
M_PI/(roundCapPoints-1));
353 verticesOut.push_back(centerVertex);
354 verticesOut.push_back(
SVertex(corner2, 0.f, 0.f));
359 CVector3D rotationBaseVector = (corner2 - centerPoint).Normalized() * radius;
366 for (
int i = 1; i < roundCapPoints - 1; ++i)
371 CVector3D worldPos3D = centerPoint + quatRotation.
Rotate(rotationBaseVector);
376 float v =
clamp((i/(
float)(roundCapPoints-1)), 0.f, 1.f);
377 verticesOut.push_back(
SVertex(worldPos3D, u, v));
381 verticesOut.push_back(
SVertex(corner1, 0.f, 1.f));
385 for (
int i=1; i < roundCapPoints; ++i)
387 indicesOut.push_back(indexOffset);
388 indicesOut.push_back(indexOffset + i);
389 indicesOut.push_back(indexOffset + i + 1);
400 verticesOut.push_back(centerVertex);
401 verticesOut.push_back(
SVertex(corner2, 0.f, 0.f));
402 verticesOut.push_back(
SVertex(corner2 + (lineDirectionNormal * (line.
m_Thickness)), 0.f, 0.33333f));
403 verticesOut.push_back(
SVertex(corner1 + (lineDirectionNormal * (line.
m_Thickness)), 0.f, 0.66666f));
404 verticesOut.push_back(
SVertex(corner1, 0.f, 1.0f));
406 for (
int i=1; i < 4; ++i)
408 indicesOut.push_back(indexOffset);
409 indicesOut.push_back(indexOffset + i);
410 indicesOut.push_back(indexOffset + i + 1);
size_t m_Index
Start index of this chunk in owner.
CTexturePtr m_TextureBase
void CreateLineCap(const SOverlayTexturedLine &line, const CVector3D &corner1, const CVector3D &corner2, const CVector3D &normal, SOverlayTexturedLine::LineCapType endCapType, std::vector< SVertex > &verticesOut, std::vector< u16 > &indicesOut)
Creates a line cap of the specified type endCapType at the end of the segment going in direction norm...
CVertexBufferManager g_VBMan
float Dot(const CVector3D &vector) const
CVector3D Cross(const CVector3D &vector) const
CVector3D Rotate(const CVector3D &vec) const
VertexArray::Attribute m_Position
float GetExactGroundLevel(float x, float z) const
CVector3D Centroid(const SVertex &v1, const SVertex &v2)
Small utility function; grabs the centroid of the positions of two vertices.
u8 * Bind()
Bind to this buffer; return pointer to address required as parameter to glVertexPointer ( + etc) call...
square end that extends half the line width beyond the line end
const entity_id_t SYSTEM_ENTITY
Entity ID for singleton 'system' components.
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
CVertexBuffer::VBChunk * Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target)
Try to allocate a vertex buffer of the given size and type.
Textured line overlay, with world-space coordinates, rendered in the world onto the terrain...
bool m_Closed
Should this line be treated as a closed loop? If set, any end cap settings are ignored.
Semi-circular line ending.
CColor m_Color
Color to apply to the line texture, where indicated by the mask.
virtual float GetExactWaterLevel(float x, float z)=0
Get the current water level at the given point.
CVertexBuffer::VBChunk * m_VB
void UpdateChunkVertices(VBChunk *chunk, void *data)
Update vertex data for given chunk. Transfers the provided data to the actual OpenGL vertex buffer...
std::vector< float > m_Coords
(x, z) vertex coordinate pairs; y is computed automatically.
CTexturePtr m_TextureMask
A simplified syntax for accessing entity components.
size_t m_Count
Number of vertices used by chunk.
void Update(const SOverlayTexturedLine &line)
void Release(CVertexBuffer::VBChunk *chunk)
Returns the given chunk to its owning buffer.
CVertexBuffer * m_Owner
Owning (parent) vertex buffer.
no line ending; abrupt stop of the line (aka. butt ending)
void Render(const SOverlayTexturedLine &line, const CShaderProgramPtr &shader)
#define debug_warn(expr)
display the error dialog with the given text.
void FromAxisAngle(const CVector3D &axis, float angle)
const CSimContext * m_SimContext
Simulation context applicable for this overlay line; used to obtain terrain information during automa...
LineCapType m_StartCapType
float m_Thickness
Half-width of the line, in world-space units.
CVector3D Normalized() const
static const float OVERLAY_VOFFSET
Small vertical offset of overlays from terrain to prevent visual glitches.
shared_ptr< CShaderProgram > CShaderProgramPtr
T clamp(T value, T min, T max)
CVertexBuffer::VBChunk * m_VBIndices
CVector3D CalcExactNormal(float x, float z) const
CTerrain & GetTerrain() const