JD2022-TU1/main/extern/Camcam/LIBS/Render/OGL_3D.cpp

687 lines
No EOL
22 KiB
C++

#include "OGL_Class.h"
#include "SCENE.h"
u32 COL_MulColor(u32 A,u32 B);
void OGL_DI::RenderMesh(Mesh *pMyMesh,u32 Num, u32 Base)
{
u32 Counter,Color;
FaceIndex *Indexes;
FaceIndex *Indexes_UV;
Vector Fake;
Vector *PointsN,*PointsUV,*Points;
GLubyte *PointColors;
Points = pMyMesh->Points;
PointsN = pMyMesh->PointsN;
PointsUV = pMyMesh->PointsUV;
PointColors = (GLubyte*)pMyMesh->VertexColors;
if (CurrentRS.USEVERTEXCOLORS == 0) PointColors = NULL;
if (!Points) Points = &Fake;
if (!PointsN) PointsN = &Fake;
if (!PointsUV) PointsUV = &Fake;
Indexes = pMyMesh->Indexes + Base;
Indexes_UV = pMyMesh->Indexes_UV + Base;
if (Num == -1)
Counter = pMyMesh->NumberOfFaces;
else
Counter = Num;
if (CurrentRS.MappingMode == 1) // Chrome
{
PointsUV = PointsN;
Indexes_UV = Indexes;
}
if ((CurrentRS.MappingMode == 4) && pMyMesh->NumberOfPointsUV2) // uv2
{
PointsUV = pMyMesh->PointsUV2;
Indexes_UV = pMyMesh->Indexes_UV2 + Base;
}
// Somewhere in the initialization part of your program…
/* Soft Picking */
if (PickingEnable) PickMesh(pMyMesh,Num, Base);
if (AllLightNumber && CurrentRS.LIGHTED)
{
glEnable(GL_LIGHTING);
for (int VazyFeTourner = 0 ; VazyFeTourner < AllLightNumber ; VazyFeTourner++)
{
glEnable(GL_LIGHT0 + VazyFeTourner);
float ambientLight[] = { 0.0f, 0.0f, 0.0f, 0.0f };
float diffuseLight[] = { AllLight[VazyFeTourner].LightDesc->LightColor.x, AllLight[VazyFeTourner].LightDesc->LightColor.y, AllLight[VazyFeTourner].LightDesc->LightColor.z,1};
float MulLight[] = { (float)(CurrentColor & 0xff) / 255.0f, (float)((CurrentColor>>8) & 0xff) / 255.0f, (float)((CurrentColor>>16) & 0xff) / 255.0f, (float)((CurrentColor>>24) & 0xff) / 255.0f};
float specularLight[] = { 0.0f, 0.0f, 0.0f,1.0f };
float Atenuaztion[] = { 1.0f, 0.0f, 0.0f}; // default no attenuation
float sppotdirection[3];
float position[4];
diffuseLight[0] = AllLight[VazyFeTourner].LightDesc->LightColor.x;
diffuseLight[1] = AllLight[VazyFeTourner].LightDesc->LightColor.y;
diffuseLight[2] = AllLight[VazyFeTourner].LightDesc->LightColor.z;
// Assign created components to GL_LIGHT0
if (AllLight[VazyFeTourner].LightDesc->LightType == 3) // Ambient
{
diffuseLight[0] *= MulLight[0];
diffuseLight[1] *= MulLight[1];
diffuseLight[2] *= MulLight[2];
diffuseLight[3] *= MulLight[3];
ambientLight[0] = diffuseLight[0] * 4;
ambientLight[1] = diffuseLight[1] * 4;
ambientLight[2] = diffuseLight[2] * 4;
ambientLight[3] = diffuseLight[3] * 4;
diffuseLight[0] = diffuseLight[1] = diffuseLight[2] = diffuseLight[3] = 0.0f;
}
diffuseLight[0] *= MulLight[0];
diffuseLight[1] *= MulLight[1];
diffuseLight[2] *= MulLight[2];
diffuseLight[3] *= MulLight[3];
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_SPECULAR, specularLight);
float ScaleNorm;
ScaleNorm = 1.0f/AllLight[VazyFeTourner].Direction.Norm();
sppotdirection[0] = -AllLight[VazyFeTourner].Direction.x*ScaleNorm;
sppotdirection[1] = -AllLight[VazyFeTourner].Direction.y*ScaleNorm;
sppotdirection[2] = -AllLight[VazyFeTourner].Direction.z*ScaleNorm;
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_SPOT_DIRECTION, sppotdirection);
float Cutof,SpotExp;
Cutof = 180.0f;
if (AllLight[VazyFeTourner].LightDesc->LightType == 1)
{
Cutof = AllLight[VazyFeTourner].LightDesc->BigAlpha * 180.0f / 3.1415927f;
SpotExp = 0;
if (AllLight[VazyFeTourner].LightDesc->BigAlpha)
SpotExp = 128.0f * (1.0f - AllLight[VazyFeTourner].LightDesc->SmallAlpha / AllLight[VazyFeTourner].LightDesc->BigAlpha);
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_SPOT_EXPONENT, &SpotExp);
}
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_SPOT_CUTOFF, &Cutof);
if ((AllLight[VazyFeTourner].LightDesc->LightType == 2) /*|| // Direct ?
(AllLight[VazyFeTourner].LightDesc->LightType == 3)*/) // or ambient
{
position[0] = AllLight[VazyFeTourner].Direction.x;
position[1] = AllLight[VazyFeTourner].Direction.y;
position[2] = AllLight[VazyFeTourner].Direction.z;
position[3] = 0.0f;
}
else
{
position[0] = AllLight[VazyFeTourner].Position.x;
position[1] = AllLight[VazyFeTourner].Position.y;
position[2] = AllLight[VazyFeTourner].Position.z;
position[3] = 1.0f;
}
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_POSITION, position);
if ((AllLight[VazyFeTourner].LightDesc->LightType != 2)/*&&
(AllLight[VazyFeTourner].LightDesc->LightType != 3)*/)// !Direct or ambient?
{
Atenuaztion[0] = 1.0f;
Atenuaztion[1] = -0.41421356 / (AllLight[VazyFeTourner].LightDesc->Far*ScaleNorm);
Atenuaztion[2] = 1.41421356 / (AllLight[VazyFeTourner].LightDesc->Far*ScaleNorm);
}
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_CONSTANT_ATTENUATION, &Atenuaztion[0]);
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_LINEAR_ATTENUATION, &Atenuaztion[1]);
glLightfv(GL_LIGHT0+ VazyFeTourner, GL_QUADRATIC_ATTENUATION, &Atenuaztion[2]);
}
}
Color = CurrentColor/* | 0xff000000*/;
if (CurrentRS.NormalExtraction != 0.0f)
{
glBegin(GL_TRIANGLES);
glColor4ubv((GLubyte *)&Color);
while (Counter--)
{
Vector V;
if (PointColors) glColor4ubv(PointColors + 4*Indexes->I[0]);
glTexCoord3fv((GLfloat *)(PointsUV + Indexes_UV->I[0]));
glNormal3fv((GLfloat *)(PointsN + Indexes->I[0]));
V = (*(PointsN + Indexes->I[0]) * CurrentRS.NormalExtraction) + *(Points + Indexes->I[0]);
glVertex3fv((GLfloat *)&V);
if (PointColors) glColor4ubv(PointColors + 4*Indexes->I[2]);
glTexCoord3fv((GLfloat *)(PointsUV + Indexes_UV->I[2]));
glNormal3fv((GLfloat *)(PointsN + Indexes->I[2]));
V = (*(PointsN + Indexes->I[2]) * CurrentRS.NormalExtraction) + *(Points + Indexes->I[2]);
glVertex3fv((GLfloat *)&V);
if (PointColors) glColor4ubv(PointColors + 4*Indexes->I[1]);
glTexCoord3fv((GLfloat *)(PointsUV + Indexes_UV->I[1]));
glNormal3fv((GLfloat *)(PointsN + Indexes->I[1]));
V = (*(PointsN + Indexes->I[1]) * CurrentRS.NormalExtraction) + *(Points + Indexes->I[1]);
glVertex3fv((GLfloat *)&V);
Indexes++;
Indexes_UV++;
}
glEnd();
} else
{
if (OptimiseQuadRender && pMyMesh->NumberOfFaces == 2 && pMyMesh->NumberOfPoints == 4)
{
glBegin(GL_POLYGON);
glColor4ubv((GLubyte *) &Color);
glTexCoord3fv( (GLfloat *)(PointsUV));
glVertex3fv( (GLfloat *)(Points));
glTexCoord3fv( (GLfloat *)(PointsUV+3));
glVertex3fv( (GLfloat *)(Points+3));
glTexCoord3fv( (GLfloat *)(PointsUV+2));
glVertex3fv( (GLfloat *)(Points+2));
glTexCoord3fv( (GLfloat *)(PointsUV+1));
glVertex3fv( (GLfloat *)(Points+1));
glEnd( );
} else
{
glBegin(GL_TRIANGLES);
glColor4ubv((GLubyte *)&Color);
if (pMyMesh->UVAreUnic) // One UVPP is computed, so we use fast buffers
{
glEnd();
// Invert backface mode
CurrentRS.BACKFACE_INVERT == 0 ? glCullFace(GL_BACK) : glCullFace(GL_FRONT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (PointColors)
{
glEnableClientState(GL_COLOR_ARRAY);
glColor4ubv(PointColors + Indexes_UV->I[1]);
glColorPointer (4, GL_UNSIGNED_BYTE, 4, PointColors);
}
glTexCoordPointer(3, GL_FLOAT, sizeof(Vector), PointsUV);
glNormalPointer(GL_FLOAT, sizeof(Vector), PointsN);
glVertexPointer(3, GL_FLOAT, sizeof(Vector), Points);
glDrawElements(GL_TRIANGLES, Counter*3, GL_UNSIGNED_INT, Indexes);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (PointColors) glDisableClientState(GL_COLOR_ARRAY);
CurrentRS.BACKFACE_INVERT == 0 ? glCullFace(GL_FRONT) : glCullFace(GL_BACK);
} else
{
while (Counter--)
{
if (PointColors) glColor4ubv(PointColors + 4*Indexes->I[0]);
glTexCoord3fv((GLfloat *)(PointsUV + Indexes_UV->I[0]));
glNormal3fv((GLfloat *)(PointsN + Indexes->I[0]));
glVertex3fv((GLfloat *)(Points + Indexes->I[0]));
if (PointColors) glColor4ubv(PointColors + 4*Indexes->I[2]);
glTexCoord3fv((GLfloat *)(PointsUV + Indexes_UV->I[2]));
glNormal3fv((GLfloat *)(PointsN + Indexes->I[2]));
glVertex3fv((GLfloat *)(Points + Indexes->I[2]));
if (PointColors) glColor4ubv(PointColors + 4*Indexes->I[1]);
glTexCoord3fv((GLfloat *)(PointsUV + Indexes_UV->I[1]));
glNormal3fv((GLfloat *)(PointsN + Indexes->I[1]));
glVertex3fv((GLfloat *)(Points + Indexes->I[1]));
Indexes++;
Indexes_UV++;
}//*/
glEnd();//*/
}
}
}
glDisable(GL_LIGHTING);
if (AllLightNumber && CurrentRS.LIGHTED)
{
for (int VazyFeTourner = 0 ; VazyFeTourner < AllLightNumber ; VazyFeTourner++)
glDisable(GL_LIGHT0 + VazyFeTourner);
}
}
void OGL_DI::ReverseRenderMesh(Mesh *pMyMesh,u32 TextureSource,u32 Num, u32 Base)
{
SAVE_MATRIXES();
GLfloat _4x4_Persp_Corrected[16];
GLfloat _4x4_Texture_x_Persp[16];
u32 Counter,Color;
FaceIndex *Indexes;
FaceIndex *Indexes_UV;
Vector Fake;
Vector *PointsN,*PointsUV,*Points;
Points = pMyMesh->Points;
PointsN = pMyMesh->PointsN;
PointsUV = pMyMesh->PointsUV;
if (!Points) Points = &Fake;
if (!PointsN) PointsN = &Fake;
if (!PointsUV) PointsUV = &Fake;
if ((TextureSource == -1) || (AllRef[TextureSource].OGLRef == -1)) return;
Indexes = pMyMesh->Indexes + Base;
Indexes_UV = pMyMesh->Indexes_UV + Base;
if (Num == -1)
Counter = pMyMesh->NumberOfFaces;
else
Counter = Num;
if ((CurrentRS.MappingMode == 4) && pMyMesh->NumberOfPointsUV2) // uv2
{
PointsUV = pMyMesh->PointsUV2;
Indexes_UV = pMyMesh->Indexes_UV2 + Base;
}
Points = pMyMesh->Points;
Setexture(TextureSource);
/*Set perspective to Ortho *********************************************************/
SetMatrix(GL_MODELVIEW,NULL);
GLfloat _4x4[16] = {
2, 0, 0, 0,
0, 2, 0, 0,
0, 0, 0, 0,
-1, -1, 0, 1,
};
SetMatrix(GL_PROJECTION,_4x4);
/*Set texture transfor to perspective **********************************************/
/* recenter MATRIX */
/* Input = X , Y , 1 , Z */
/* output = X+Z , Y+Z , 1 , Z */
float CX,CY,YC;
CX = (float)AllRef[TextureSource].pExtRef->SX / GetUpperPO2((float)AllRef[TextureSource].pExtRef->SX);
CY = (float)AllRef[TextureSource].pExtRef->SY / GetUpperPO2((float)AllRef[TextureSource].pExtRef->SY);
YC = (float)AllRef[TextureSource].pExtRef->SX / (float)AllRef[TextureSource].pExtRef->SY;
YC *= CY;
GLfloat _4x4_PerspLocal[16]= {
FocalSave, 0, 0, 0,
0, FocalSave, 0, 0,
0, 0, 0, 1,
0, 0, 0.1, 0,
};
GLfloat _4x4_Persp2[16]= {
CX/2.0f, 0, 0, 0,
0, YC/2.0f, 0, 0,
0, 0, 1, 0,
CX/2.0f, CY/2.0f, 0, 1,
};
Mul4x4Matrix(_4x4_PerspLocal,_4x4_Persp2,_4x4_Persp_Corrected);
Mul4x4Matrix(_4x4_Model,_4x4_Persp_Corrected,_4x4_Texture_x_Persp);
if (CurrentRS.MappingMode == 1) // Chrome
{
Points = pMyMesh->PointsN;
GLfloat _4x4_Model2[16];
memcpy(_4x4_Model2,_4x4_Model,sizeof(GLfloat)*16);
_4x4_Model2[12] = _4x4_Model2[13] = _4x4_Model2[14] = 0.0f;
_4x4_Model2[14] = 0.0f;
glMatrixMode(GL_TEXTURE);
glTranslatef(0.5,0.5,-1 );
glMultMatrixf( _4x4_Model2 );
glScalef(0.5,0.5,0.5);
} else
SetMatrix(GL_TEXTURE,_4x4_Texture_x_Persp);
/* Compute color in soft (alpha lighting isn't supported with opengl) */
if (ComputeMaskAlpha != 0.0)
{
if (ComputingBufferSize < 4*pMyMesh->NumberOfPoints)
{
if (pComputingBuffer) CC_free(pComputingBuffer);
pComputingBuffer = NULL;
ComputingBufferSize = 4*pMyMesh->NumberOfPoints;
pComputingBuffer = CC_malloc(4*pMyMesh->NumberOfPoints);
}
{
Vector CamDir;
Vector *pNormalBase,*pNormalEnd;
u32 *pColorR;
pColorR = (u32 *)pComputingBuffer;
pNormalBase = pMyMesh->PointsN;
pNormalEnd = pNormalBase + pMyMesh->NumberOfPoints;
CamDir = Vector(-_4x4_Model[2],-_4x4_Model[6],-_4x4_Model[10]);
while (pNormalBase < pNormalEnd)
{
s32 AS;
AS = (s32)((CamDir * *pNormalBase) * 255.0f * ComputeMaskAlpha);
if (AS < 0) AS = 0;
if (AS > 255) AS = 255;
*pColorR = (((u32)AS)<<24) | 0xffffff;
pNormalBase++;
pColorR++;
}
}
}
//*/
/* Render ****************************************************************************/
Color = 0xffffffff;
glBegin(GL_TRIANGLES);
glColor4ubv((GLubyte *)&Color);
if (pMyMesh->UVAreUnic) // One UVPP is computed, so we use fast buffers
{
glEnd();
// Invert backface mode
CurrentRS.BACKFACE_INVERT == 0 ? glCullFace(GL_BACK) : glCullFace(GL_FRONT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
if (ComputeMaskAlpha != 0.0) glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, sizeof(Vector), Points);
glNormalPointer(GL_FLOAT, sizeof(Vector), PointsN);
glVertexPointer(3, GL_FLOAT, sizeof(Vector), PointsUV);
if (ComputeMaskAlpha != 0.0) glColorPointer(4,GL_UNSIGNED_BYTE, sizeof(u32), pComputingBuffer);
glDrawElements(GL_TRIANGLES, Counter*3, GL_UNSIGNED_INT, Indexes);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
if (ComputeMaskAlpha != 0.0) glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
CurrentRS.BACKFACE_INVERT == 0 ? glCullFace(GL_FRONT) : glCullFace(GL_BACK);
} else
{
while (Counter--)
{
if (ComputeMaskAlpha != 0.0) glColor4ubv((GLubyte *)((u32*)pComputingBuffer + Indexes->I[0]));
glTexCoord3fv((GLfloat *)(Points + Indexes->I[0]));
glVertex2fv((GLfloat *)(PointsUV + Indexes_UV->I[0]));
if (ComputeMaskAlpha != 0.0) glColor4ubv((GLubyte *)((u32*)pComputingBuffer + Indexes->I[2]));
glTexCoord3fv((GLfloat *)(Points + Indexes->I[2]));
glVertex2fv((GLfloat *)(PointsUV + Indexes_UV->I[2]));
if (ComputeMaskAlpha != 0.0) glColor4ubv((GLubyte *)((u32*)pComputingBuffer + Indexes->I[1]));
glTexCoord3fv((GLfloat *)(Points + Indexes->I[1]));
glVertex2fv((GLfloat *)(PointsUV + Indexes_UV->I[1]));
Indexes++;
Indexes_UV++;
}
glEnd();
}
RESTORE_MATRIXES();
/* glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);*/
}
// version de brut, tous les angles
#define NB_ANGLES 360
static float *COS_TAB = NULL;
static float *SIN_TAB = NULL;
static SIZE gridSize;
static float *gridX = NULL;
static float *gridY = NULL;
void OGL_DI::DrawParticules(void *pList, int nbParticules, u32 TextureIndex, SIZE grid,RS *RenderState, MATRIX Orientation)
{
int gbIdx;
float *fPtr1;
float *fPtr2;
Particules *particulePtr;
int XTextureIdx, YTextureIdx;
u32 Color = CurrentColor;
Vector NewI, NewJ;
Particules *particuleList = (Particules *)pList;
Color |=0xff000000;
RS Nullmlml;
GLOB_SetDefaultRS(&Nullmlml);
Nullmlml.BACKFACE = 0;
if (RenderState == NULL)
SetRS(&Nullmlml,TextureIndex);
else
SetRS(RenderState,TextureIndex);
if (COS_TAB == NULL)
{
fPtr1 = COS_TAB = (float *)CC_malloc(NB_ANGLES*sizeof(float));
fPtr2 = SIN_TAB = (float *)CC_malloc(NB_ANGLES*sizeof(float));
for (gbIdx=0; gbIdx<NB_ANGLES; gbIdx++, fPtr1++, fPtr2++)
{
*fPtr1 = cos((float)gbIdx*3.1415927/180);
*fPtr2 = sin((float)gbIdx*3.1415927/180);
}
}
if (gridX == NULL ||
gridSize.cx != grid.cx ||
gridSize.cy != grid.cy)
{
if (gridX) CC_free(gridX);
if (gridY) CC_free(gridY);
gridSize = grid;
fPtr1 = gridX = (float *)CC_malloc((gridSize.cx+1)*sizeof(float));
fPtr2 = gridY = (float *)CC_malloc((gridSize.cy+1)*sizeof(float));
for (gbIdx=0; gbIdx<=gridSize.cx; gbIdx++, fPtr1++)
*fPtr1 = (float)gbIdx/gridSize.cx;
for (gbIdx=0; gbIdx<=gridSize.cy; gbIdx++, fPtr2++)
*fPtr2 = (float)gbIdx/gridSize.cy;
}
glBegin(GL_QUADS);
for (particulePtr = particuleList; nbParticules > 0; nbParticules--, particulePtr++)
{
if (!particulePtr->alive) continue;
fPtr1 = COS_TAB + (((int)particulePtr->rotAngle + NB_ANGLES) % NB_ANGLES);
fPtr2 = SIN_TAB + (((int)particulePtr->rotAngle + NB_ANGLES) % NB_ANGLES);
XTextureIdx = particulePtr->textureIdx % gridSize.cx;
YTextureIdx = particulePtr->textureIdx / gridSize.cx;
YTextureIdx = gridSize.cy - YTextureIdx - 1;
NewI = (Orientation.I * *fPtr1 + Orientation.J * *fPtr2)*particulePtr->width*particulePtr->scaleFactor;
NewJ = (Orientation.J * *fPtr1 - Orientation.I * *fPtr2)*particulePtr->height*particulePtr->scaleFactor;
((u8 *)&Color)[0] = ((u32)((u8 *)&CurrentColor)[0] * (u32)((u8 *)&particulePtr->RGBA)[0])>>8;
((u8 *)&Color)[1] = ((u32)((u8 *)&CurrentColor)[1] * (u32)((u8 *)&particulePtr->RGBA)[1])>>8;
((u8 *)&Color)[2] = ((u32)((u8 *)&CurrentColor)[2] * (u32)((u8 *)&particulePtr->RGBA)[2])>>8;
((u8 *)&Color)[3] = ((u32)((u8 *)&CurrentColor)[3] * (u32)((u8 *)&particulePtr->RGBA)[3])>>8;
glColor4ubv((GLubyte *) &Color);
glTexCoord2f(gridX[XTextureIdx ], gridY[YTextureIdx + 1]);
glVertex3f (particulePtr->coords.x - NewI.x + NewJ.x,
particulePtr->coords.y - NewI.y + NewJ.y,
particulePtr->coords.z - NewI.z + NewJ.z);
glTexCoord2f(gridX[XTextureIdx + 1], gridY[YTextureIdx + 1]);
glVertex3f (particulePtr->coords.x + NewI.x + NewJ.x,
particulePtr->coords.y + NewI.y + NewJ.y,
particulePtr->coords.z + NewI.z + NewJ.z);
glTexCoord2f(gridX[XTextureIdx + 1], gridY[YTextureIdx ]);
glVertex3f (particulePtr->coords.x + NewI.x - NewJ.x,
particulePtr->coords.y + NewI.y - NewJ.y,
particulePtr->coords.z + NewI.z - NewJ.z);
glTexCoord2f(gridX[XTextureIdx ], gridY[YTextureIdx ]);
glVertex3f (particulePtr->coords.x - NewI.x - NewJ.x,
particulePtr->coords.y - NewI.y - NewJ.y,
particulePtr->coords.z - NewI.z - NewJ.z);
}
glEnd( );
}
void OGL_DI::DrawFur(void *fur, u32 TextureIndex,RS *RenderState, MATRIX Orientation, u32 debug)
{
FUR_OBJ *furPtr = (FUR_OBJ *)fur;
u32 Color = CurrentColor;
Vector quadPos0, quadPos1, moveVect, axeU, axeV;
RS Nullmlml;
GLOB_SetDefaultRS(&Nullmlml);
Nullmlml.BACKFACE = 0;
if (RenderState == NULL)
SetRS(&Nullmlml,TextureIndex);
else
SetRS(RenderState,TextureIndex);
Color |=0xff000000;
int spriteIdx = 0;
int spriteLvlIdx;
float vStep = 1.0f/furPtr->SpriteLevels;
float vStepVal = 0;
float curVStep;
int curOrientation = 0;
Vector *orientPtr = NULL;
MATRIX orientMat;
Vector orientationDir = (furPtr->OrientationMeca.motionCenterPos - furPtr->OrientationMeca.curCenterPos)*furPtr->OrientationStrengh;
if (furPtr->Mode & 4)
{
glBegin(GL_QUADS);
for (spriteIdx = 0; spriteIdx < furPtr->nbFurElmt; spriteIdx++)
{
axeV = Orientation.I*furPtr->SpriteWidth*furPtr->WidthList[spriteIdx];
if (furPtr->randW) axeV += axeV*furPtr->randW[spriteIdx];
axeU = Orientation.J*furPtr->SpriteHeight*furPtr->HeightList[spriteIdx];
if (furPtr->randH) axeU += axeU*furPtr->randH[spriteIdx];
u32 CurrentInColor = 0;
if (furPtr->ColorList)
{
CurrentInColor= Color;
Color = COL_MulColor(CurrentColor,furPtr->ColorList[spriteIdx]) | 0xff000000;
}
glColor4ubv((GLubyte *) &Color);
glTexCoord2f(0, 1);
glVertex3f (furPtr->OriginList[spriteIdx].x - axeV.x + axeU.x,
furPtr->OriginList[spriteIdx].y - axeV.y + axeU.y,
furPtr->OriginList[spriteIdx].z - axeV.z + axeU.z);
glTexCoord2f(1, 1);
glVertex3f (furPtr->OriginList[spriteIdx].x + axeV.x + axeU.x,
furPtr->OriginList[spriteIdx].y + axeV.y + axeU.y,
furPtr->OriginList[spriteIdx].z + axeV.z + axeU.z);
glTexCoord2f(1, 0);
glVertex3f (furPtr->OriginList[spriteIdx].x + axeV.x - axeU.x,
furPtr->OriginList[spriteIdx].y + axeV.y - axeU.y,
furPtr->OriginList[spriteIdx].z + axeV.z - axeU.z);
glTexCoord2f(0, 0);
glVertex3f (furPtr->OriginList[spriteIdx].x - axeV.x - axeU.x,
furPtr->OriginList[spriteIdx].y - axeV.y - axeU.y,
furPtr->OriginList[spriteIdx].z - axeV.z - axeU.z);
if (furPtr->ColorList)
{
Color = CurrentInColor;
}
}
glEnd( );
} else
{
for (spriteIdx = 0; spriteIdx < furPtr->nbFurElmt; spriteIdx++)
{
if (furPtr->Mode & 1 && furPtr->nbOrientation > 0)
{
orientPtr = furPtr->OrientationList + curOrientation;
curOrientation = (curOrientation + 1) % furPtr->nbOrientation;
if (furPtr->Mode & 2)
{
orientMat.I = furPtr->DirectionList[spriteIdx];
orientMat.J = furPtr->VList[spriteIdx];
orientMat.K = orientMat.I^orientMat.J;
memset(&orientMat.T, 0, sizeof(orientMat.T));
orientMat.T = orientMat**orientPtr;
orientPtr = &orientMat.T;
} else
{
orientMat.T = *orientPtr;
orientPtr = &orientMat.T;
}
*orientPtr *= furPtr->OrientationStrengh;
*orientPtr += orientationDir;
}
if (furPtr->Mode & 8)
axeV = Orientation.I*(furPtr->SpriteWidth*furPtr->WidthList[spriteIdx]);
else
axeV = furPtr->VList[spriteIdx]*(furPtr->SpriteWidth*furPtr->WidthList[spriteIdx]);
u32 CurrentInColor = 0;
if (furPtr->ColorList)
{
CurrentInColor= Color;
Color = COL_MulColor(CurrentColor,furPtr->ColorList[spriteIdx]) | 0xff000000;
}
for (int pass=0; pass<2; pass++)
{
if (furPtr->randW) axeV += axeV*furPtr->randW[spriteIdx];
curVStep = vStep*(furPtr->SpriteHeight*furPtr->HeightList[spriteIdx]);
if (furPtr->randH) curVStep+= curVStep*furPtr->randH[spriteIdx];
quadPos0 = (furPtr->OriginList[spriteIdx] + furPtr->DirectionList[spriteIdx]*furPtr->SpritePosition) - axeV;
quadPos1 = (furPtr->OriginList[spriteIdx] + furPtr->DirectionList[spriteIdx]*furPtr->SpritePosition) + axeV;
glBegin(GL_QUAD_STRIP);
glColor4ubv((GLubyte *) &Color);
vStepVal = 0;
for (spriteLvlIdx = 0; spriteLvlIdx <= furPtr->SpriteLevels; spriteLvlIdx++, vStepVal += vStep)
{
glTexCoord2f(0, vStepVal);
glVertex3f (quadPos0.x, quadPos0.y, quadPos0.z);
glTexCoord2f(1, vStepVal);
glVertex3f (quadPos1.x, quadPos1.y, quadPos1.z);
if (orientPtr)
moveVect = (*orientPtr*spriteLvlIdx) +
furPtr->DirectionList[spriteIdx]*(furPtr->SpriteLevels - spriteLvlIdx);
else
moveVect = (orientationDir*spriteLvlIdx) +
furPtr->DirectionList[spriteIdx]*(furPtr->SpriteLevels - spriteLvlIdx);
moveVect.Normalize();
moveVect *= curVStep;
quadPos0 += moveVect;
quadPos1 += moveVect;
}
if (pass == 0 && furPtr->Mode & 16)
axeV = axeV^furPtr->DirectionList[spriteIdx];
else
pass = 10;
}
glEnd( );
if (furPtr->ColorList)
{
Color = CurrentInColor;
}
}
}
if (debug)
{
ClearZ();
SetRS(&Nullmlml,-1);
DrawLine(0xffffffff, &furPtr->OrientationMeca.motionCenterPos, &furPtr->OrientationMeca.curCenterPos, 2);
}
}