Moved the rendering methods into a new file.
--HG-- branch : gsoc2013-dfighterhg/feature/gsoc2013-dfighter
parent
b0613e334c
commit
afb56ea660
@ -0,0 +1,419 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "stdopengl.h"
|
||||
|
||||
#include "driver_opengl.h"
|
||||
#include "nel/3d/index_buffer.h"
|
||||
#include "driver_opengl_vertex_buffer_hard.h"
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
#ifdef NL_STATIC
|
||||
namespace NLDRIVERGL3 {
|
||||
#endif
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderLines)
|
||||
|
||||
// setup material
|
||||
if ( !setupMaterial(mat) || _LastIB._Values == NULL )
|
||||
return false;
|
||||
|
||||
if( !setupProgram( mat ) )
|
||||
return false;
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
// render primitives.
|
||||
//==============================
|
||||
// start multipass.
|
||||
uint nPass;
|
||||
nPass= beginMultiPass();
|
||||
// draw all passes.
|
||||
for(uint pass=0;pass<nPass; pass++)
|
||||
{
|
||||
// setup the pass.
|
||||
if( !setupPass(pass) )
|
||||
return false;
|
||||
|
||||
// draw the primitives.
|
||||
if(nlines)
|
||||
{
|
||||
if (_LastIB._Format == CIndexBuffer::Indices16)
|
||||
{
|
||||
glDrawElements(GL_LINES,2*nlines,GL_UNSIGNED_SHORT,((uint16 *) _LastIB._Values)+firstIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlassert(_LastIB._Format == CIndexBuffer::Indices32);
|
||||
glDrawElements(GL_LINES,2*nlines,GL_UNSIGNED_INT,((uint32 *) _LastIB._Values)+firstIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end multipass.
|
||||
endMultiPass();
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NLines+= nlines;
|
||||
_PrimitiveProfileOut.NLines+= nlines;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderTriangles);
|
||||
|
||||
// setup material
|
||||
if ( !setupMaterial(mat) || _LastIB._Values == NULL )
|
||||
return false;
|
||||
|
||||
if( !setupProgram( mat ) )
|
||||
return false;
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
|
||||
// render primitives.
|
||||
//==============================
|
||||
// start multipass.
|
||||
uint nPass;
|
||||
|
||||
nPass= beginMultiPass();
|
||||
|
||||
// draw all passes.
|
||||
for(uint pass=0;pass<nPass; pass++)
|
||||
{
|
||||
// setup the pass.
|
||||
if( !setupPass(pass) )
|
||||
return false;
|
||||
|
||||
// draw the primitives.
|
||||
if(ntris)
|
||||
{
|
||||
if (_LastIB._Format == CIndexBuffer::Indices16)
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_SHORT, ((uint16 *) _LastIB._Values)+firstIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlassert(_LastIB._Format == CIndexBuffer::Indices32);
|
||||
glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, ((uint32 *) _LastIB._Values)+firstIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end multipass.
|
||||
endMultiPass();
|
||||
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NTriangles+= ntris;
|
||||
_PrimitiveProfileOut.NTriangles+= ntris * nPass;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderSimpleTriangles(uint32 firstTri, uint32 ntris)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderSimpleTriangles);
|
||||
|
||||
nlassert(ntris>0);
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
// Don't setup any material here.
|
||||
|
||||
// render primitives.
|
||||
//==============================
|
||||
// NO MULTIPASS HERE!!
|
||||
// draw the primitives. (nb: ntris>0).
|
||||
|
||||
if (_LastIB._Format == CIndexBuffer::Indices16)
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_SHORT, ((uint16 *) _LastIB._Values)+firstTri);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlassert(_LastIB._Format == CIndexBuffer::Indices32);
|
||||
glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, ((uint32 *) _LastIB._Values)+firstTri);
|
||||
}
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NTriangles+= ntris;
|
||||
_PrimitiveProfileOut.NTriangles+= ntris;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderRawPoints(CMaterial& mat, uint32 startIndex, uint32 numPoints)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderRawPoints)
|
||||
|
||||
// setup material
|
||||
if ( !setupMaterial(mat) )
|
||||
return false;
|
||||
|
||||
if( !setupProgram( mat ) )
|
||||
return false;
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
// render primitives.
|
||||
//==============================
|
||||
// start multipass.
|
||||
uint nPass;
|
||||
nPass= beginMultiPass();
|
||||
// draw all passes.
|
||||
for(uint pass=0;pass<nPass; pass++)
|
||||
{
|
||||
// setup the pass.
|
||||
if( !setupPass(pass) )
|
||||
return false;
|
||||
|
||||
// draw the primitives.
|
||||
if(numPoints)
|
||||
glDrawArrays(GL_POINTS, startIndex, numPoints);
|
||||
}
|
||||
// end multipass.
|
||||
endMultiPass();
|
||||
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NPoints+= numPoints;
|
||||
_PrimitiveProfileOut.NPoints+= numPoints * nPass;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderRawLines(CMaterial& mat, uint32 startIndex, uint32 numLines)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderRawLines)
|
||||
|
||||
// setup material
|
||||
if ( !setupMaterial(mat) )
|
||||
return false;
|
||||
|
||||
if( !setupProgram( mat ) )
|
||||
return false;
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
// render primitives.
|
||||
//==============================
|
||||
// start multipass.
|
||||
uint nPass;
|
||||
nPass= beginMultiPass();
|
||||
// draw all passes.
|
||||
for(uint pass=0;pass<nPass; pass++)
|
||||
{
|
||||
// setup the pass.
|
||||
if( !setupPass(pass) )
|
||||
return false;
|
||||
|
||||
// draw the primitives.
|
||||
if(numLines)
|
||||
glDrawArrays(GL_LINES, startIndex << 1, numLines << 1);
|
||||
}
|
||||
// end multipass.
|
||||
endMultiPass();
|
||||
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NLines += numLines ;
|
||||
_PrimitiveProfileOut.NLines += numLines * nPass;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderRawTriangles(CMaterial& mat, uint32 startIndex, uint32 numTris)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderRawTriangles)
|
||||
|
||||
// setup material
|
||||
if ( !setupMaterial(mat) )
|
||||
return false;
|
||||
|
||||
if( !setupProgram( mat ) )
|
||||
return false;
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
// render primitives.
|
||||
//==============================
|
||||
// start multipass.
|
||||
uint nPass;
|
||||
nPass= beginMultiPass();
|
||||
// draw all passes.
|
||||
for(uint pass=0;pass<nPass; pass++)
|
||||
{
|
||||
// setup the pass.
|
||||
if( !setupPass(pass) )
|
||||
return false;
|
||||
|
||||
// draw the primitives.
|
||||
if(numTris)
|
||||
{
|
||||
glDrawArrays(GL_TRIANGLES, startIndex*3, numTris*3);
|
||||
}
|
||||
}
|
||||
// end multipass.
|
||||
endMultiPass();
|
||||
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NTriangles += numTris ;
|
||||
_PrimitiveProfileOut.NTriangles += numTris * nPass;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL3::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQuads)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL3_renderRawQuads)
|
||||
if (!numQuads) return true;
|
||||
|
||||
// setup material
|
||||
if ( !setupMaterial(mat) )
|
||||
return false;
|
||||
|
||||
if( !setupProgram( mat ) )
|
||||
return false;
|
||||
|
||||
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
|
||||
|
||||
const uint32 QUAD_BATCH_SIZE = 2048;
|
||||
static GLshort defaultIndices[QUAD_BATCH_SIZE * 6];
|
||||
static bool init = false;
|
||||
if (!init)
|
||||
{
|
||||
// setup the base index buffer
|
||||
for(uint k = 0; k < QUAD_BATCH_SIZE; ++k)
|
||||
{
|
||||
// first tri
|
||||
defaultIndices[k * 6] = (GLshort) (k * 4);
|
||||
defaultIndices[k * 6 + 1] = (GLshort) (k * 4 + 1);
|
||||
defaultIndices[k * 6 + 2] = (GLshort) (k * 4 + 2);
|
||||
// second tri
|
||||
defaultIndices[k * 6 + 3] = (GLshort) (k * 4);
|
||||
defaultIndices[k * 6 + 4] = (GLshort) (k * 4 + 2);
|
||||
defaultIndices[k * 6 + 5] = (GLshort) (k * 4 + 3);
|
||||
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
// render primitives.
|
||||
//==============================
|
||||
// start multipass.
|
||||
uint nPass;
|
||||
nPass= beginMultiPass();
|
||||
// draw all passes.
|
||||
for(uint pass=0;pass<nPass; pass++)
|
||||
{
|
||||
// setup the pass.
|
||||
if( !setupPass(pass) )
|
||||
return false;
|
||||
|
||||
uint32 currIndex = startIndex;
|
||||
uint32 numLeftQuads = numQuads;
|
||||
|
||||
// draw first batch of quads using the static setupped array
|
||||
if (startIndex < QUAD_BATCH_SIZE)
|
||||
{
|
||||
// draw first quads (as pair of tri to have guaranteed orientation)
|
||||
uint numQuadsToDraw = std::min(QUAD_BATCH_SIZE - startIndex, numQuads);
|
||||
glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_SHORT, defaultIndices + 6 * startIndex);
|
||||
numLeftQuads -= numQuadsToDraw;
|
||||
currIndex += 4 * numQuadsToDraw;
|
||||
}
|
||||
|
||||
// draw remaining quads
|
||||
while (numLeftQuads)
|
||||
{
|
||||
// TODO : resetting vertex pointer would avoid the need to rebuild indices each times
|
||||
uint32 numQuadsToDraw = std::min(numLeftQuads, QUAD_BATCH_SIZE);
|
||||
// draw all quads
|
||||
if (4 * numQuadsToDraw + currIndex <= (1 << 16))
|
||||
{
|
||||
// indices fits on 16 bits
|
||||
GLshort indices[QUAD_BATCH_SIZE * 6];
|
||||
GLshort *curr = indices;
|
||||
GLshort *end = indices + 6 * numQuadsToDraw;
|
||||
uint16 vertexIndex = (uint16) currIndex;
|
||||
do
|
||||
{
|
||||
*curr++ = vertexIndex;
|
||||
*curr++ = vertexIndex + 1;
|
||||
*curr++ = vertexIndex + 2;
|
||||
*curr++ = vertexIndex;
|
||||
*curr++ = vertexIndex + 2;
|
||||
*curr++ = vertexIndex + 3;
|
||||
vertexIndex += 4;
|
||||
}
|
||||
while(curr != end);
|
||||
glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_SHORT, indices);
|
||||
}
|
||||
else
|
||||
{
|
||||
// indices fits on 32 bits
|
||||
GLint indices[QUAD_BATCH_SIZE];
|
||||
GLint *curr = indices;
|
||||
GLint *end = indices + 6 * numQuadsToDraw;
|
||||
uint32 vertexIndex = currIndex;
|
||||
do
|
||||
{
|
||||
*curr++ = vertexIndex;
|
||||
*curr++ = vertexIndex + 1;
|
||||
*curr++ = vertexIndex + 2;
|
||||
*curr++ = vertexIndex;
|
||||
*curr++ = vertexIndex + 2;
|
||||
*curr++ = vertexIndex + 3;
|
||||
vertexIndex += 4;
|
||||
}
|
||||
while(curr != end);
|
||||
glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_INT, indices);
|
||||
}
|
||||
numLeftQuads -= numQuadsToDraw;
|
||||
currIndex += 4 * numQuadsToDraw;
|
||||
}
|
||||
}
|
||||
// end multipass.
|
||||
endMultiPass();
|
||||
|
||||
|
||||
// Profiling.
|
||||
_PrimitiveProfileIn.NQuads += numQuads ;
|
||||
_PrimitiveProfileOut.NQuads += numQuads * nPass;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef NL_STATIC
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue