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

827 lines
No EOL
33 KiB
C++

#include "D3D_Class.h"
#include "SCENE.h"
#ifdef __D3D
#ifndef PI
#define PI (3.14159265358979323846)
#endif
u32 COL_MulColor(u32 A,u32 B);
void D3D_DI::RenderMesh(Mesh *pMyMesh,u32 Num, u32 Base)
{
#if 1
u32 Counter,Color;
FaceIndex *Indexes;
FaceIndex *Indexes_UV;
Vector Fake;
Vector *PointsN,*PointsUV,*Points;
u8 *PointColors;
Points = pMyMesh->Points;
PointsN = pMyMesh->PointsN;
PointsUV = pMyMesh->PointsUV;
PointColors = (u8*)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 (Counter > MaxD3DVertices/3) Counter = MaxD3DVertices/3; // DO NOT ACCEPT BIG MESHES
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);
static D3DMATERIAL9* d3dMat = 0;
if (d3dMat == 0)
{
d3dMat = new D3DMATERIAL9();
memset(d3dMat, 0, sizeof(D3DMATERIAL9));
D3DCOLORVALUE ambient = {0.2, 0.2, 0.2, 1.0};
D3DCOLORVALUE diffuse = {0.8, 0.8, 0.8, 1.0};
D3DCOLORVALUE specular = {0.0, 0.0, 0.0, 1.0};
D3DCOLORVALUE emissive = {0.0, 0.0, 0.0, 1.0};
d3dMat->Ambient = ambient;
d3dMat->Diffuse = diffuse;
d3dMat->Specular = specular;
d3dMat->Emissive = emissive;
d3dMat->Power = 0;
d3ddev->SetRenderState(D3DRS_AMBIENT, 0xFF333333); // to match OpenGL default of (0.2, 0.2, 0.2, 1.0)
d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE , D3DMCS_MATERIAL);//*/
}
d3ddev->SetMaterial(d3dMat);
if (AllLightNumber && CurrentRS.LIGHTED)
{
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);
for (int VazyFeTourner = 0 ; VazyFeTourner < AllLightNumber ; VazyFeTourner++)
{
//glEnable(GL_LIGHT0 + VazyFeTourner);
d3ddev->LightEnable(VazyFeTourner, true);
d3dLight[VazyFeTourner].Falloff = 1.0f; d3dLight[VazyFeTourner].Range = 1000.0f;
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];
D3DXMATRIX ModelView, invModelView;
GetMatrix(1, (float*)&ModelView);
float det = D3DXMatrixDeterminant(&ModelView);
D3DXMatrixInverse(&invModelView, &det, &ModelView);
diffuseLight[0] = AllLight[VazyFeTourner].LightDesc->LightColor.x;
diffuseLight[1] = AllLight[VazyFeTourner].LightDesc->LightColor.y;
diffuseLight[2] = AllLight[VazyFeTourner].LightDesc->LightColor.z;
if (AllLight[VazyFeTourner].LightDesc->LightType == 0) // point
d3dLight[VazyFeTourner].Type = D3DLIGHT_POINT;
if (AllLight[VazyFeTourner].LightDesc->LightType == 3) // Ambient
{
d3dLight[VazyFeTourner].Type = D3DLIGHT_POINT;
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);
memcpy(&d3dLight[VazyFeTourner].Ambient, ambientLight, sizeof(D3DCOLORVALUE));
memcpy(&d3dLight[VazyFeTourner].Diffuse, diffuseLight, sizeof(D3DCOLORVALUE));
memcpy(&d3dLight[VazyFeTourner].Specular, specularLight, sizeof(D3DCOLORVALUE));
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);
D3DXVECTOR4 dir(sppotdirection[0], sppotdirection[1], sppotdirection[2], 0.0f);
D3DXVECTOR4 result;
D3DXVec4Transform(&result, &dir, &invModelView);
memcpy(&d3dLight[VazyFeTourner].Direction, &result, sizeof(D3DVECTOR));
float Cutof, SpotExp;
Cutof = 180.0f;
if (AllLight[VazyFeTourner].LightDesc->LightType == 1)
{
d3dLight[VazyFeTourner].Type = D3DLIGHT_SPOT;
Cutof = AllLight[VazyFeTourner].LightDesc->BigAlpha * 180.0f;
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);
//d3dLight[VazyFeTourner].Falloff = SpotExp;
}
//glLightfv(GL_LIGHT0+ VazyFeTourner, GL_SPOT_CUTOFF, &Cutof);
d3dLight[VazyFeTourner].Theta = d3dLight[VazyFeTourner].Phi = Cutof * PI / 180.0f;
if ((AllLight[VazyFeTourner].LightDesc->LightType == 2) /*|| // Direct ?
(AllLight[VazyFeTourner].LightDesc->LightType == 3)*/) // or ambient
{
d3dLight[VazyFeTourner].Type = D3DLIGHT_DIRECTIONAL;
position[0] = AllLight[VazyFeTourner].Direction.x;
position[1] = AllLight[VazyFeTourner].Direction.y;
position[2] = -AllLight[VazyFeTourner].Direction.z;
position[3] = 0.0f;
D3DXVECTOR4 dir(position[0],position[1], position[2], position[3]);
D3DXVECTOR4 result;
D3DXVec4Transform(&result, &dir, &ModelView);
memcpy(&d3dLight[VazyFeTourner].Direction, &result, sizeof(D3DVECTOR));
}
else // positional
{
position[0] = AllLight[VazyFeTourner].Position.x;
position[1] = AllLight[VazyFeTourner].Position.y;
position[2] = AllLight[VazyFeTourner].Position.z;
position[3] = 1.0f;
D3DXVECTOR4 pos(position[0],position[1], position[2], position[3]);
D3DXVECTOR4 result;
D3DXVec4Transform(&result, &pos, &ModelView);
memcpy(&d3dLight[VazyFeTourner].Position, &result, sizeof(D3DVECTOR));
}
//glLightfv(GL_LIGHT0+ VazyFeTourner, GL_POSITION, position);
//memcpy(&d3dLight[VazyFeTourner].Direction, &AllLight[VazyFeTourner].Direction, sizeof(D3DVECTOR));
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]);
d3dLight[VazyFeTourner].Attenuation0 = Atenuaztion[0];
d3dLight[VazyFeTourner].Attenuation1 = Atenuaztion[1];
d3dLight[VazyFeTourner].Attenuation2 = Atenuaztion[2];
d3ddev->SetLight(VazyFeTourner, &d3dLight[VazyFeTourner]);
}
}
Vertex* v;
m_pVertexBuffer->Lock(0, 0, (void**)&v, D3DLOCK_DISCARD);
WORD* ic;
m_pIndexBuffer->Lock(0, 0, (void**)&ic, D3DLOCK_DISCARD);
Color = CurrentColor; // | 0xff000000;
D3DCOLOR color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
int i = 0, j =0;
if (CurrentRS.NormalExtraction != 0.0f)
{
i = 0;
j = Counter;
while (j--)
{
Vector V;
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*Indexes->I[0]+3], PointColors[4*Indexes->I[0]+0], PointColors[4*Indexes->I[0]+1], PointColors[4*Indexes->I[0]+2]);
V = (*(PointsN + Indexes->I[0]) * CurrentRS.NormalExtraction) + *(Points + Indexes->I[0]);
v[i*3] = Vertex(V.x, V.y, V.z, color, PointsN[Indexes->I[0]].x, PointsN[Indexes->I[0]].y, PointsN[Indexes->I[0]].z, PointsUV[Indexes_UV->I[0]].x, PointsUV[Indexes_UV->I[0]].y, PointsUV[Indexes_UV->I[0]].z);
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*Indexes->I[2]+3], PointColors[4*Indexes->I[2]+0], PointColors[4*Indexes->I[2]+1], PointColors[4*Indexes->I[2]+2]);
V = (*(PointsN + Indexes->I[2]) * CurrentRS.NormalExtraction) + *(Points + Indexes->I[2]);
v[i*3+1] = Vertex(V.x, V.y, V.z, color, PointsN[Indexes->I[2]].x, PointsN[Indexes->I[2]].y, PointsN[Indexes->I[2]].z, PointsUV[Indexes_UV->I[2]].x, PointsUV[Indexes_UV->I[2]].y, PointsUV[Indexes_UV->I[2]].z);
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*Indexes->I[1]+3], PointColors[4*Indexes->I[1]+0], PointColors[4*Indexes->I[1]+1], PointColors[4*Indexes->I[1]+2]);
V = (*(PointsN + Indexes->I[1]) * CurrentRS.NormalExtraction) + *(Points + Indexes->I[1]);
v[i*3+2] = Vertex(V.x, V.y, V.z, color, PointsN[Indexes->I[1]].x, PointsN[Indexes->I[1]].y, PointsN[Indexes->I[1]].z, PointsUV[Indexes_UV->I[1]].x, PointsUV[Indexes_UV->I[1]].y, PointsUV[Indexes_UV->I[1]].z);
Indexes++;
Indexes_UV++;
i++;
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, Counter);
}
else
{
if (OptimiseQuadRender && pMyMesh->NumberOfFaces == 2 && pMyMesh->NumberOfPoints == 4)
{
//for (i=0; i<2; i++) // just 2 triangles for the quad
{
v[0] = Vertex(Points[0].x, Points[0].y, Points[0].z, color, PointsN[0].x, PointsN[0].y, PointsN[0].z, PointsUV[0].x, PointsUV[0].y, PointsUV[0].z);
v[1] = Vertex(Points[3].x, Points[3].y, Points[3].z, color, PointsN[3].x, PointsN[3].y, PointsN[3].z, PointsUV[3].x, PointsUV[3].y, PointsUV[3].z);
v[2] = Vertex(Points[2].x, Points[2].y, Points[2].z, color, PointsN[2].x, PointsN[2].y, PointsN[2].z, PointsUV[2].x, PointsUV[2].y, PointsUV[2].z);
v[3] = Vertex(Points[2].x, Points[2].y, Points[2].z, color, PointsN[2].x, PointsN[2].y, PointsN[2].z, PointsUV[2].x, PointsUV[2].y, PointsUV[2].z);
v[4] = Vertex(Points[1].x, Points[1].y, Points[1].z, color, PointsN[1].x, PointsN[1].y, PointsN[1].z, PointsUV[1].x, PointsUV[1].y, PointsUV[1].z);
v[5] = Vertex(Points[0].x, Points[0].y, Points[0].z, color, PointsN[0].x, PointsN[0].y, PointsN[0].z, PointsUV[0].x, PointsUV[0].y, PointsUV[0].z);
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
}
else
{
//glBegin(GL_TRIANGLES);
//glColor4ubv((GLubyte *)&Color);
if (pMyMesh->UVAreUnic) // One UVPP is computed, so we use fast buffers
{
//glEnd();
// Invert backface mode
if (CurrentRS.BACKFACE) d3ddev->SetRenderState(D3DRS_CULLMODE, CurrentRS.BACKFACE_INVERT == 0 ? D3DCULL_CW : D3DCULL_CCW);
//glDrawElements(GL_TRIANGLES, Counter*3, GL_UNSIGNED_INT, Indexes);
for (i=0; i<pMyMesh->NumberOfPoints; i++) // fill in the vertices
{
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*i+3], PointColors[4*i+0], PointColors[4*i+1], PointColors[4*i+2]);
v[i] = Vertex(Points[i].x, Points[i].y, Points[i].z, color, PointsN[i].x, PointsN[i].y, PointsN[i].z, PointsUV[i].x, PointsUV[i].y, PointsUV[i].z);
}
for (i=0; i<Counter; i++) // fill in indices
{
ic[i*3+0] = Indexes[i].I[0];
ic[i*3+1] = Indexes[i].I[1];
ic[i*3+2] = Indexes[i].I[2];
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, pMyMesh->NumberOfPoints, 0, Counter);
if (CurrentRS.BACKFACE) d3ddev->SetRenderState(D3DRS_CULLMODE, CurrentRS.BACKFACE_INVERT == 0 ? D3DCULL_CCW : D3DCULL_CW);
//*/
}
else
{
i = 0;
j = Counter;
while (j--)
{
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*Indexes->I[0]+3], PointColors[4*Indexes->I[0]+0], PointColors[4*Indexes->I[0]+1], PointColors[4*Indexes->I[0]+2]);
v[i*3] = Vertex(Points[Indexes->I[0]].x, Points[Indexes->I[0]].y, Points[Indexes->I[0]].z, color, PointsN[Indexes->I[0]].x, PointsN[Indexes->I[0]].y, PointsN[Indexes->I[0]].z, PointsUV[Indexes_UV->I[0]].x, PointsUV[Indexes_UV->I[0]].y, PointsUV[Indexes_UV->I[0]].z);
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*Indexes->I[2]+3], PointColors[4*Indexes->I[2]+0], PointColors[4*Indexes->I[2]+1], PointColors[4*Indexes->I[2]+2]);
v[i*3+1] = Vertex(Points[Indexes->I[2]].x, Points[Indexes->I[2]].y, Points[Indexes->I[2]].z, color, PointsN[Indexes->I[2]].x, PointsN[Indexes->I[2]].y, PointsN[Indexes->I[2]].z, PointsUV[Indexes_UV->I[2]].x, PointsUV[Indexes_UV->I[2]].y, PointsUV[Indexes_UV->I[2]].z);
if (PointColors) color = D3DCOLOR_ARGB(PointColors[4*Indexes->I[1]+3], PointColors[4*Indexes->I[1]+0], PointColors[4*Indexes->I[1]+1], PointColors[4*Indexes->I[1]+2]);
v[i*3+2] = Vertex(Points[Indexes->I[1]].x, Points[Indexes->I[1]].y, Points[Indexes->I[1]].z, color, PointsN[Indexes->I[1]].x, PointsN[Indexes->I[1]].y, PointsN[Indexes->I[1]].z, PointsUV[Indexes_UV->I[1]].x, PointsUV[Indexes_UV->I[1]].y, PointsUV[Indexes_UV->I[1]].z);
Indexes++;
Indexes_UV++;
i++;
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, Counter);
}
}
}
d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);
if (AllLightNumber && CurrentRS.LIGHTED)
{
for (int VazyFeTourner = 0 ; VazyFeTourner < AllLightNumber ; VazyFeTourner++)
//glDisable(GL_LIGHT0 + VazyFeTourner);
d3ddev->LightEnable(VazyFeTourner, false);
}
#endif
}
void D3D_DI::ReverseRenderMesh(Mesh *pMyMesh,u32 TextureSource,u32 Num, u32 Base)
{
#if 1
SAVE_MATRIXES();
f32 _4x4_Persp_Corrected[16];
f32 _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 *********************************************************/
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
Matrix(0); // load identity into modelview mat
f32 _4x4[16] = {
2, 0, 0, 0,
0, 2, 0, 0,
0, 0, 0, 0,
-1, -1, 0, 1,
};
SetMatrix(0, _4x4); // load into proj mat
/*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;
f32 _4x4_PerspLocal[16]= {
FocalSave, 0, 0, 0,
0, FocalSave, 0, 0,
0, 0, 0, 1,
0, 0, 0.1, 0,
};
f32 _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);
//glMatrixMode(GL_TEXTURE);
if (CurrentRS.MappingMode == 1) // Chrome
{
Points = pMyMesh->PointsN;
f32 _4x4_Model2[16];
memcpy(_4x4_Model2, _4x4_Model, sizeof(f32)*16);
_4x4_Model2[12] = _4x4_Model2[13] = _4x4_Model2[14] = 0.0f;
_4x4_Model2[14] = 0.0f;
//glMatrixMode(GL_TEXTURE);
D3DXMATRIX trans; D3DXMatrixTranslation(&trans, 0.5, 0.5, -1);
D3DXMATRIX model2; memcpy(&model2, _4x4_Model2, sizeof(D3DXMATRIX));
D3DXMATRIX scale; D3DXMatrixScaling(&scale, 0.5, 0.5, 0.5);
D3DXMATRIX tex; d3ddev->GetTransform(D3DTS_TEXTURE0, &tex);
tex = scale * model2 * trans * tex;
// Modify translation
//ModifyTextureTranslation(&tex);
//d3ddev->SetTransform(D3DTS_TEXTURE0, &tex);
SetMatrix(2, (float*)&tex);
}
else
{
SetMatrix(2, _4x4_Texture_x_Persp); // load into texture mat
}
/*
// the following block of code flips the y coordinates of the texture
D3DXMATRIX mTexture; d3ddev->GetTransform(D3DTS_TEXTURE0, &mTexture);
D3DXMATRIX mTrans, mScale;
D3DXMatrixScaling(&mScale, 1.0f, -1.0f, 1.0f);
D3DXMatrixTranslation(&mTrans, 0.0f, 1.0f - CY, 0.0f); // to adjust off-center y
mTexture = mTexture * mTrans * mScale;
d3ddev->SetTransform(D3DTS_TEXTURE0, &mTexture);
//*/
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
/* 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 ****************************************************************************/
Vertex* v;
m_pVertexBuffer->Lock(0, 0, (void**)&v, D3DLOCK_DISCARD);
WORD* ic;
m_pIndexBuffer->Lock(0, 0, (void**)&ic, D3DLOCK_DISCARD);
Color = 0xffffffff;
D3DCOLOR color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
int i = 0, j = 0;
if (pMyMesh->UVAreUnic) // One UVPP is computed, so we use fast buffers
{
//glEnd();
// Invert backface mode
if (CurrentRS.BACKFACE) d3ddev->SetRenderState(D3DRS_CULLMODE, CurrentRS.BACKFACE_INVERT == 0 ? D3DCULL_CW : D3DCULL_CCW);
for (i=0; i<Counter; i++)
{
if (ComputeMaskAlpha != 0.0) Color = ((u32*)pComputingBuffer)[Indexes[i].I[0]];
color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
v[i*3] = Vertex(PointsUV[Indexes[i].I[0]].x, PointsUV[Indexes[i].I[0]].y, PointsUV[Indexes[i].I[0]].z, color, PointsN[Indexes[i].I[0]].x, PointsN[Indexes[i].I[0]].y, PointsN[Indexes[i].I[0]].z, Points[Indexes[i].I[0]].x, Points[Indexes[i].I[0]].y, Points[Indexes[i].I[0]].z);
if (ComputeMaskAlpha != 0.0) Color = ((u32*)pComputingBuffer)[Indexes[i].I[2]];
color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
v[i*3+1] = Vertex(PointsUV[Indexes[i].I[1]].x, PointsUV[Indexes[i].I[1]].y, PointsUV[Indexes[i].I[0]].z, color, PointsN[Indexes[i].I[1]].x, PointsN[Indexes[i].I[1]].y, PointsN[Indexes[i].I[1]].z, Points[Indexes[i].I[1]].x, Points[Indexes[i].I[1]].y, Points[Indexes[i].I[1]].z);
if (ComputeMaskAlpha != 0.0) Color = ((u32*)pComputingBuffer)[Indexes[i].I[1]];
color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
v[i*3+2] = Vertex(PointsUV[Indexes[i].I[2]].x, PointsUV[Indexes[i].I[2]].y, PointsUV[Indexes[i].I[0]].z, color, PointsN[Indexes[i].I[2]].x, PointsN[Indexes[i].I[2]].y, PointsN[Indexes[i].I[2]].z, Points[Indexes[i].I[2]].x, Points[Indexes[i].I[2]].y, Points[Indexes[i].I[2]].z);//*/
} //*/
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, Counter);
if (CurrentRS.BACKFACE) d3ddev->SetRenderState(D3DRS_CULLMODE, CurrentRS.BACKFACE_INVERT == 0 ? D3DCULL_CW : D3DCULL_CCW);
}
else
{
i = 0;
j = Counter;
while (j--)
{
if (ComputeMaskAlpha != 0.0) Color = *(((u32*)pComputingBuffer) + Indexes->I[0]);
color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
v[i*3] = Vertex(PointsUV[Indexes_UV->I[0]].x, PointsUV[Indexes_UV->I[0]].y, PointsUV[Indexes_UV->I[0]].z, color, PointsN[Indexes->I[0]].x, PointsN[Indexes->I[0]].y, PointsN[Indexes->I[0]].z, Points[Indexes->I[0]].x, Points[Indexes->I[0]].y, Points[Indexes->I[0]].z);
if (ComputeMaskAlpha != 0.0) Color = *(((u32*)pComputingBuffer) + Indexes->I[2]);
color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
v[i*3+1] = Vertex(PointsUV[Indexes_UV->I[2]].x, PointsUV[Indexes_UV->I[2]].y, PointsUV[Indexes_UV->I[0]].z, color, PointsN[Indexes->I[2]].x, PointsN[Indexes->I[2]].y, PointsN[Indexes->I[2]].z, Points[Indexes->I[2]].x, Points[Indexes->I[2]].y, Points[Indexes->I[2]].z);
if (ComputeMaskAlpha != 0.0) Color = *(((u32*)pComputingBuffer) + Indexes->I[1]);
color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
v[i*3+2] = Vertex(PointsUV[Indexes_UV->I[1]].x, PointsUV[Indexes_UV->I[1]].y, PointsUV[Indexes_UV->I[0]].z, color, PointsN[Indexes->I[1]].x, PointsN[Indexes->I[1]].y, PointsN[Indexes->I[1]].z, Points[Indexes->I[1]].x, Points[Indexes->I[1]].y, Points[Indexes->I[1]].z);//*/
i++;
Indexes++;
Indexes_UV++;
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, Counter);
}
RESTORE_MATRIXES();
#endif
}
// 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 D3D_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;
}
/*******************************RENDER******************************************************/
Vertex* v;
WORD* ic;
D3DCOLOR color;
particulePtr = particuleList;
while (nbParticules > 0)
{
int i = 0;
m_pVertexBuffer->Lock(0, 0, (void**)&v, D3DLOCK_DISCARD);
m_pIndexBuffer->Lock(0, 0, (void**)&ic, D3DLOCK_DISCARD);
for (; nbParticules > 0 && i<(MaxD3DVertices-6); 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;
color = D3DCOLOR_ARGB((particulePtr->RGBA) & 0xFF, (particulePtr->RGBA >> 24) & 0xFF, (particulePtr->RGBA >> 16) & 0xFF, (particulePtr->RGBA >> 8) & 0xFF);
v[i++] = Vertex(particulePtr->coords.x - NewI.x - NewJ.x, particulePtr->coords.y - NewI.y - NewJ.y, particulePtr->coords.z - NewI.z - NewJ.z, color, 0, 0, -1, gridX[XTextureIdx ], 1.0f - gridY[YTextureIdx + 1], 1.0f);
v[i++] = Vertex(particulePtr->coords.x + NewI.x - NewJ.x, particulePtr->coords.y + NewI.y - NewJ.y, particulePtr->coords.z + NewI.z - NewJ.z, color, 0, 0, -1, gridX[XTextureIdx + 1], 1.0f - gridY[YTextureIdx + 1], 1.0f);
v[i++] = Vertex(particulePtr->coords.x + NewI.x + NewJ.x, particulePtr->coords.y + NewI.y + NewJ.y, particulePtr->coords.z + NewI.z + NewJ.z, color, 0, 0, -1, gridX[XTextureIdx + 1], 1.0f - gridY[YTextureIdx ], 1.0f);
v[i++] = Vertex(particulePtr->coords.x + NewI.x + NewJ.x, particulePtr->coords.y + NewI.y + NewJ.y, particulePtr->coords.z + NewI.z + NewJ.z, color, 0, 0, -1, gridX[XTextureIdx + 1], 1.0f - gridY[YTextureIdx ], 1.0f);
v[i++] = Vertex(particulePtr->coords.x - NewI.x + NewJ.x, particulePtr->coords.y - NewI.y + NewJ.y, particulePtr->coords.z - NewI.z + NewJ.z, color, 0, 0, -1, gridX[XTextureIdx ], 1.0f - gridY[YTextureIdx ], 1.0f);
v[i++] = Vertex(particulePtr->coords.x - NewI.x - NewJ.x, particulePtr->coords.y - NewI.y - NewJ.y, particulePtr->coords.z - NewI.z - NewJ.z, color, 0, 0, -1, gridX[XTextureIdx ], 1.0f - gridY[YTextureIdx + 1], 1.0f);
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, i/3);
}
}
void D3D_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;
Vertex* v;
WORD* ic;
D3DCOLOR color;
int i = 0;
if (furPtr->Mode & 4)
{
spriteIdx = 0;
while (spriteIdx < furPtr->nbFurElmt)
{
i = 0;
m_pVertexBuffer->Lock(0, 0, (void**)&v, D3DLOCK_DISCARD);
m_pIndexBuffer->Lock(0, 0, (void**)&ic, D3DLOCK_DISCARD);
for (spriteIdx; spriteIdx < furPtr->nbFurElmt && i<(MaxD3DVertices-6); 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;
}
color = ARGB2ABGR(Color);
v[i++] = Vertex( furPtr->OriginList[spriteIdx].x - axeV.x + axeU.x,
furPtr->OriginList[spriteIdx].y - axeV.y + axeU.y,
furPtr->OriginList[spriteIdx].z - axeV.z + axeU.z,
color, 0, 0, -1, 0, 1, 1.0f);
v[i++] = Vertex( furPtr->OriginList[spriteIdx].x + axeV.x + axeU.x,
furPtr->OriginList[spriteIdx].y + axeV.y + axeU.y,
furPtr->OriginList[spriteIdx].z + axeV.z + axeU.z,
color, 0, 0, -1, 1, 1, 1.0f);
v[i++] = Vertex( furPtr->OriginList[spriteIdx].x + axeV.x - axeU.x,
furPtr->OriginList[spriteIdx].y + axeV.y - axeU.y,
furPtr->OriginList[spriteIdx].z + axeV.z - axeU.z,
color, 0, 0, -1, 1, 0, 1.0f);
v[i++] = Vertex( furPtr->OriginList[spriteIdx].x + axeV.x - axeU.x,
furPtr->OriginList[spriteIdx].y + axeV.y - axeU.y,
furPtr->OriginList[spriteIdx].z + axeV.z - axeU.z,
color, 0, 0, -1, 1, 0, 1.0f);
v[i++] = Vertex( furPtr->OriginList[spriteIdx].x - axeV.x - axeU.x,
furPtr->OriginList[spriteIdx].y - axeV.y - axeU.y,
furPtr->OriginList[spriteIdx].z - axeV.z - axeU.z,
color, 0, 0, -1, 0, 0, 1.0f);
v[i++] = Vertex( furPtr->OriginList[spriteIdx].x - axeV.x + axeU.x,
furPtr->OriginList[spriteIdx].y - axeV.y + axeU.y,
furPtr->OriginList[spriteIdx].z - axeV.z + axeU.z,
color, 0, 0, -1, 0, 1, 1.0f);
if (furPtr->ColorList)
Color = CurrentInColor;
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, i/3);
}
} 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]);
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;
m_pVertexBuffer->Lock(0, 0, (void**)&v, D3DLOCK_DISCARD);
m_pIndexBuffer->Lock(0, 0, (void**)&ic, D3DLOCK_DISCARD);
u32 CurrentInColor = 0;
if (furPtr->ColorList)
{
CurrentInColor = Color;
Color = COL_MulColor(CurrentColor,furPtr->ColorList[spriteIdx]) | 0xff000000;
}
color = ARGB2ABGR(Color);
vStepVal = 0;
i = 0;
for (spriteLvlIdx = 0; spriteLvlIdx <= furPtr->SpriteLevels; spriteLvlIdx++, vStepVal += vStep)
{
v[i++] = Vertex( quadPos0.x, quadPos0.y, quadPos0.z,
color, 0, 0, -1, 0, vStepVal, 1.0f);
v[i++] = Vertex( quadPos1.x, quadPos1.y, quadPos1.z,
color, 0, 0, -1, 1, vStepVal, 1.0f);
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;
}
m_pVertexBuffer->Unlock();
m_pIndexBuffer->Unlock();
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, i-2);
if (furPtr->ColorList)
Color = CurrentInColor;
}
}
if (debug)
{
ClearZ();
SetRS(&Nullmlml,-1);
DrawLine(0xffffffff, &furPtr->OrientationMeca.motionCenterPos, &furPtr->OrientationMeca.curCenterPos, 2);
}
}
#endif