218 lines
6.8 KiB
C++
218 lines
6.8 KiB
C++
#include <SDL_opengl.h>
|
|
#include <malloc.h>
|
|
#include "sbre_int.h"
|
|
|
|
static const int pNumIndex[3] =
|
|
{ (2*4+1*8)*3, (2*8+5*16)*3, (2*16+13*32)*3 };
|
|
|
|
static Vector pTVertex4pt[2*4+2];
|
|
static Vector pTVertex8pt[6*8+2];
|
|
static Vector pTVertex16pt[14*16+2];
|
|
|
|
static uint16 pTIndex4pt[(2*4+1*8)*3];
|
|
static uint16 pTIndex8pt[(2*8+5*16)*3];
|
|
static uint16 pTIndex16pt[(2*16+13*32)*3];
|
|
|
|
static Vector *ppTVertex[3] =
|
|
{ pTVertex4pt, pTVertex8pt, pTVertex16pt };
|
|
|
|
static uint16 *ppTIndex[3] =
|
|
{ pTIndex4pt, pTIndex8pt, pTIndex16pt };
|
|
|
|
|
|
/*
|
|
static void MakeRotationalSolid(Vector* pPos, int n, int r, Vector* pRes) {
|
|
int i, j, k;
|
|
for (i=1; i<n-1; i++) {
|
|
float angstep = 2.0f * 3.141592f / steps, ang = 0.0f;
|
|
for (=1; i<n; i++, ang+=angstep, pCur++) {
|
|
pCur->x = sin(ang) * pPos->y;
|
|
pCur->y = cos(ang) * pPos->y;
|
|
pCur->z = pPos->z;
|
|
}
|
|
}
|
|
*pCur = pos0; pCur++;
|
|
*pCur = pos1; pCur++;
|
|
}
|
|
*/
|
|
|
|
static void GenerateThrusters(void) {
|
|
Vector pos0 = { 0.0f, 0.0f, 0.0f };
|
|
Vector pos1 = { 0.0f, 0.0f, 1.0f };
|
|
Vector tan0 = { 0.0f, 1.0f, 0.2f };
|
|
Vector tan1 = { 0.0f, -0.2f, 1.0f };
|
|
|
|
int j, n;
|
|
for(j=0, n=4; j<3; j++, n<<=1) {
|
|
Vector* pCur = ppTVertex[j];
|
|
float t, incstep = 1.0f / (n-1);
|
|
int i; for(i=0, t=incstep; i<n-2; i++, t+=incstep) {
|
|
Vector* pPos = pCur; pCur++;
|
|
ResolveHermiteSpline(&pos0, &pos1, &tan0, &tan1, t, pPos);
|
|
|
|
float angstep = 2.0f * 3.141592f / n, ang = angstep;
|
|
int i; for(i=1; i<n; i++, ang+=angstep, pCur++) {
|
|
pCur->x = sin(ang) * pPos->y;
|
|
pCur->y = cos(ang) * pPos->y;
|
|
pCur->z = pPos->z;
|
|
}
|
|
}
|
|
*pCur = pos0; pCur++;
|
|
*pCur = pos1; pCur++;
|
|
|
|
int ni=0, k;
|
|
uint16 *pIndex = ppTIndex[j];
|
|
|
|
for(k=0; k<n; k++) {
|
|
int k1 = k+1==n ? 0 : k+1;
|
|
pIndex[ni++] = (n-2)*n; pIndex[ni++] = k; pIndex[ni++] = k1;
|
|
pIndex[ni++] = (n-2)*n+1; pIndex[ni++] = k1+(n-3)*n; pIndex[ni++] = k+(n-3)*n;
|
|
}
|
|
for(i=0; i<n-3; i++) {
|
|
for(k=0; k<n; k++) {
|
|
int k1 = k+1==n ? 0 : k+1;
|
|
pIndex[ni++] = k+i*n; pIndex[ni++] = k+i*n+n; pIndex[ni++] = k1+i*n;
|
|
pIndex[ni++] = k1+i*n; pIndex[ni++] = k+i*n+n; pIndex[ni++] = k1+i*n+n;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void RenderThruster(RState* pState, Thruster* pThruster, Vector* pPos, Vector* pDir) {
|
|
// Thruster *pThruster = pState->pModel->pThruster + index;
|
|
|
|
Vector start, end, dir = *pDir;
|
|
VecMul(pPos, pState->scale, &start);
|
|
float power = -VecDot(&dir, (Vector*)pState->pObjParam->linthrust);
|
|
|
|
if(!(pThruster->dir & THRUST_NOANG)) {
|
|
Vector angdir, *pAT = (Vector*)pState->pObjParam->angthrust, cpos;
|
|
VecAdd(&pState->compos, &start, &cpos);
|
|
VecCross(&cpos, &dir, &angdir);
|
|
// VecNorm(&angdir, &angdir);
|
|
float xp = angdir.x * pAT->x;
|
|
float yp = angdir.y * pAT->y;
|
|
float zp = angdir.z * pAT->z;
|
|
if(xp+yp+zp > 0) {
|
|
if(xp > yp && xp > zp && fabs(pAT->x) > power) power = fabs(pAT->x);
|
|
else if(yp > xp && yp > zp && fabs(pAT->y) > power) power = fabs(pAT->y);
|
|
else if(zp > xp && zp > yp && fabs(pAT->z) > power) power = fabs(pAT->z);
|
|
}
|
|
}
|
|
|
|
if(power <= 0.001f) return;
|
|
power *= pState->scale;
|
|
float width = sqrt(power)*pThruster->power*0.6f;
|
|
float len = power*pThruster->power;
|
|
VecMul(&dir, len, &end);
|
|
VecAdd(&end, &start, &end);
|
|
|
|
Vector v1, v2, pos; Matrix m, m2;
|
|
v1.x = dir.y; v1.y = dir.z; v1.z = dir.x;
|
|
VecCross(&v1, &dir, &v2); VecNorm(&v2, &v2);
|
|
VecCross(&v2, &dir, &v1);
|
|
m.x1 = v1.x; m.x2 = v2.x; m.x3 = dir.x;
|
|
m.y1 = v1.y; m.y2 = v2.y; m.y3 = dir.y;
|
|
m.z1 = v1.z; m.z2 = v2.z; m.z3 = dir.z;
|
|
MatMatMult(&pState->objorient, &m, &m2);
|
|
|
|
MatVecMult(&pState->objorient, &start, &pos);
|
|
VecAdd(&pos, &pState->objpos, &pos);
|
|
|
|
float pMV[16];
|
|
pMV[ 0] = m2.x1; pMV[ 1] = m2.y1; pMV[ 2] = m2.z1; pMV[ 3] = 0.0f;
|
|
pMV[ 4] = m2.x2; pMV[ 5] = m2.y2; pMV[ 6] = m2.z2; pMV[ 7] = 0.0f;
|
|
pMV[ 8] = m2.x3; pMV[ 9] = m2.y3; pMV[10] = m2.z3; pMV[11] = 0.0f;
|
|
pMV[12] = pos.x; pMV[13] = pos.y; pMV[14] = pos.z; pMV[15] = 1.0f;
|
|
glPushMatrix();
|
|
glLoadMatrixf(pMV);
|
|
|
|
glScalef(width*0.5f, width*0.5f, len*0.666f);
|
|
glColor4f(0.0f, 0.4f, 1.0f, 0.6f);
|
|
glVertexPointer(3, GL_FLOAT, sizeof(Vector), pTVertex8pt);
|
|
glDrawElements(GL_TRIANGLES, pNumIndex[1], GL_UNSIGNED_SHORT, pTIndex8pt);
|
|
|
|
glScalef(2.0f, 2.0f, 1.5f);
|
|
glColor4f(0.4f, 0.0f, 1.0f, 0.6f);
|
|
glVertexPointer(3, GL_FLOAT, sizeof(Vector), pTVertex8pt);
|
|
glDrawElements(GL_TRIANGLES, pNumIndex[1], GL_UNSIGNED_SHORT, pTIndex8pt);
|
|
|
|
glPopMatrix();
|
|
return;
|
|
}
|
|
|
|
// Occlusion problems
|
|
static void RenderLight (RState* pState, int index) {
|
|
/* Light *pLight = pState->pModel->pLight + index;
|
|
|
|
float *pColor = pLight->pColor;
|
|
if (pLight->animcolor != -1) pColor = pState->pObjParam->ppColor[pLight->animcolor];
|
|
|
|
float power = pLight->power;
|
|
if (pLight->animpower != -1) power *= pState->pObjParam->pAnim[pLight->animpower];
|
|
|
|
Vector xax, zax;
|
|
VecAdd (&pState->campos, pState->pVtx+pLight->vtx, &zax);
|
|
Vector yax = { pState->objorient.x2, pState->objorient.y2, pState->objorient.z2 };
|
|
VecNorm (&zax, &zax); VecCross (&yax, &zax, &xax);
|
|
VecNorm (&xax, &xax); VecCross (&zax, &xax, &yax);
|
|
*/
|
|
}
|
|
|
|
struct TransElem {
|
|
Vector pos, dir;
|
|
Thruster* pThruster;
|
|
float dist;
|
|
};
|
|
|
|
inline void SWAP (TransElem* a, TransElem* b) { TransElem t = *a; *a = *b; *b = t; }
|
|
|
|
static void QuickSort (TransElem* pA, int end) {
|
|
if(end <= 0) return;
|
|
float pivotval = pA[end].dist;
|
|
int i, j; for(i=0, j=0; i<end; i++)
|
|
if(pA[i].dist < pivotval) { SWAP (pA+i, pA+j); j++; }
|
|
SWAP (pA+end, pA+j);
|
|
if(j > 1) QuickSort (pA, j-1); j++;
|
|
if(j < end) QuickSort (pA+j, end-j);
|
|
}
|
|
|
|
static int thrustgen = 0;
|
|
|
|
void RenderThrusters(RState* pState, int numThrusters, Thruster* pThrusters) {
|
|
Vector* pVtx = pState->pVtx;
|
|
|
|
if(!thrustgen) GenerateThrusters();
|
|
thrustgen = 1;
|
|
|
|
TransElem* pList = (TransElem*)alloca(numThrusters*2*sizeof(TransElem));
|
|
Vector tv;
|
|
int i, numElem = 0;
|
|
for(i=0; i<numThrusters; i++) {
|
|
Thruster *pThruster = pThrusters+i;
|
|
pList[numElem].pThruster = pThruster;
|
|
pList[numElem].pos = pVtx[pThruster->pos];
|
|
pList[numElem].dir = pVtx[pThruster->dir&0xff];
|
|
VecAdd(&pState->campos, &pList[numElem].pos, &tv);
|
|
pList[numElem].dist = VecDot(&tv, &tv);
|
|
|
|
if(pThruster->dir & THRUST_XREF) {
|
|
pList[numElem+1] = pList[numElem];
|
|
pList[numElem+1].pos.x = -pList[numElem].pos.x;
|
|
pList[numElem+1].dir.x = -pList[numElem].dir.x;
|
|
VecAdd(&pState->campos, &pList[numElem+1].pos, &tv);
|
|
pList[numElem+1].dist = VecDot(&tv, &tv);
|
|
numElem++;
|
|
}
|
|
numElem++;
|
|
}
|
|
|
|
QuickSort(pList, numElem-1);
|
|
|
|
// for(i=numElem-1; i>=0; i--)
|
|
for(i=0; i<numElem; i++) {
|
|
RenderThruster(pState, pList[i].pThruster, &pList[i].pos, &pList[i].dir);
|
|
}
|
|
}
|
|
|