Files
GTASource/rage/scaleform/Src/GRenderer/GRendererOGLImplPS3.cpp

597 lines
21 KiB
C++
Raw Normal View History

2025-02-23 17:40:52 +08:00
/**********************************************************************
Filename : GRendererOGLImplPS3.cpp
Content : OpenGL renderer implementation - NV_Cg
Created :
Authors :
Copyright : (c) 2001-2005 Scaleform Corp. All Rights Reserved.
Notes :
Licensees may use this file in accordance with the valid Scaleform
Commercial License Agreement provided with the software.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
**********************************************************************/
struct CgShader
{
CGprogram prog;
CGparameter cxmul, cxadd;
CGparameter tex[5];
};
struct CgVProgram
{
CGprogram prog;
CGparameter mvp;
CGparameter texgenx[2], texgeny[2];
CGparameter factor;
};
class GTextureOGLImplPS3 : public GTextureOGLImpl
{
GLuint PboId;
UPInt TexSize;
UInt TexPitch;
public:
GTextureOGLImplPS3(GRendererOGLImpl *prenderer) : GTextureOGLImpl(prenderer) { PboId = 0; }
void ReleaseTextureId ()
{
GTextureOGLImpl::ReleaseTextureId();
glDeleteBuffers(1, &PboId);
}
bool InitDynamicTexture(int width, int height, GImage::ImageFormat format, int mipmaps, UInt usage)
{
ReleaseTextureId();
GLint internalFormat=0;
GLint datatype = GL_UNSIGNED_BYTE;
UInt bpp = 0;
if (format == GImage::Image_ARGB_8888 || format == GImage::Image_RGB_888)
{
internalFormat = GL_RGBA8;
datatype = GL_UNSIGNED_INT_8_8_8_8;
bpp = 4;
}
else if (format == GImage::Image_A_8)
{
#ifdef GFC_GL_NO_ALPHA_TEXTURES
internalFormat = GL_RGBA8;
datatype = GL_UNSIGNED_INT_8_8_8_8;
bpp = 4;
#else
internalFormat = GL_ALPHA;
bpp = 1;
#endif
}
else
GASSERT(0);
InitTextureId(GL_LINEAR);
TextureFmt = internalFormat;
TextureData = datatype;
TexWidth = width;
TexHeight = height;
TexPitch = width * bpp;
TexSize = TexPitch * height;
Mipmaps = 1+mipmaps;
UInt wtmp = width, htmp = height;
for (int i = 0; i < mipmaps; i++)
{
wtmp = wtmp >> 1;
htmp = htmp >> 1;
if (wtmp < 1) wtmp = 1;
if (htmp < 1) htmp = 1;
TexSize += TexPitch * htmp * bpp;
}
glGenBuffers(1, &PboId);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
glBufferData(GL_TEXTURE_REFERENCE_BUFFER_SCE, TexSize, 0, GL_STATIC_DRAW);
glTextureReferenceSCE(GL_TEXTURE_2D, mipmaps+1, width, height, 1, internalFormat, TexPitch, 0);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
CallHandlers(ChangeHandler::Event_DataChange);
return 1;
}
void Update(int level, int n, const UpdateRect *rects, const GImageBase *pim)
{
UInt bpp = 0;
if (pim->Format == GImage::Image_ARGB_8888)
bpp = 4;
else if (pim->Format == GImage::Image_RGB_888)
bpp = 3;
else if (pim->Format == GImage::Image_A_8)
bpp = 1;
else
GASSERT(0);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
// cannot use WRITE_ONLY since the old buffer contents are not preserved
UByte *pTexData = (UByte*)glMapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, GL_READ_WRITE);
int h = TexHeight;
for (int i = 0; i < level; i++)
{
pTexData += TexPitch * h;
h >>= 1;
if (h < 1)
h = 1;
}
if (bpp == 3)
{
for (int i = 0; i < n; i++)
{
GRect<int> rect = rects[i].src;
UByte *pdest = pTexData + rects[i].dest.y * TexPitch + rects[i].dest.x * 4;
for (int j = 0; j < rect.Height(); j++)
for (int k = 0; k < rect.Width(); k++)
{
pdest[j * TexPitch + k * 4 +0] = pim->pData[(j + rect.Top) * pim->Pitch + (k + rect.Left) * 3 +0];
pdest[j * TexPitch + k * 4 +1] = pim->pData[(j + rect.Top) * pim->Pitch + (k + rect.Left) * 3 +1];
pdest[j * TexPitch + k * 4 +2] = pim->pData[(j + rect.Top) * pim->Pitch + (k + rect.Left) * 3 +2];
pdest[j * TexPitch + k * 4 +3] = 255;
}
}
}
#ifdef GFC_GL_NO_ALPHA_TEXTURES
else if (bpp == 1)
{
for (int i = 0; i < n; i++)
{
GRect<int> rect = rects[i].src;
UByte *pdest = pTexData + rects[i].dest.y * TexPitch + rects[i].dest.x * 4;
for (int j = 0; j < rect.Height(); j++)
for (int k = 0; k < rect.Width(); k++)
{
pdest[j * TexPitch + k * 4 +0] =
pdest[j * TexPitch + k * 4 +1] =
pdest[j * TexPitch + k * 4 +2] = 255;
pdest[j * TexPitch + k * 4 +3] = pim->pData[(j + rect.Top) * pim->Pitch + (k + rect.Left)];
}
}
}
#endif
else
for (int i = 0; i < n; i++)
{
for (int j = 0; j < rects[i].src.Height(); j++)
memcpy(pTexData + TexPitch * (rects[i].dest.y + j) + bpp * rects[i].dest.x,
pim->pData + pim->Pitch * (j + rects[i].src.Top) + pim->GetBytesPerPixel() * rects[i].src.Left,
rects[i].src.Width() * bpp);
}
if (!glUnmapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE))
GASSERT(0);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
}
int Map(int level, int n, MapRect* maps, int flags)
{
GUNUSED(flags);
GASSERT(level < Mipmaps && n > 0 && maps);
UInt bpp=0;
switch (TextureFmt)
{
case GL_RGBA8:
bpp = 4;
break;
case GL_ALPHA:
case GL_LUMINANCE:
bpp = 1;
break;
}
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
UByte *pTexData = (UByte*)glMapBuffer
(GL_TEXTURE_REFERENCE_BUFFER_SCE, flags & Map_KeepOld ? GL_READ_WRITE : GL_WRITE_ONLY);
UInt mipw = TexWidth, miph = TexHeight;
for (int i = 0; i < level; i++)
{
pTexData += TexPitch * miph;
mipw >>= 1;
miph >>= 1;
if (mipw < 1)
mipw = 1;
if (miph < 1)
miph = 1;
}
maps[0].width = mipw;
maps[0].height = miph;
maps[0].pitch = mipw * bpp;
maps[0].pData = pTexData;
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
return 1;
}
bool Unmap(int level, int n, MapRect* maps, int flags)
{
GUNUSED2(flags,n);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
int ret = glUnmapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
return ret;
}
void Bind(int stageIndex, GRenderer::BitmapWrapMode WrapMode, GRenderer::BitmapSampleMode SampleMode, bool useMipmaps);
};
class GTextureOGLImplPS3YUV : public GTextureOGLImplYUV
{
public:
GLuint PboId;
UInt TexSizeYA, TexSizeUV, TexPitch;
GTextureOGLImplPS3YUV(GRendererOGLImpl *prenderer) : GTextureOGLImplYUV(prenderer)
{
PboId = 0;
}
virtual bool InitDynamicTexture(int width, int height, GImage::ImageFormat format, int mipmaps, UInt usage)
{
if (!pRenderer)
return 0;
GASSERT(mipmaps == 0);
ReleaseTextureId();
TexWidth = TexPitch = width;
TexHeight = height;
DeleteTexture = 1;
UInt ntex = (format == GImage::Image_ARGB_8888 ? 4 : 3);
Mipmaps = mipmaps+1;
TextureFmt = GL_LUMINANCE;
TextureData = GL_UNSIGNED_BYTE;
TexSizeYA = TexPitch * height;
TexSizeUV = (TexWidth>>1) * (TexHeight>>1);
UPInt TexSize = TexSizeYA + TexSizeUV * 2;
if (format == GImage::Image_ARGB_8888)
TexSize += TexSizeYA;
glGenBuffers(1, &PboId);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
glBufferData(GL_TEXTURE_REFERENCE_BUFFER_SCE, TexSize, 0, GL_STATIC_DRAW);
glGenTextures(1, (GLuint*)&TextureId);
glGenTextures(ntex-1, TextureUVA);
glBindTexture(GL_TEXTURE_2D, TextureId);
glTextureReferenceSCE(GL_TEXTURE_2D, mipmaps+1, width, height, 1, TextureFmt, TexPitch, 0);
glBindTexture(GL_TEXTURE_2D, TextureUVA[0]);
glTextureReferenceSCE(GL_TEXTURE_2D, mipmaps+1, width>>1, height>>1, 1, TextureFmt, TexPitch>>1, TexSizeYA);
glBindTexture(GL_TEXTURE_2D, TextureUVA[1]);
glTextureReferenceSCE(GL_TEXTURE_2D, mipmaps+1, width>>1, height>>1, 1, TextureFmt, TexPitch>>1, TexSizeYA+TexSizeUV);
if (format == GImage::Image_ARGB_8888)
{
glBindTexture(GL_TEXTURE_2D, TextureUVA[2]);
glTextureReferenceSCE(GL_TEXTURE_2D, mipmaps+1, width, height, 1, TextureFmt, TexPitch, TexSizeYA+TexSizeUV*2);
}
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
CallHandlers(ChangeHandler::Event_DataChange);
return 1;
}
virtual int Map(int level, int n, MapRect* maps, int flags)
{
GUNUSED(flags);
GASSERT(n >= (TextureUVA[2] ? 4 : 3) && maps);
GASSERT(level == 0);
n = TextureUVA[2] ? 4 : 3;
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
UByte *pTexData = (UByte*)glMapBuffer
(GL_TEXTURE_REFERENCE_BUFFER_SCE, flags & Map_KeepOld ? GL_READ_WRITE : GL_WRITE_ONLY);
maps[0].width = TexWidth;
maps[0].height = TexHeight;
maps[0].pitch = TexPitch;
maps[0].pData = pTexData;
maps[1].width = TexWidth>>1;
maps[1].height = TexHeight>>1;
maps[1].pitch = TexPitch>>1;
maps[1].pData = pTexData + TexSizeYA;
maps[2].width = TexWidth>>1;
maps[2].height = TexHeight>>1;
maps[2].pitch = TexPitch>>1;
maps[2].pData = pTexData + TexSizeYA + TexSizeUV;
if (n == 4)
{
maps[3].width = TexWidth;
maps[3].height = TexHeight;
maps[3].pitch = TexPitch;
maps[3].pData = pTexData + TexSizeYA + TexSizeUV*2;
}
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
return n;
}
virtual bool Unmap(int level, int n, MapRect* maps, int flags)
{
GUNUSED4(flags,n,maps,level);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, PboId);
int ret = glUnmapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE);
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
return ret;
}
virtual void ReleaseTextureId()
{
GTextureOGLImplYUV::ReleaseTextureId();
glDeleteBuffers(1, &PboId);
}
void Bind(int stageIndex, GRenderer::BitmapWrapMode WrapMode, GRenderer::BitmapSampleMode SampleMode, bool useMipmaps);
};
/* Compiled shaders */
extern int _binary_p_cxform_fpo_cgelf_start;
extern int _binary_p_cxformmul_fpo_cgelf_start;
extern int _binary_p_cxg2t_fpo_cgelf_start;
extern int _binary_p_cxg2tm_fpo_cgelf_start;
extern int _binary_p_cxg_fpo_cgelf_start;
extern int _binary_p_cxgm_fpo_cgelf_start;
extern int _binary_p_cxgmna_fpo_cgelf_start;
extern int _binary_p_cxgna_fpo_cgelf_start;
extern int _binary_p_cxgt_fpo_cgelf_start;
extern int _binary_p_cxgtm_fpo_cgelf_start;
extern int _binary_p_text_fpo_cgelf_start;
extern int _binary_p_texta_fpo_cgelf_start;
extern int _binary_p_textmul_fpo_cgelf_start;
extern int _binary_v_1tex_vpo_cgelf_start;
extern int _binary_v_2tex_vpo_cgelf_start;
#ifndef GFC_NO_YUV_TEXTURES
extern int _binary_p_cxformyuv_fpo_cgelf_start;
extern int _binary_p_cxformyuvmul_fpo_cgelf_start;
extern int _binary_p_cxformyuva_fpo_cgelf_start;
extern int _binary_p_cxformyuvamul_fpo_cgelf_start;
#endif
class GRendererOGLImplPS3 : public GRendererOGLImpl
{
public:
int CurVProgram;
CGprofile CgFProfile, CgVProfile;
CgShader CgFShaders[PS_Count];
CgVProgram CgVShaders[2];
GTextureOGL* CreateTexture()
{
ReleaseQueuedResources();
GLock::Locker guard(&TexturesLock);
return new GTextureOGLImplPS3(this);
}
GTextureOGL* CreateTextureYUV()
{
ReleaseQueuedResources();
GLock::Locker guard(&TexturesLock);
return new GTextureOGLImplPS3YUV(this);
}
virtual void DisableShaders ()
{
cgGLDisableProfile (CgFProfile);
cgGLDisableProfile (CgVProfile);
}
virtual void SetPixelShader (PixelShaderType ps, SInt pass = 0)
{
GUNUSED(pass);
CurrentShader = ps;
cgGLBindProgram (CgFShaders[ps].prog);
cgGLEnableProfile (CgFProfile);
}
virtual bool SetVertexProgram (VertexFormat vf, SInt numtex)
{
if (vf == Vertex_XY16iCF32)
{
CurVProgram = (numtex == 2) ? 1 : 0;
cgGLBindProgram (CgVShaders[CurVProgram].prog);
cgGLEnableProfile (CgVProfile);
return 1;
}
CurVProgram = 0;
return 0;
}
virtual void SetVertexProgState ()
{
cgGLSetStateMatrixParameter (CgVShaders[CurVProgram].mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
}
virtual void SetTexgenState (SInt stageIndex, const FillTexture& fill)
{
const GRenderer::Matrix& m = fill.TextureMatrix;
Float p[4] = { 0, 0, 0, 0 };
GASSERT(stageIndex < 2);
p[0] = m.M_[0][0];
p[1] = m.M_[0][1];
p[3] = m.M_[0][2];
cgGLSetParameter4fv (CgVShaders[CurVProgram].texgenx[stageIndex], p);
p[0] = m.M_[1][0];
p[1] = m.M_[1][1];
p[3] = m.M_[1][2];
cgGLSetParameter4fv (CgVShaders[CurVProgram].texgeny[stageIndex], p);
}
virtual void ApplyPShaderCxform(const Cxform &cxform) const
{
Float scm[4] = { cxform.M_[0][0], cxform.M_[1][0],
cxform.M_[2][0], cxform.M_[3][0] };
Float sca[4] = { cxform.M_[0][1] / 255.0f, cxform.M_[1][1] / 255.0f,
cxform.M_[2][1] / 255.0f, cxform.M_[3][1] / 255.0f };
cgGLSetParameter4fv (CgFShaders[CurrentShader].cxmul, scm);
cgGLSetParameter4fv (CgFShaders[CurrentShader].cxadd, sca);
}
virtual void VertexAttribArray (SInt attr, GLint size, GLenum type, GLboolean norm, GLsizei stride, GLvoid* array)
{
GUNUSED2(attr,norm);
cgGLSetParameterPointer (CgVShaders[CurVProgram].factor, size, type, stride, array);
//cgGLSetParameterPointer (CgVShaders[CurVProgram].factor, 2, GL_SHORT, stride, array);
cgGLEnableClientState (CgVShaders[CurVProgram].factor);
}
virtual void DisableVertexAttribArrays ()
{
cgGLDisableClientState (CgVShaders[CurVProgram].factor);
}
void InitFragShader (CGcontext ctx, PixelShaderType ps, const void *progin)
{
CgFShaders[ps].prog = cgCreateProgram(ctx, CG_BINARY, (const char*) progin, CgFProfile, NULL, NULL);
CgFShaders[ps].cxmul = cgGetNamedParameter (CgFShaders[ps].prog, "cmul");
CgFShaders[ps].cxadd = cgGetNamedParameter (CgFShaders[ps].prog, "cadd");
CgFShaders[ps].tex[0] = cgGetNamedParameter (CgFShaders[ps].prog, "tex");
if (!CgFShaders[ps].tex[0])
{
CgFShaders[ps].tex[0] = cgGetNamedParameter (CgFShaders[ps].prog, "tex_y");
if (CgFShaders[ps].tex[0])
{
CgFShaders[ps].tex[2] = cgGetNamedParameter (CgFShaders[ps].prog, "tex_u");
CgFShaders[ps].tex[3] = cgGetNamedParameter (CgFShaders[ps].prog, "tex_v");
CgFShaders[ps].tex[4] = cgGetNamedParameter (CgFShaders[ps].prog, "tex_a");
}
}
else
CgFShaders[ps].tex[1] = cgGetNamedParameter (CgFShaders[ps].prog, "tex1");
}
virtual bool SetDependentVideoMode()
{
if (!GRendererOGLImpl::SetDependentVideoMode())
return 0;
// Already initialized, return
if (UseShaders)
return 1;
CgFProfile = cgGLGetLatestProfile (CG_GL_FRAGMENT);
cgGLEnableProfile (CgFProfile);
CgVProfile = cgGLGetLatestProfile (CG_GL_VERTEX);
cgGLEnableProfile (CgVProfile);
CurVProgram = 0;
CGcontext ctx = cgCreateContext();
cgGLSetManageTextureParameters (ctx, 1);
CgVShaders[0].prog = cgCreateProgram(ctx, CG_BINARY, (const char *) &_binary_v_1tex_vpo_cgelf_start, CgVProfile, NULL, NULL);
CgVShaders[0].texgenx[0] = cgGetNamedParameter (CgVShaders[0].prog, "texgenx0");
CgVShaders[0].texgeny[0] = cgGetNamedParameter (CgVShaders[0].prog, "texgeny0");
CgVShaders[0].factor = cgGetNamedParameter (CgVShaders[0].prog, "ifactor");
CgVShaders[0].mvp = cgGetNamedParameter (CgVShaders[0].prog, "mvp");
CgVShaders[1].prog = cgCreateProgram(ctx, CG_BINARY, (const char *) &_binary_v_2tex_vpo_cgelf_start, CgVProfile, NULL, NULL);
CgVShaders[1].texgenx[0] = cgGetNamedParameter (CgVShaders[1].prog, "texgenx0");
CgVShaders[1].texgeny[0] = cgGetNamedParameter (CgVShaders[1].prog, "texgeny0");
CgVShaders[1].texgenx[1] = cgGetNamedParameter (CgVShaders[1].prog, "texgenx1");
CgVShaders[1].texgeny[1] = cgGetNamedParameter (CgVShaders[1].prog, "texgeny1");
CgVShaders[1].factor = cgGetNamedParameter (CgVShaders[1].prog, "ifactor");
CgVShaders[1].mvp = cgGetNamedParameter (CgVShaders[1].prog, "mvp");
InitFragShader (ctx, PS_TextTexture, &_binary_p_texta_fpo_cgelf_start);
InitFragShader (ctx, PS_TextTextureColor, &_binary_p_text_fpo_cgelf_start);
InitFragShader (ctx, PS_TextTextureColorMultiply, &_binary_p_textmul_fpo_cgelf_start);
InitFragShader (ctx, PS_TextTextureYUV, &_binary_p_cxformyuv_fpo_cgelf_start);
InitFragShader (ctx, PS_TextTextureYUVA, &_binary_p_cxformyuva_fpo_cgelf_start);
InitFragShader (ctx, PS_TextTextureYUVMultiply, &_binary_p_cxformyuvmul_fpo_cgelf_start);
InitFragShader (ctx, PS_TextTextureYUVAMultiply, &_binary_p_cxformyuvamul_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformTexture, &_binary_p_cxform_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformTextureMultiply, &_binary_p_cxformmul_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformGouraud, &_binary_p_cxg_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformGouraudMultiply, &_binary_p_cxgm_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformGouraudNoAddAlpha, &_binary_p_cxgna_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformGouraudMultiplyNoAddAlpha, &_binary_p_cxgmna_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformGouraudTexture, &_binary_p_cxgt_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformGouraudMultiplyTexture, &_binary_p_cxgtm_fpo_cgelf_start);
InitFragShader (ctx, PS_Cxform2Texture, &_binary_p_cxg2t_fpo_cgelf_start);
InitFragShader (ctx, PS_CxformMultiply2Texture, &_binary_p_cxg2tm_fpo_cgelf_start);
UseAcBlend = 1;
UseShaders = 1;
MaxTexUnits = 4;
TexNonPower2 = 2;
return 1;
}
};
void GTextureOGLImplPS3::Bind(int stageIndex, GRenderer::BitmapWrapMode WrapMode, GRenderer::BitmapSampleMode SampleMode, bool useMipmaps)
{
GRendererOGLImplPS3 *pRendererPS3 = (GRendererOGLImplPS3*)pRenderer;
glActiveTexture(cgGLGetTextureEnum(pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[stageIndex]));
glBindTexture(GL_TEXTURE_2D, TextureId);
cgGLSetTextureParameter (pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[stageIndex], TextureId);
cgGLEnableTextureParameter (pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[stageIndex]);
pRenderer->ApplySampleMode(WrapMode, SampleMode, useMipmaps);
}
void GTextureOGLImplPS3YUV::Bind(int stageIndex, GRenderer::BitmapWrapMode WrapMode, GRenderer::BitmapSampleMode SampleMode, bool useMipmaps)
{
GASSERT(stageIndex == 0);
GRendererOGLImplPS3 *pRendererPS3 = (GRendererOGLImplPS3*)pRenderer;
for (int i = 0; i < (TextureUVA[2] ? 3 : 2); i++)
{
glActiveTexture(cgGLGetTextureEnum(pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[i+2]));
glBindTexture(GL_TEXTURE_2D, TextureUVA[i]);
cgGLSetTextureParameter (pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[i+2], TextureUVA[i]);
cgGLEnableTextureParameter (pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[i+2]);
pRenderer->ApplySampleMode(WrapMode, SampleMode, useMipmaps);
}
glActiveTexture(cgGLGetTextureEnum(pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[0]));
glBindTexture(GL_TEXTURE_2D, TextureId);
cgGLSetTextureParameter (pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[0], TextureId);
cgGLEnableTextureParameter (pRendererPS3->CgFShaders[pRendererPS3->CurrentShader].tex[0]);
pRenderer->ApplySampleMode(WrapMode, SampleMode, useMipmaps);
}