mirror of
https://github.com/aap/librw.git
synced 2025-12-20 09:29:49 +00:00
fixed sky mipmap stream write; experimented with software pipeline
This commit is contained in:
661
tools/clumpview/tl_tests.cpp
Normal file
661
tools/clumpview/tl_tests.cpp
Normal file
@@ -0,0 +1,661 @@
|
||||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
extern bool dosoftras;
|
||||
|
||||
using namespace rw;
|
||||
using namespace RWDEVICE;
|
||||
|
||||
//
|
||||
// This is a test to implement T&L in software and render with Im2D
|
||||
//
|
||||
|
||||
namespace gen {
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
struct Directional {
|
||||
V3d at;
|
||||
RGBAf color;
|
||||
};
|
||||
static Directional directionals[MAX_LIGHTS];
|
||||
static int32 numDirectionals;
|
||||
static RGBAf ambLight;
|
||||
|
||||
static void
|
||||
enumLights(Matrix *lightmat)
|
||||
{
|
||||
int32 n;
|
||||
World *world;
|
||||
|
||||
world = (World*)engine->currentWorld;
|
||||
ambLight.red = 0.0;
|
||||
ambLight.green = 0.0;
|
||||
ambLight.blue = 0.0;
|
||||
ambLight.alpha = 0.0;
|
||||
numDirectionals = 0;
|
||||
// only unpositioned lights right now
|
||||
FORLIST(lnk, world->directionalLights){
|
||||
Light *l = Light::fromWorld(lnk);
|
||||
if(l->getType() == Light::DIRECTIONAL){
|
||||
if(numDirectionals >= MAX_LIGHTS)
|
||||
continue;
|
||||
n = numDirectionals++;
|
||||
V3d::transformVectors(&directionals[n].at, &l->getFrame()->getLTM()->at, 1, lightmat);
|
||||
directionals[n].color = l->color;
|
||||
directionals[n].color.alpha = 0.0f;
|
||||
}else if(l->getType() == Light::AMBIENT){
|
||||
ambLight.red += l->color.red;
|
||||
ambLight.green += l->color.green;
|
||||
ambLight.blue += l->color.blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ObjSpace3DVertex
|
||||
{
|
||||
V3d objVertex;
|
||||
V3d objNormal;
|
||||
RGBA color;
|
||||
TexCoords texCoords;
|
||||
};
|
||||
|
||||
enum {
|
||||
CLIPXLO = 0x01,
|
||||
CLIPXHI = 0x02,
|
||||
CLIPX = 0x03,
|
||||
CLIPYLO = 0x04,
|
||||
CLIPYHI = 0x08,
|
||||
CLIPY = 0x0C,
|
||||
CLIPZLO = 0x10,
|
||||
CLIPZHI = 0x20,
|
||||
CLIPZ = 0x30,
|
||||
};
|
||||
|
||||
struct CamSpace3DVertex
|
||||
{
|
||||
V3d camVertex;
|
||||
uint8 clipFlags;
|
||||
RGBAf color;
|
||||
TexCoords texCoords;
|
||||
};
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
uint16 *indices;
|
||||
int32 numIndices;
|
||||
ObjSpace3DVertex *vertices;
|
||||
int32 numVertices;
|
||||
// int vertStride; // not really needed right now
|
||||
Material *material;
|
||||
Mesh *mesh;
|
||||
};
|
||||
|
||||
struct InstanceDataHeader : public rw::InstanceDataHeader
|
||||
{
|
||||
uint32 serialNumber;
|
||||
ObjSpace3DVertex *vertices;
|
||||
uint16 *indices;
|
||||
InstanceData *inst;
|
||||
};
|
||||
|
||||
static void
|
||||
instanceAtomic(Atomic *atomic)
|
||||
{
|
||||
static V3d zeroNorm = { 0.0f, 0.0f, 0.0f };
|
||||
static RGBA black = { 0, 0, 0, 255 };
|
||||
static TexCoords zeroTex = { 0.0f, 0.0f };
|
||||
int i;
|
||||
uint j;
|
||||
int x, x1, x2, x3;
|
||||
Geometry *geo;
|
||||
MeshHeader *header;
|
||||
Mesh *mesh;
|
||||
InstanceDataHeader *insthead;
|
||||
InstanceData *inst;
|
||||
uint32 firstVert;
|
||||
uint16 *srcindices, *dstindices;
|
||||
|
||||
geo = atomic->geometry;
|
||||
if(geo->instData)
|
||||
return;
|
||||
header = geo->meshHeader;
|
||||
int numTris;
|
||||
if(header->flags & MeshHeader::TRISTRIP)
|
||||
numTris = header->totalIndices - 2*header->numMeshes;
|
||||
else
|
||||
numTris = header->totalIndices / 3;
|
||||
int size;
|
||||
size = sizeof(InstanceDataHeader) + header->numMeshes*sizeof(InstanceData) +
|
||||
geo->numVertices*sizeof(ObjSpace3DVertex) + numTris*6*sizeof(uint16);
|
||||
insthead = (InstanceDataHeader*)rwNew(size, ID_GEOMETRY);
|
||||
geo->instData = insthead;
|
||||
insthead->platform = 0;
|
||||
insthead->serialNumber = header->serialNum;
|
||||
inst = (InstanceData*)(insthead+1);
|
||||
insthead->inst = inst;
|
||||
insthead->vertices = (ObjSpace3DVertex*)(inst+header->numMeshes);
|
||||
dstindices = (uint16*)(insthead->vertices+geo->numVertices);
|
||||
insthead->indices = dstindices;
|
||||
|
||||
// TODO: morphing
|
||||
MorphTarget *mt = geo->morphTargets;
|
||||
for(i = 0; i < geo->numVertices; i++){
|
||||
insthead->vertices[i].objVertex = mt->vertices[i];
|
||||
if(geo->flags & Geometry::NORMALS)
|
||||
insthead->vertices[i].objNormal = mt->normals[i];
|
||||
else
|
||||
insthead->vertices[i].objNormal = zeroNorm;
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
insthead->vertices[i].color = geo->colors[i];
|
||||
else
|
||||
insthead->vertices[i].color = black;
|
||||
if(geo->numTexCoordSets > 0)
|
||||
insthead->vertices[i].texCoords = geo->texCoords[0][i];
|
||||
else
|
||||
insthead->vertices[i].texCoords = zeroTex;
|
||||
}
|
||||
|
||||
mesh = header->getMeshes();
|
||||
for(i = 0; i < header->numMeshes; i++){
|
||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||
&firstVert, &inst->numVertices);
|
||||
inst->indices = dstindices;
|
||||
inst->vertices = &insthead->vertices[firstVert];
|
||||
inst->mesh = mesh;
|
||||
inst->material = mesh->material;
|
||||
srcindices = mesh->indices;
|
||||
if(header->flags & MeshHeader::TRISTRIP){
|
||||
inst->numIndices = 0;
|
||||
x = 0;
|
||||
for(j = 0; j < mesh->numIndices-2; j++){
|
||||
x1 = srcindices[j+x];
|
||||
x ^= 1;
|
||||
x2 = srcindices[j+x];
|
||||
x3 = srcindices[j+2];
|
||||
if(x1 != x2 && x2 != x3 && x1 != x3){
|
||||
dstindices[0] = x1;
|
||||
dstindices[1] = x2;
|
||||
dstindices[2] = x3;
|
||||
dstindices += 3;
|
||||
inst->numIndices += 3;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
inst->numIndices = mesh->numIndices;
|
||||
for(j = 0; j < mesh->numIndices; j += 3){
|
||||
dstindices[0] = srcindices[j+0] - firstVert;
|
||||
dstindices[1] = srcindices[j+1] - firstVert;
|
||||
dstindices[2] = srcindices[j+2] - firstVert;
|
||||
dstindices += 3;
|
||||
}
|
||||
}
|
||||
|
||||
inst++;
|
||||
mesh++;
|
||||
}
|
||||
}
|
||||
|
||||
struct MeshState
|
||||
{
|
||||
int32 flags;
|
||||
Matrix obj2cam;
|
||||
Matrix obj2world;
|
||||
int32 numVertices;
|
||||
int32 numPrimitives;
|
||||
SurfaceProperties surfProps;
|
||||
RGBA matCol;
|
||||
};
|
||||
|
||||
static void
|
||||
cam2screen(Im2DVertex *scrvert, CamSpace3DVertex *camvert)
|
||||
{
|
||||
RGBA col;
|
||||
float32 recipZ;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
int32 width = cam->frameBuffer->width;
|
||||
int32 height = cam->frameBuffer->height;
|
||||
recipZ = 1.0f/camvert->camVertex.z;
|
||||
|
||||
scrvert->setScreenX(camvert->camVertex.x * recipZ * width);
|
||||
scrvert->setScreenY(camvert->camVertex.y * recipZ * height);
|
||||
// scrvert->setScreenX(camvert->camVertex.x * recipZ * width/2 + width/4);
|
||||
// scrvert->setScreenY(camvert->camVertex.y * recipZ * height/2 + height/4);
|
||||
scrvert->setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
scrvert->setCameraZ(camvert->camVertex.z);
|
||||
scrvert->setRecipCameraZ(recipZ);
|
||||
scrvert->setU(camvert->texCoords.u, recipZ);
|
||||
scrvert->setV(camvert->texCoords.v, recipZ);
|
||||
convColor(&col, &camvert->color);
|
||||
scrvert->setColor(col.red, col.green, col.blue, col.alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
transform(MeshState *mstate, ObjSpace3DVertex *objverts, CamSpace3DVertex *camverts, Im2DVertex *scrverts)
|
||||
{
|
||||
int32 i;
|
||||
float32 z;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
for(i = 0; i < mstate->numVertices; i++){
|
||||
V3d::transformPoints(&camverts[i].camVertex, &objverts[i].objVertex, 1, &mstate->obj2cam);
|
||||
convColor(&camverts[i].color, &objverts[i].color);
|
||||
camverts[i].texCoords = objverts[i].texCoords;
|
||||
|
||||
camverts[i].clipFlags = 0;
|
||||
z = camverts[i].camVertex.z;
|
||||
// 0 < x < z
|
||||
if(camverts[i].camVertex.x >= z) camverts[i].clipFlags |= CLIPXHI;
|
||||
if(camverts[i].camVertex.x <= 0) camverts[i].clipFlags |= CLIPXLO;
|
||||
// 0 < y < z
|
||||
if(camverts[i].camVertex.y >= z) camverts[i].clipFlags |= CLIPYHI;
|
||||
if(camverts[i].camVertex.y <= 0) camverts[i].clipFlags |= CLIPYLO;
|
||||
// near < z < far
|
||||
if(z >= cam->farPlane) camverts[i].clipFlags |= CLIPZHI;
|
||||
if(z <= cam->nearPlane) camverts[i].clipFlags |= CLIPZLO;
|
||||
|
||||
cam2screen(&scrverts[i], &camverts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
light(MeshState *mstate, ObjSpace3DVertex *objverts, CamSpace3DVertex *camverts)
|
||||
{
|
||||
int32 i;
|
||||
RGBAf colf;
|
||||
RGBAf amb = ambLight;
|
||||
amb = scale(ambLight, mstate->surfProps.ambient);
|
||||
for(i = 0; i < mstate->numVertices; i++){
|
||||
camverts[i].color = add(camverts[i].color, amb);
|
||||
if((mstate->flags & Geometry::NORMALS) == 0)
|
||||
continue;
|
||||
for(int32 k = 0; k < numDirectionals; k++){
|
||||
float32 f = dot(objverts[i].objNormal, neg(directionals[k].at));
|
||||
if(f <= 0.0f) continue;
|
||||
f *= mstate->surfProps.diffuse;
|
||||
colf = scale(directionals[k].color, f);
|
||||
camverts[i].color = add(camverts[i].color, colf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
postlight(MeshState *mstate, CamSpace3DVertex *camverts, Im2DVertex *scrverts)
|
||||
{
|
||||
int32 i;
|
||||
RGBA col;
|
||||
RGBAf colf;
|
||||
for(i = 0; i < mstate->numVertices; i++){
|
||||
convColor(&colf, &mstate->matCol);
|
||||
camverts[i].color = modulate(camverts[i].color, colf);
|
||||
clamp(&camverts[i].color);
|
||||
convColor(&col, &camverts[i].color);
|
||||
scrverts[i].setColor(col.red, col.green, col.blue, col.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static int32
|
||||
cullTriangles(MeshState *mstate, CamSpace3DVertex *camverts, uint16 *indices, uint16 *clipindices)
|
||||
{
|
||||
int32 i;
|
||||
int32 x1, x2, x3;
|
||||
int32 newNumPrims;
|
||||
int32 numClip;
|
||||
|
||||
newNumPrims = 0;
|
||||
numClip = 0;
|
||||
for(i = 0; i < mstate->numPrimitives; i++, indices += 3){
|
||||
x1 = indices[0];
|
||||
x2 = indices[1];
|
||||
x3 = indices[2];
|
||||
// Only a simple frustum call
|
||||
if(camverts[x1].clipFlags &
|
||||
camverts[x2].clipFlags &
|
||||
camverts[x3].clipFlags)
|
||||
continue;
|
||||
if(camverts[x1].clipFlags |
|
||||
camverts[x2].clipFlags |
|
||||
camverts[x3].clipFlags)
|
||||
numClip++;
|
||||
// The Triangle is in, probably
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2;
|
||||
clipindices[2] = x3;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
}
|
||||
mstate->numPrimitives = newNumPrims;
|
||||
return numClip;
|
||||
}
|
||||
|
||||
static void
|
||||
interpVertex(CamSpace3DVertex *out, CamSpace3DVertex *v1, CamSpace3DVertex *v2, float32 t)
|
||||
{
|
||||
float32 z;
|
||||
float32 invt;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
invt = 1.0f - t;
|
||||
out->camVertex = add(scale(v1->camVertex, invt), scale(v2->camVertex, t));
|
||||
out->color = add(scale(v1->color, invt), scale(v2->color, t));
|
||||
out->texCoords.u = v1->texCoords.u*invt + v2->texCoords.u*t;
|
||||
out->texCoords.v = v1->texCoords.v*invt + v2->texCoords.v*t;
|
||||
|
||||
out->clipFlags = 0;
|
||||
z = out->camVertex.z;
|
||||
// 0 < x < z
|
||||
if(out->camVertex.x >= z) out->clipFlags |= CLIPXHI;
|
||||
if(out->camVertex.x <= 0) out->clipFlags |= CLIPXLO;
|
||||
// 0 < y < z
|
||||
if(out->camVertex.y >= z) out->clipFlags |= CLIPYHI;
|
||||
if(out->camVertex.y <= 0) out->clipFlags |= CLIPYLO;
|
||||
// near < z < far
|
||||
if(z >= cam->farPlane) out->clipFlags |= CLIPZHI;
|
||||
if(z <= cam->nearPlane) out->clipFlags |= CLIPZLO;
|
||||
}
|
||||
|
||||
static void
|
||||
clipTriangles(MeshState *mstate, CamSpace3DVertex *camverts, Im2DVertex *scrverts, uint16 *indices, uint16 *clipindices)
|
||||
{
|
||||
int32 i, j;
|
||||
int32 x1, x2, x3;
|
||||
int32 newNumPrims;
|
||||
CamSpace3DVertex buf[18];
|
||||
CamSpace3DVertex *in, *out, *tmp;
|
||||
int32 nin, nout;
|
||||
float32 t;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
newNumPrims = 0;
|
||||
for(i = 0; i < mstate->numPrimitives; i++, indices += 3){
|
||||
x1 = indices[0];
|
||||
x2 = indices[1];
|
||||
x3 = indices[2];
|
||||
|
||||
if((camverts[x1].clipFlags |
|
||||
camverts[x2].clipFlags |
|
||||
camverts[x3].clipFlags) == 0){
|
||||
// all inside
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2;
|
||||
clipindices[2] = x3;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// set up triangle
|
||||
in = &buf[0];
|
||||
out = &buf[9];
|
||||
in[0] = camverts[x1];
|
||||
in[1] = camverts[x2];
|
||||
in[2] = camverts[x3];
|
||||
nin = 3;
|
||||
nout = 0;
|
||||
|
||||
#define V(a) in[a].camVertex.
|
||||
|
||||
// clip z near
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPZLO){
|
||||
t = (cam->nearPlane - V(x1)z)/(V(x2)z - V(x1)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPZLO) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip z far
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPZHI){
|
||||
t = (cam->farPlane - V(x1)z)/(V(x2)z - V(x1)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPZHI) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip y 0
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPYLO){
|
||||
t = -V(x1)y/(V(x2)y - V(x1)y);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPYLO) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip y z
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPYHI){
|
||||
t = (V(x1)z - V(x1)y)/(V(x1)z - V(x1)y + V(x2)y - V(x2)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPYHI) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip x 0
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPXLO){
|
||||
t = -V(x1)x/(V(x2)x - V(x1)x);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPXLO) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip x z
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPXHI){
|
||||
t = (V(x1)z - V(x1)x)/(V(x1)z - V(x1)x + V(x2)x - V(x2)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPXHI) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
|
||||
// Insert new triangles
|
||||
x1 = mstate->numVertices;
|
||||
for(j = 0; j < nout; j++){
|
||||
x2 = mstate->numVertices++;
|
||||
camverts[x2] = out[j];
|
||||
cam2screen(&scrverts[x2], &camverts[x2]);
|
||||
}
|
||||
x2 = x1+1;
|
||||
for(j = 0; j < nout-2; j++){
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2++;
|
||||
clipindices[2] = x2;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
}
|
||||
}
|
||||
mstate->numPrimitives = newNumPrims;
|
||||
}
|
||||
|
||||
static void
|
||||
submitTriangles(RWDEVICE::Im2DVertex *scrverts, int32 numVerts, uint16 *indices, int32 numTris)
|
||||
{
|
||||
void rastest_renderTriangles(RWDEVICE::Im2DVertex *scrverts, int32 verts, uint16 *indices, int32 numTris);
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||
if(dosoftras)
|
||||
rastest_renderTriangles(scrverts, numVerts, indices, numTris);
|
||||
else{
|
||||
//int i;
|
||||
//for(i = 0; i < numVerts; i++){
|
||||
// scrverts[i].x = (int)(scrverts[i].x*16.0f) / 16.0f;
|
||||
// scrverts[i].y = (int)(scrverts[i].y*16.0f) / 16.0f;
|
||||
//}
|
||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, scrverts, numVerts,
|
||||
indices, numTris*3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
drawMesh(MeshState *mstate, ObjSpace3DVertex *objverts, uint16 *indices)
|
||||
{
|
||||
CamSpace3DVertex *camverts;
|
||||
Im2DVertex *scrverts;
|
||||
uint16 *cullindices, *clipindices;
|
||||
uint32 numClip;
|
||||
|
||||
camverts = rwNewT(CamSpace3DVertex, mstate->numVertices, MEMDUR_FUNCTION);
|
||||
scrverts = rwNewT(Im2DVertex, mstate->numVertices, MEMDUR_FUNCTION);
|
||||
cullindices = rwNewT(uint16, mstate->numPrimitives*3, MEMDUR_FUNCTION);
|
||||
|
||||
transform(mstate, objverts, camverts, scrverts);
|
||||
|
||||
numClip = cullTriangles(mstate, camverts, indices, cullindices);
|
||||
|
||||
// int32 i;
|
||||
// for(i = 0; i < mstate->numVertices; i++){
|
||||
// if(camverts[i].clipFlags & CLIPX)
|
||||
// camverts[i].color.red = 255;
|
||||
// if(camverts[i].clipFlags & CLIPY)
|
||||
// camverts[i].color.green = 255;
|
||||
// if(camverts[i].clipFlags & CLIPZ)
|
||||
// camverts[i].color.blue = 255;
|
||||
// }
|
||||
|
||||
light(mstate, objverts, camverts);
|
||||
|
||||
// mstate->matCol.red = 255;
|
||||
// mstate->matCol.green = 255;
|
||||
// mstate->matCol.blue = 255;
|
||||
|
||||
postlight(mstate, camverts, scrverts);
|
||||
|
||||
// each triangle can have a maximum of 9 vertices (7 triangles) after clipping
|
||||
// so resize to whatever we may need
|
||||
camverts = rwResizeT(CamSpace3DVertex, camverts, mstate->numVertices + numClip*9, MEMDUR_FUNCTION);
|
||||
scrverts = rwResizeT(Im2DVertex, scrverts, mstate->numVertices + numClip*9, MEMDUR_FUNCTION);
|
||||
clipindices = rwNewT(uint16, mstate->numPrimitives*3 + numClip*7*3, MEMDUR_FUNCTION);
|
||||
|
||||
clipTriangles(mstate, camverts, scrverts, cullindices, clipindices);
|
||||
|
||||
submitTriangles(scrverts, mstate->numVertices, clipindices, mstate->numPrimitives);
|
||||
|
||||
rwFree(camverts);
|
||||
rwFree(scrverts);
|
||||
rwFree(cullindices);
|
||||
rwFree(clipindices);
|
||||
}
|
||||
|
||||
static void
|
||||
drawAtomic(Atomic *atomic)
|
||||
{
|
||||
MeshState mstate;
|
||||
Matrix lightmat;
|
||||
Geometry *geo;
|
||||
MeshHeader *header;
|
||||
InstanceData *inst;
|
||||
int i;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
instanceAtomic(atomic);
|
||||
|
||||
mstate.obj2world = *atomic->getFrame()->getLTM();
|
||||
mstate.obj2cam = mstate.obj2world;
|
||||
mstate.obj2cam.transform(&cam->viewMatrix, COMBINEPOSTCONCAT);
|
||||
Matrix::invert(&lightmat, &mstate.obj2world);
|
||||
enumLights(&lightmat);
|
||||
|
||||
geo = atomic->geometry;
|
||||
header = geo->meshHeader;
|
||||
inst = ((InstanceDataHeader*)geo->instData)->inst;
|
||||
for(i = 0; i < header->numMeshes; i++){
|
||||
mstate.flags = geo->flags;
|
||||
mstate.numVertices = inst->numVertices;
|
||||
mstate.numPrimitives = inst->numIndices / 3;
|
||||
mstate.surfProps = inst->material->surfaceProps;
|
||||
mstate.matCol = inst->material->color;
|
||||
drawMesh(&mstate, inst->vertices, inst->indices);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tlTest(Clump *clump)
|
||||
{
|
||||
FORLIST(lnk, clump->atomics){
|
||||
Atomic *a = Atomic::fromClump(lnk);
|
||||
drawAtomic(a);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Im2DVertex *clipverts;
|
||||
static int32 numClipverts;
|
||||
|
||||
void
|
||||
genIm3DTransform(void *vertices, int32 numVertices, Matrix *world)
|
||||
{
|
||||
Im3DVertex *objverts;
|
||||
V3d pos;
|
||||
Matrix xform;
|
||||
Camera *cam;
|
||||
int32 i;
|
||||
objverts = (Im3DVertex*)vertices;
|
||||
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
int32 width = cam->frameBuffer->width;
|
||||
int32 height = cam->frameBuffer->height;
|
||||
|
||||
|
||||
xform = cam->viewMatrix;
|
||||
if(world)
|
||||
xform.transform(world, COMBINEPRECONCAT);
|
||||
|
||||
clipverts = rwNewT(Im2DVertex, numVertices, MEMDUR_EVENT);
|
||||
numClipverts = numVertices;
|
||||
|
||||
for(i = 0; i < numVertices; i++){
|
||||
V3d::transformPoints(&pos, &objverts[i].position, 1, &xform);
|
||||
|
||||
float32 recipZ = 1.0f/pos.z;
|
||||
RGBA c = objverts[i].getColor();
|
||||
|
||||
clipverts[i].setScreenX(pos.x * recipZ * width);
|
||||
clipverts[i].setScreenY(pos.y * recipZ * height);
|
||||
clipverts[i].setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
clipverts[i].setCameraZ(pos.z);
|
||||
clipverts[i].setRecipCameraZ(recipZ);
|
||||
clipverts[i].setColor(c.red, c.green, c.blue, c.alpha);
|
||||
clipverts[i].setU(objverts[i].u, recipZ);
|
||||
clipverts[i].setV(objverts[i].v, recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
genIm3DRenderIndexed(PrimitiveType prim, void *indices, int32 numIndices)
|
||||
{
|
||||
im2d::RenderIndexedPrimitive(prim, clipverts, numClipverts, indices, numIndices);
|
||||
}
|
||||
|
||||
void
|
||||
genIm3DEnd(void)
|
||||
{
|
||||
rwFree(clipverts);
|
||||
clipverts = nil;
|
||||
numClipverts = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user