From 478dfdf2621dc7b5ef071b0617c4f54a102ec185 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Wed, 11 May 2022 21:35:25 +0200 Subject: [PATCH] WIP integration of fhDoom debug line rendering --- neo/renderer/ImmediateMode.cpp | 525 +++++++++++++++++++++ neo/renderer/ImmediateMode.h | 130 +++++ neo/renderer/NVRHI/RenderBackend_NVRHI.cpp | 13 - neo/renderer/NVRHI/RenderDebug_NVRHI.cpp | 92 +++- neo/renderer/RenderBackend.h | 2 - 5 files changed, 746 insertions(+), 16 deletions(-) create mode 100644 neo/renderer/ImmediateMode.cpp create mode 100644 neo/renderer/ImmediateMode.h diff --git a/neo/renderer/ImmediateMode.cpp b/neo/renderer/ImmediateMode.cpp new file mode 100644 index 00000000..52774ccc --- /dev/null +++ b/neo/renderer/ImmediateMode.cpp @@ -0,0 +1,525 @@ +/* +=========================================================================== + +Doom 3 GPL Source Code +Copyright (C) 2016 Johannes Ohlemacher (http://github.com/eXistence/fhDOOM) +Copyright (C) 2022 Robert Beckebans (BFG integration) + +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). + +Doom 3 Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 Source Code. If not, see . + +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "RenderCommon.h" +#include "ImmediateMode.h" + + +namespace +{ +const int c_drawVertsCapacity = ( 20000 * 4 ); +//const int c_drawIndexesCapacity = ( 20000 * 6 ); + +idDrawVert drawVerts[c_drawVertsCapacity]; +triIndex_t lineIndices[c_drawVertsCapacity * 2]; +triIndex_t sphereIndices[c_drawVertsCapacity * 2]; + +bool active = false; +} + +/* +void fhSimpleVert::SetColor( const idVec3& v ) +{ + SetColor( idVec4( v, 1.0f ) ); +} + +void fhSimpleVert::SetColor( const idVec4& v ) +{ + color[0] = static_cast( v.x * 255.0f ); + color[1] = static_cast( v.y * 255.0f ); + color[2] = static_cast( v.z * 255.0f ); + color[3] = static_cast( v.w * 255.0f ); + +} +*/ + +int fhImmediateMode::drawCallCount = 0; +int fhImmediateMode::drawCallVertexSize = 0; + +void fhImmediateMode::Init() +{ + for( int i = 0; i < c_drawVertsCapacity * 2; ++i ) + { + lineIndices[i] = i; + } + + ResetStats(); +} + +void fhImmediateMode::ResetStats() +{ + drawCallCount = 0; + drawCallVertexSize = 0; +} +int fhImmediateMode::DrawCallCount() +{ + return drawCallCount; +} + +int fhImmediateMode::DrawCallVertexSize() +{ + return drawCallVertexSize; +} + + +fhImmediateMode::fhImmediateMode( bool geometryOnly ) + : drawVertsUsed( 0 ) + , currentTexture( nullptr ) + , geometryOnly( geometryOnly ) + , currentMode( GFX_INVALID_ENUM ) +{ +} + +fhImmediateMode::~fhImmediateMode() +{ + End(); +} + +void fhImmediateMode::SetTexture( idImage* texture ) +{ + currentTexture = texture; +} + +void fhImmediateMode::Begin( GFXenum mode ) +{ + End(); + assert( !active ); + active = true; + + currentMode = mode; + drawVertsUsed = 0; +} + +void fhImmediateMode::End( nvrhi::ICommandList* commandList ) +{ + active = false; + if( !drawVertsUsed ) + { + return; + } + + vertexBlock = vertexCache.AllocVertex( NULL, c_drawVertsCapacity, sizeof( idDrawVert ), commandList ); + indexBlock = vertexCache.AllocIndex( NULL, c_drawVertsCapacity * 2, sizeof( triIndex_t ), commandList ); + + vertexPointer = ( idDrawVert* )vertexCache.MappedVertexBuffer( vertexBlock ); + indexPointer = ( triIndex_t* )vertexCache.MappedIndexBuffer( indexBlock ); + numVerts = 0; + numIndexes = 0; + + idDrawVert* verts = AllocVerts( drawVertsUsed, lineIndices, drawVertsUsed * 2 ); + WriteDrawVerts16( verts, drawVerts, drawVertsUsed ); + + /* + auto vert = vertexCache.AllocFrameTemp( drawVerts, drawVertsUsed * sizeof( fhSimpleVert ) ); + drawCallVertexSize += drawVertsUsed * sizeof( fhSimpleVert ); + int offset = vertexCache.Bind( vert ); + */ + + /* + if( !geometryOnly ) + { + if( currentTexture ) + { + currentTexture->Bind( 1 ); + + if( currentTexture->type == TT_CUBIC ) + { + GL_UseProgram( skyboxProgram ); + } + else if( currentTexture->pixelFormat == pixelFormat_t::DEPTH_24 || currentTexture->pixelFormat == pixelFormat_t::DEPTH_24_STENCIL_8 ) + { + GL_UseProgram( debugDepthProgram ); + } + else + { + GL_UseProgram( defaultProgram ); + } + } + else + { + GL_UseProgram( vertexColorProgram ); + } + + fhRenderProgram::SetModelViewMatrix( GL_ModelViewMatrix.Top() ); + fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() ); + fhRenderProgram::SetDiffuseColor( idVec4::one ); + fhRenderProgram::SetColorAdd( idVec4::zero ); + fhRenderProgram::SetColorModulate( idVec4::one ); + fhRenderProgram::SetBumpMatrix( idVec4( 1, 0, 0, 0 ), idVec4( 0, 1, 0, 0 ) ); + } + + GL_SetupVertexAttributes( fhVertexLayout::Simple, offset ); + */ + + GFXenum mode = currentMode; + + if( mode == GFX_QUADS || mode == GFX_POLYGON || mode == GFX_QUAD_STRIP ) //quads and polygons are replaced by triangles in GLSL mode + { + //mode = GFX_TRIANGLES; + } + + glDrawElements( mode, + drawVertsUsed, + GL_UNSIGNED_SHORT, + lineIndices ); + + /* + drawCallCount++; + + GL_SetVertexLayout( fhVertexLayout::None ); + + if( !geometryOnly ) + { + GL_UseProgram( nullptr ); + } + + if( !geometryOnly ) + { + globalImages->BindNull( 1 ); + } + */ + + drawVertsUsed = 0; + currentMode = GFX_INVALID_ENUM; +} + +void fhImmediateMode::TexCoord2f( float s, float t ) +{ + currentTexCoord[0] = s; + currentTexCoord[1] = t; +} + +void fhImmediateMode::TexCoord2fv( const float* v ) +{ + TexCoord2f( v[0], v[1] ); +} + +void fhImmediateMode::Color4f( float r, float g, float b, float a ) +{ + currentColor[0] = static_cast( r * 255.0f ); + currentColor[1] = static_cast( g * 255.0f ); + currentColor[2] = static_cast( b * 255.0f ); + currentColor[3] = static_cast( a * 255.0f ); +} + +void fhImmediateMode::Color3f( float r, float g, float b ) +{ + Color4f( r, g, b, 1.0f ); +} + +void fhImmediateMode::Color3fv( const float* c ) +{ + Color4f( c[0], c[1], c[2], 1.0f ); +} + +void fhImmediateMode::Color4fv( const float* c ) +{ + Color4f( c[0], c[1], c[2], c[3] ); +} + +void fhImmediateMode::Color4ubv( const byte* bytes ) +{ + currentColor[0] = bytes[0]; + currentColor[1] = bytes[1]; + currentColor[2] = bytes[2]; + currentColor[3] = bytes[3]; +} + +void fhImmediateMode::Vertex3fv( const float* c ) +{ + Vertex3f( c[0], c[1], c[2] ); +} + +void fhImmediateMode::Vertex3f( float x, float y, float z ) +{ + if( drawVertsUsed + 1 >= c_drawVertsCapacity ) + { + return; + } + + //we don't want to draw deprecated quads/polygons... correct them by re-adding + // previous vertices, so we render triangles instead of quads/polygons + // NOTE: this only works for convex polygons (just as GL_POLYGON) + if( ( currentMode == GFX_POLYGON || currentMode == GFX_QUADS ) && + drawVertsUsed >= 3 && + drawVertsUsed + 3 < c_drawVertsCapacity ) + { + drawVerts[drawVertsUsed] = drawVerts[0]; + drawVerts[drawVertsUsed + 1] = drawVerts[drawVertsUsed - 1]; + drawVertsUsed += 2; + } + + if( currentMode == GFX_QUAD_STRIP && drawVertsUsed >= 3 && drawVertsUsed + 3 < c_drawVertsCapacity ) + { + if( drawVertsUsed % 6 == 0 ) + { + drawVerts[drawVertsUsed] = drawVerts[drawVertsUsed - 3]; + drawVerts[drawVertsUsed + 1] = drawVerts[drawVertsUsed - 1]; + } + else if( drawVertsUsed % 3 == 0 ) + { + drawVerts[drawVertsUsed] = drawVerts[drawVertsUsed - 1]; + drawVerts[drawVertsUsed + 1] = drawVerts[drawVertsUsed - 2]; + } + drawVertsUsed += 2; + } + + + idDrawVert& vertex = drawVerts[drawVertsUsed++]; + vertex.xyz.Set( x, y, z ); + vertex.SetTexCoord( currentTexCoord[0], currentTexCoord[1] ); + vertex.color[0] = currentColor[0]; + vertex.color[1] = currentColor[1]; + vertex.color[2] = currentColor[2]; + vertex.color[3] = currentColor[3]; +} + +void fhImmediateMode::Vertex2f( float x, float y ) +{ + Vertex3f( x, y, 0.0f ); +} + + +/* +void fhImmediateMode::Sphere( float radius, int rings, int sectors, bool inverse ) +{ + assert( !active ); + assert( radius > 0.0f ); + assert( rings > 1 ); + assert( sectors > 1 ); + + float const R = 1. / ( float )( rings - 1 ); + float const S = 1. / ( float )( sectors - 1 ); + + int vertexNum = 0; + for( int r = 0; r < rings; r++ ) + { + for( int s = 0; s < sectors; s++ ) + { + float const y = sin( -( idMath::PI / 2.0f ) + idMath::PI * r * R ); + float const x = cos( 2 * idMath::PI * s * S ) * sin( idMath::PI * r * R ); + float const z = sin( 2 * idMath::PI * s * S ) * sin( idMath::PI * r * R ); + + drawVerts[vertexNum].xyz.x = x * radius; + drawVerts[vertexNum].xyz.y = y * radius; + drawVerts[vertexNum].xyz.z = z * radius; + drawVerts[vertexNum].st.x = s * S; + drawVerts[vertexNum].st.y = r * R; + drawVerts[vertexNum].color[0] = currentColor[0]; + drawVerts[vertexNum].color[1] = currentColor[1]; + drawVerts[vertexNum].color[2] = currentColor[2]; + drawVerts[vertexNum].color[3] = currentColor[3]; + + vertexNum += 1; + } + } + + int indexNum = 0; + for( int r = 0; r < rings - 1; r++ ) + { + for( int s = 0; s < sectors - 1; s++ ) + { + if( r == 0 ) + { + //faces of first ring are single triangles + sphereIndices[indexNum + 2] = r * sectors + s; + sphereIndices[indexNum + 1] = ( r + 1 ) * sectors + s; + sphereIndices[indexNum + 0] = ( r + 1 ) * sectors + ( s + 1 ); + + indexNum += 3; + } + else if( r == rings - 2 ) + { + //faces of last ring are single triangles + sphereIndices[indexNum + 0] = r * sectors + s; + sphereIndices[indexNum + 1] = r * sectors + ( s + 1 ); + sphereIndices[indexNum + 2] = ( r + 1 ) * sectors + ( s + 1 ); + + indexNum += 3; + } + else + { + //faces of remaining rings are quads (two triangles) + sphereIndices[indexNum + 0] = r * sectors + s; + sphereIndices[indexNum + 1] = r * sectors + ( s + 1 ); + sphereIndices[indexNum + 2] = ( r + 1 ) * sectors + ( s + 1 ); + + sphereIndices[indexNum + 3] = sphereIndices[indexNum + 2]; + sphereIndices[indexNum + 4] = ( r + 1 ) * sectors + s; + sphereIndices[indexNum + 5] = sphereIndices[indexNum + 0]; + + indexNum += 6; + } + } + } + + if( inverse ) + { + for( int i = 0; i + 2 < indexNum; i += 3 ) + { + unsigned short tmp = sphereIndices[i]; + sphereIndices[i] = sphereIndices[i + 2]; + sphereIndices[i + 2] = tmp; + } + } + + GL_UseProgram( vertexColorProgram ); + + auto vert = vertexCache.AllocFrameTemp( drawVerts, vertexNum * sizeof( fhSimpleVert ) ); + int offset = vertexCache.Bind( vert ); + + fhRenderProgram::SetModelViewMatrix( GL_ModelViewMatrix.Top() ); + fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() ); + fhRenderProgram::SetDiffuseColor( idVec4::one ); + fhRenderProgram::SetBumpMatrix( idVec4( 1, 0, 0, 0 ), idVec4( 0, 1, 0, 0 ) ); + + GL_SetupVertexAttributes( fhVertexLayout::Simple, offset ); + + glDrawElements( GL_TRIANGLES, + indexNum, + GL_UNSIGNED_SHORT, + sphereIndices ); + + GL_SetVertexLayout( fhVertexLayout::None ); + GL_UseProgram( nullptr ); +} +*/ + +void fhImmediateMode::AddTrianglesFromPolygon( fhImmediateMode& im, const idVec3* xyz, int num ) +{ + assert( im.getCurrentMode() == GL_TRIANGLES ); + + if( num < 3 ) + { + return; + } + + for( int i = 0; i < num; ++i ) + { + if( i > 0 && i % 3 == 0 ) + { + im.Vertex3fv( xyz[0].ToFloatPtr() ); + im.Vertex3fv( xyz[i - 1].ToFloatPtr() ); + } + im.Vertex3fv( xyz[i].ToFloatPtr() ); + } +} + + +/* +fhLineBuffer::fhLineBuffer() + : verticesUsed( 0 ) + , verticesAllocated( 4096 ) +{ + vertices = new fhSimpleVert[verticesAllocated]; +} + +fhLineBuffer::~fhLineBuffer() +{ + delete[] vertices; +} + +void fhLineBuffer::Add( idVec3 from, idVec3 to, idVec3 color ) +{ + Add( from, to, idVec4( color.x, color.y, color.z, 1.0f ) ); +} + +void fhLineBuffer::Add( idVec3 from, idVec3 to, idVec4 color ) +{ + if( verticesAllocated - verticesUsed < 2 ) + { + fhSimpleVert* n = new fhSimpleVert[verticesUsed * 2]; + memcpy( n, vertices, sizeof( vertices[0] ) * verticesUsed ); + delete[] vertices; + vertices = n; + verticesAllocated = verticesUsed * 2; + } + + byte colorBytes[4]; + colorBytes[0] = static_cast( color.x * 255.0f ); + colorBytes[1] = static_cast( color.y * 255.0f ); + colorBytes[2] = static_cast( color.z * 255.0f ); + colorBytes[3] = static_cast( color.w * 255.0f ); + + fhSimpleVert& fromVert = vertices[verticesUsed + 0]; + fhSimpleVert& toVert = vertices[verticesUsed + 1]; + + memcpy( fromVert.color, colorBytes, sizeof( colorBytes ) ); + memcpy( toVert.color, colorBytes, sizeof( colorBytes ) ); + fromVert.xyz = from; + toVert.xyz = to; + + verticesUsed += 2; +} + +void fhLineBuffer::Commit() +{ + if( verticesUsed > 0 ) + { + GL_UseProgram( vertexColorProgram ); + + fhRenderProgram::SetModelViewMatrix( GL_ModelViewMatrix.Top() ); + fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() ); + fhRenderProgram::SetDiffuseColor( idVec4::one ); + fhRenderProgram::SetColorAdd( idVec4::zero ); + fhRenderProgram::SetColorModulate( idVec4::one ); + fhRenderProgram::SetBumpMatrix( idVec4( 1, 0, 0, 0 ), idVec4( 0, 1, 0, 0 ) ); + + int verticesCommitted = 0; + while( verticesCommitted < verticesUsed ) + { + static const int maxVerticesPerCommit = ( sizeof( lineIndices ) / sizeof( lineIndices[0] ) ) / 2; + + int verticesToCommit = Min( maxVerticesPerCommit, verticesUsed - verticesCommitted ); + + auto vert = vertexCache.AllocFrameTemp( &vertices[verticesCommitted], verticesToCommit * sizeof( fhSimpleVert ) ); + int offset = vertexCache.Bind( vert ); + + GL_SetupVertexAttributes( fhVertexLayout::Simple, offset ); + + glDrawElements( GL_LINES, + verticesToCommit, + GL_UNSIGNED_SHORT, + lineIndices ); + + verticesCommitted += verticesToCommit; + } + } + + verticesUsed = 0; +} + +void fhLineBuffer::Clear() +{ + verticesUsed = 0; +} +*/ \ No newline at end of file diff --git a/neo/renderer/ImmediateMode.h b/neo/renderer/ImmediateMode.h new file mode 100644 index 00000000..fe51e076 --- /dev/null +++ b/neo/renderer/ImmediateMode.h @@ -0,0 +1,130 @@ +/* +=========================================================================== + +Doom 3 GPL Source Code +Copyright (C) 2016 Johannes Ohlemacher (http://github.com/eXistence/fhDOOM) + +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). + +Doom 3 Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 Source Code. If not, see . + +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#pragma once + +class idDrawVert; + +/* +struct fhSimpleVert +{ + idVec3 xyz; + idVec2 st; + byte color[4]; + + void SetColor( const idVec3& v ); + void SetColor( const idVec4& v ); + + static const int xyzOffset = 0; + static const int texcoordOffset = 12; + static const int colorOffset = 20; +}; + +static_assert( sizeof( fhSimpleVert ) == 24, "unexpected size of simple vertex, due to padding?" ); +*/ + +enum GFXenum +{ + GFX_INVALID_ENUM = 0x0500, + GFX_LINES = 0x0001, + GFX_LINE_LOOP = 0x0002, + GFX_QUADS = 0x0007, + GFX_QUAD_STRIP = 0x0008, + GFX_POLYGON = 0x0009, +}; + + +class fhImmediateMode +{ +public: + explicit fhImmediateMode( bool geometryOnly = false ); + ~fhImmediateMode(); + + void SetTexture( idImage* texture ); + + void Begin( GFXenum mode ); + void TexCoord2f( float s, float t ); + void TexCoord2fv( const float* v ); + void Color3fv( const float* c ); + void Color3f( float r, float g, float b ); + void Color4f( float r, float g, float b, float a ); + void Color4fv( const float* c ); + void Color4ubv( const byte* bytes ); + void Vertex3fv( const float* c ); + void Vertex3f( float x, float y, float z ); + void Vertex2f( float x, float y ); + void End( nvrhi::ICommandList* commandList ); + + void Sphere( float radius, int rings, int sectors, bool inverse = false ); + + GFXenum getCurrentMode() const + { + return currentMode; + } + + static void AddTrianglesFromPolygon( fhImmediateMode& im, const idVec3* xyz, int num ); + + static void Init(); + static void ResetStats(); + static int DrawCallCount(); + static int DrawCallVertexSize(); +private: + bool geometryOnly; + float currentTexCoord[2]; + GFXenum currentMode; + byte currentColor[4]; + idImage* currentTexture; + int drawVertsUsed; + + vertCacheHandle_t vertexBlock; + vertCacheHandle_t indexBlock; + idDrawVert* vertexPointer; + triIndex_t* indexPointer; + int numVerts; + int numIndexes; + + static int drawCallCount; + static int drawCallVertexSize; +}; + +class fhLineBuffer +{ +public: + fhLineBuffer(); + ~fhLineBuffer(); + + void Add( idVec3 from, idVec3 to, idVec4 color ); + void Add( idVec3 from, idVec3 to, idVec3 color ); + void Clear(); + void Commit(); + +private: + int verticesAllocated; + int verticesUsed; + idDrawVert* vertices; +}; diff --git a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp index 73a35c32..d29871f8 100644 --- a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp +++ b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp @@ -780,19 +780,6 @@ void idRenderBackend::GL_BlockingSwapBuffers() renderLog.EndFrame(); } -void idRenderBackend::GL_EndRenderPass() -{ -#if 0 - commandList->close(); - - deviceManager->GetDevice()->executeCommandList( commandList ); - - deviceManager->GetDevice()->runGarbageCollection(); - - commandList->open(); -#endif -} - /* ======================== GL_SetDefaultState diff --git a/neo/renderer/NVRHI/RenderDebug_NVRHI.cpp b/neo/renderer/NVRHI/RenderDebug_NVRHI.cpp index 83ab5886..aa711fd2 100644 --- a/neo/renderer/NVRHI/RenderDebug_NVRHI.cpp +++ b/neo/renderer/NVRHI/RenderDebug_NVRHI.cpp @@ -3,7 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. -Copyright (C) 2014-2021 Robert Beckebans +Copyright (C) 2014-2022 Robert Beckebans Copyright (C) 2014-2016 Kot in Action Creative Artel Copyright (C) 2016-2017 Dustin Land @@ -34,6 +34,7 @@ If you have questions concerning this license or the applicable additional terms #include "../RenderCommon.h" #include "../simplex.h" // line font definition +#include "../ImmediateMode.h" idCVar r_showCenterOfProjection( "r_showCenterOfProjection", "0", CVAR_RENDERER | CVAR_BOOL, "Draw a cross to show the center of projection" ); idCVar r_showLines( "r_showLines", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = draw alternate horizontal lines, 2 = draw alternate vertical lines" ); @@ -1749,6 +1750,95 @@ RB_DrawText */ static void RB_DrawText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align ) { + renderProgManager.BindShader_Color(); + + // RB begin + //GL_Color( color[0], color[1], color[2], 1 /*color[3]*/ ); + renderProgManager.CommitUniforms( tr.backend.GL_GetCurrentState() ); + // RB end + + int i, j, len, num, index, charIndex, line; + float textLen = 1.0f, spacing = 1.0f; + idVec3 org, p1, p2; + + if( text && *text ) + { + im.Begin( GFX_LINES ); + im.Color3fv( color.ToFloatPtr() ); + + if( text[0] == '\n' ) + { + line = 1; + } + else + { + line = 0; + } + + len = strlen( text ); + for( i = 0; i < len; i++ ) + { + + if( i == 0 || text[i] == '\n' ) + { + org = origin - viewAxis[2] * ( line * 36.0f * scale ); + if( align != 0 ) + { + for( j = 1; i + j <= len; j++ ) + { + if( i + j == len || text[i + j] == '\n' ) + { + textLen = RB_DrawTextLength( text + i, scale, j ); + break; + } + } + if( align == 2 ) + { + // right + org += viewAxis[1] * textLen; + } + else + { + // center + org += viewAxis[1] * ( textLen * 0.5f ); + } + } + line++; + } + + charIndex = text[i] - 32; + if( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) + { + continue; + } + num = simplex[charIndex][0] * 2; + spacing = simplex[charIndex][1]; + index = 2; + + while( index - 2 < num ) + { + if( simplex[charIndex][index] < 0 ) + { + index++; + continue; + } + p1 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index + 1] * viewAxis[2]; + index += 2; + if( simplex[charIndex][index] < 0 ) + { + index++; + continue; + } + p2 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index + 1] * viewAxis[2]; + + im.Vertex3fv( p1.ToFloatPtr() ); + im.Vertex3fv( p2.ToFloatPtr() ); + } + org -= viewAxis[1] * ( spacing * scale ); + } + + im.End(); + } } /* diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 88f90ee0..b22bebe4 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -363,8 +363,6 @@ private: void GL_StartFrame(); void GL_EndFrame(); - void GL_EndRenderPass(); - public: uint64 GL_GetCurrentState() const; idVec2 GetCurrentPixelOffset() const;