jkxr/Projects/Android/jni/OpenJK/code/rd-gles/tr_quicksprite.cpp
2022-09-18 19:43:59 +01:00

255 lines
5.6 KiB
C++

// tr_QuickSprite.cpp: implementation of the CQuickSpriteSystem class.
//
//////////////////////////////////////////////////////////////////////
#include "tr_local.h"
#include "tr_quicksprite.h"
void R_BindAnimatedImage( textureBundle_t *bundle );
//////////////////////////////////////////////////////////////////////
// Singleton System
//////////////////////////////////////////////////////////////////////
CQuickSpriteSystem SQuickSprite;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CQuickSpriteSystem::CQuickSpriteSystem()
{
int i;
for (i=0; i<SHADER_MAX_VERTEXES; i+=4)
{
// Bottom right
mTextureCoords[i+0][0] = 1.0;
mTextureCoords[i+0][1] = 1.0;
// Top right
mTextureCoords[i+1][0] = 1.0;
mTextureCoords[i+1][1] = 0.0;
// Top left
mTextureCoords[i+2][0] = 0.0;
mTextureCoords[i+2][1] = 0.0;
// Bottom left
mTextureCoords[i+3][0] = 0.0;
mTextureCoords[i+3][1] = 1.0;
}
}
CQuickSpriteSystem::~CQuickSpriteSystem()
{
}
void CQuickSpriteSystem::Flush(void)
{
if (mNextVert==0)
{
return;
}
/*
if (mUseFog && r_drawfog->integer == 2 &&
mFogIndex == tr.world->globalFog)
{ //enable hardware fog when we draw this thing if applicable -rww
fog_t *fog = tr.world->fogs + mFogIndex;
qglFogf(GL_FOG_MODE, GL_EXP2);
qglFogf(GL_FOG_DENSITY, logtestExp2 / fog->parms.depthForOpaque);
qglFogfv(GL_FOG_COLOR, fog->parms.color);
qglEnable(GL_FOG);
}
*/
//this should not be needed, since I just wait to disable fog for the surface til after surface sprites are done
//
// render the main pass
//
R_BindAnimatedImage( mTexBundle );
GL_State(mGLStateBits);
//
// set arrays and lock
//
#ifdef HAVE_GLES
unsigned short indexes[(mNextVert/2)*3];
int idx;
// split TRIANGLE_FAN in 2 TRIANGLES
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
qglEnableClientState( GL_COLOR_ARRAY);
/*for (int i=0; i<mNextVert; i+=4) {
qglTexCoordPointer(2, GL_FLOAT, 0, mTextureCoords+i);
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors+i );
qglVertexPointer (3, GL_FLOAT, 16, mVerts+i);
qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}*/
qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors );
qglVertexPointer (3, GL_FLOAT, 16, mVerts);
idx = 0;
for (int i=0; i<mNextVert; i+=4) {
// Triangle 1
indexes[idx+0]=i;
indexes[idx+1]=i+1;
indexes[idx+2]=i+2;
idx+=3;
// Triangle 2
indexes[idx+0]=i;
indexes[idx+1]=i+2;
indexes[idx+2]=i+3;
idx+=3;
}
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
#else
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
qglEnableClientState( GL_COLOR_ARRAY);
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors );
qglVertexPointer (3, GL_FLOAT, 16, mVerts);
if ( qglLockArraysEXT )
{
qglLockArraysEXT(0, mNextVert);
GLimp_LogComment( "glLockArraysEXT\n" );
}
qglDrawArrays(GL_QUADS, 0, mNextVert);
#endif
backEnd.pc.c_vertexes += mNextVert;
backEnd.pc.c_indexes += mNextVert;
backEnd.pc.c_totalIndexes += mNextVert;
//only for software fog pass (global soft/volumetric) -rww
if (mUseFog && (r_drawfog->integer != 2 || mFogIndex != tr.world->globalFog))
{
fog_t *fog = tr.world->fogs + mFogIndex;
//
// render the fog pass
//
GL_Bind( tr.fogImage );
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
//
// set arrays and lock
//
#ifdef HAVE_GLES
qglDisableClientState( GL_COLOR_ARRAY );
qglColor4ubv((GLubyte *)&fog->colorInt);
/*for (int i=0; i<mNextVert; i+=4) {
qglTexCoordPointer(2, GL_FLOAT, 0, mFogTextureCoords+i);
qglVertexPointer (3, GL_FLOAT, 16, mVerts+i);
qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}*/
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
#else
qglTexCoordPointer( 2, GL_FLOAT, 0, mFogTextureCoords);
// qglEnableClientState( GL_TEXTURE_COORD_ARRAY); // Done above
qglDisableClientState( GL_COLOR_ARRAY );
qglColor4ubv((GLubyte *)&fog->colorInt);
// qglVertexPointer (3, GL_FLOAT, 16, mVerts); // Done above
qglDrawArrays(GL_QUADS, 0, mNextVert);
#endif
// Second pass from fog
backEnd.pc.c_totalIndexes += mNextVert;
}
//
// unlock arrays
//
if (qglUnlockArraysEXT)
{
qglUnlockArraysEXT();
GLimp_LogComment( "glUnlockArraysEXT\n" );
}
mNextVert=0;
}
void CQuickSpriteSystem::StartGroup(textureBundle_t *bundle, uint32_t glbits, int fogIndex )
{
mNextVert = 0;
mTexBundle = bundle;
mGLStateBits = glbits;
if (fogIndex != -1)
{
mUseFog = qtrue;
mFogIndex = fogIndex;
}
else
{
mUseFog = qfalse;
}
qglDisable(GL_CULL_FACE);
}
void CQuickSpriteSystem::EndGroup(void)
{
Flush();
qglColor4ub(255,255,255,255);
qglEnable(GL_CULL_FACE);
}
void CQuickSpriteSystem::Add(float *pointdata, color4ub_t color, vec2_t fog)
{
float *curcoord;
float *curfogtexcoord;
uint32_t *curcolor;
if (mNextVert>SHADER_MAX_VERTEXES-4)
{
Flush();
}
curcoord = mVerts[mNextVert];
// This is 16*sizeof(float) because, pointdata comes from a float[16]
memcpy(curcoord, pointdata, 16*sizeof(float));
// Set up color
curcolor = &mColors[mNextVert];
*curcolor++ = *(uint32_t *)color;
*curcolor++ = *(uint32_t *)color;
*curcolor++ = *(uint32_t *)color;
*curcolor++ = *(uint32_t *)color;
if (fog)
{
curfogtexcoord = &mFogTextureCoords[mNextVert][0];
*curfogtexcoord++ = fog[0];
*curfogtexcoord++ = fog[1];
*curfogtexcoord++ = fog[0];
*curfogtexcoord++ = fog[1];
*curfogtexcoord++ = fog[0];
*curfogtexcoord++ = fog[1];
*curfogtexcoord++ = fog[0];
*curfogtexcoord++ = fog[1];
mUseFog=qtrue;
}
else
{
mUseFog=qfalse;
}
mNextVert+=4;
}