mirror of
https://github.com/aap/librw.git
synced 2025-12-18 16:39:51 +00:00
implemented im2d for d3d, fun little software T&L renderer
This commit is contained in:
@@ -13,8 +13,8 @@ void
|
||||
Camera::update(void)
|
||||
{
|
||||
if(m_rwcam){
|
||||
m_rwcam->nearPlane = m_near;
|
||||
m_rwcam->farPlane = m_far;
|
||||
m_rwcam->setNearPlane(m_near);
|
||||
m_rwcam->setFarPlane(m_far);
|
||||
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
||||
|
||||
rw::Frame *f = m_rwcam->getFrame();
|
||||
|
||||
@@ -5,10 +5,16 @@
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
Camera *camera;
|
||||
rw::Clump *clump;
|
||||
rw::World *world;
|
||||
struct SceneGlobals {
|
||||
rw::World *world;
|
||||
rw::Camera *camera;
|
||||
rw::Clump *clump;
|
||||
} Scene;
|
||||
rw::Texture *tex;
|
||||
rw::EngineStartParams engineStartParams;
|
||||
|
||||
void tlTest(rw::Clump *clump);
|
||||
|
||||
void
|
||||
Init(void)
|
||||
{
|
||||
@@ -152,6 +158,8 @@ InitRW(void)
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
tex = rw::Texture::read("maze", nil);
|
||||
|
||||
char *filename = "teapot.dff";
|
||||
if(sk::args.argc > 1)
|
||||
filename = sk::args.argv[1];
|
||||
@@ -161,31 +169,43 @@ InitRW(void)
|
||||
return false;
|
||||
}
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
assert(clump);
|
||||
Scene.clump = rw::Clump::streamRead(&in);
|
||||
assert(Scene.clump);
|
||||
in.close();
|
||||
|
||||
clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||
// TEST - Set texture to the all materials of the clump
|
||||
FORLIST(lnk, Scene.clump->atomics){
|
||||
rw::Atomic *a = rw::Atomic::fromClump(lnk);
|
||||
for(int i = 0; i < a->geometry->matList.numMaterials; i++)
|
||||
a->geometry->matList.materials[i]->setTexture(tex);
|
||||
}
|
||||
|
||||
dumpUserData(clump);
|
||||
setupClump(clump);
|
||||
Scene.clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||
|
||||
world = rw::World::create();
|
||||
dumpUserData(Scene.clump);
|
||||
setupClump(Scene.clump);
|
||||
|
||||
Scene.world = rw::World::create();
|
||||
|
||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||
ambient->setColor(0.2f, 0.2f, 0.2f);
|
||||
world->addLight(ambient);
|
||||
Scene.world->addLight(ambient);
|
||||
|
||||
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
||||
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||
direct->setFrame(rw::Frame::create());
|
||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||
world->addLight(direct);
|
||||
Scene.world->addLight(direct);
|
||||
|
||||
camera = new Camera;
|
||||
camera->m_rwcam = rw::Camera::create();
|
||||
camera->m_rwcam->setFrame(rw::Frame::create());
|
||||
Scene.camera = rw::Camera::create();
|
||||
camera->m_rwcam = Scene.camera;
|
||||
Scene.camera->frameBuffer =
|
||||
rw::Raster::create(sk::globals.width, sk::globals.height, 0, rw::Raster::CAMERA);
|
||||
Scene.camera->zBuffer =
|
||||
rw::Raster::create(sk::globals.width, sk::globals.height, 0, rw::Raster::ZBUFFER);
|
||||
Scene.camera->setFrame(rw::Frame::create());
|
||||
camera->m_aspectRatio = 640.0f/480.0f;
|
||||
camera->m_near = 0.1f;
|
||||
camera->m_far = 450.0f;
|
||||
@@ -196,7 +216,7 @@ InitRW(void)
|
||||
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||
camera->update();
|
||||
|
||||
world->addCamera(camera->m_rwcam);
|
||||
Scene.world->addCamera(camera->m_rwcam);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -204,15 +224,37 @@ InitRW(void)
|
||||
void
|
||||
im2dtest(void)
|
||||
{
|
||||
static rw::gl3::Im2DVertex verts[] = {
|
||||
{ -0.5, -0.5, 0.0, 255, 0, 0, 255, 0.0, 0.0 },
|
||||
{ 0.5, -0.5, 0.0, 0, 255, 0, 255, 0.0, 0.0 },
|
||||
{ -0.5, 0.5, 0.0, 0, 0, 255, 255, 0.0, 0.0 },
|
||||
{ 0.5, 0.5, 0.0, 0, 255, 255, 255, 0.0, 0.0 },
|
||||
using namespace rw::RWDEVICE;
|
||||
int i;
|
||||
static struct
|
||||
{
|
||||
float x, y;
|
||||
rw::uint8 r, g, b, a;
|
||||
float u, v;
|
||||
} vs[4] = {
|
||||
{ 0.0f, 0.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||
{ 640.0f, 0.0f, 0, 255, 0, 128, 1.0f, 0.0f },
|
||||
{ 0.0f, 480.0f, 0, 0, 255, 128, 0.0f, 1.0f },
|
||||
{ 640.0f, 480.0f, 0, 255, 255, 128, 1.0f, 1.0f },
|
||||
};
|
||||
static Im2DVertex verts[4];
|
||||
static short indices[] = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
||||
for(i = 0; i < 4; i++){
|
||||
verts[i].setScreenX(vs[i].x);
|
||||
verts[i].setScreenY(vs[i].y);
|
||||
verts[i].setScreenZ(rw::GetNearZ());
|
||||
verts[i].setCameraZ(Scene.camera->nearPlane);
|
||||
verts[i].setRecipCameraZ(1.0f/Scene.camera->nearPlane);
|
||||
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||
verts[i].setU(vs[i].u);
|
||||
verts[i].setV(vs[i].v);
|
||||
}
|
||||
|
||||
rw::engine->imtexture = tex;
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
&verts, 4, &indices, 4);
|
||||
}
|
||||
@@ -225,8 +267,9 @@ Draw(float timeDelta)
|
||||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
clump->render();
|
||||
Scene.clump->render();
|
||||
im2dtest();
|
||||
// tlTest(Scene.clump);
|
||||
|
||||
camera->m_rwcam->endUpdate();
|
||||
camera->m_rwcam->showRaster();
|
||||
|
||||
BIN
tools/clumpview/maze.tga
Normal file
BIN
tools/clumpview/maze.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
134
tools/clumpview/tests.cpp
Normal file
134
tools/clumpview/tests.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
using namespace rw;
|
||||
|
||||
//
|
||||
// This is a test to implement T&L in software and render with Im2D
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drawAtomic(Atomic *a)
|
||||
{
|
||||
using namespace RWDEVICE;
|
||||
Im2DVertex *im2dverts;
|
||||
V3d *xvert;
|
||||
Matrix xform;
|
||||
Matrix lightmat;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
Geometry *g = a->geometry;
|
||||
MeshHeader *mh = g->meshHeader;
|
||||
Mesh *m = mh->getMeshes();
|
||||
int32 width = cam->frameBuffer->width;
|
||||
int32 height = cam->frameBuffer->height;
|
||||
RGBA *prelight;
|
||||
V3d *normals;
|
||||
TexCoords *texcoords;
|
||||
|
||||
Matrix::mult(&xform, a->getFrame()->getLTM(), &cam->viewMatrix);
|
||||
Matrix::invert(&lightmat, a->getFrame()->getLTM());
|
||||
|
||||
enumLights(&lightmat);
|
||||
|
||||
xvert = rwNewT(V3d, g->numVertices, MEMDUR_FUNCTION);
|
||||
im2dverts = rwNewT(Im2DVertex, g->numVertices, MEMDUR_FUNCTION);
|
||||
|
||||
prelight = g->colors;
|
||||
normals = g->morphTargets[0].normals;
|
||||
texcoords = g->texCoords[0];
|
||||
|
||||
V3d::transformPoints(xvert, g->morphTargets[0].vertices, g->numVertices, &xform);
|
||||
for(int32 i = 0; i < g->numVertices; i++){
|
||||
float32 recipZ = 1.0f/xvert[i].z;
|
||||
|
||||
im2dverts[i].setScreenX(xvert[i].x * recipZ * width);
|
||||
im2dverts[i].setScreenY((xvert[i].y * recipZ * height));
|
||||
im2dverts[i].setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
im2dverts[i].setCameraZ(xvert[i].z);
|
||||
im2dverts[i].setRecipCameraZ(recipZ);
|
||||
im2dverts[i].setColor(255, 0, 0, 255);
|
||||
im2dverts[i].setU(texcoords[i].u);
|
||||
im2dverts[i].setV(texcoords[i].v);
|
||||
}
|
||||
for(int32 i = 0; i < mh->numMeshes; i++){
|
||||
for(int32 j = 0; j < m[i].numIndices; j++){
|
||||
int32 idx = m[i].indices[j];
|
||||
RGBA col;
|
||||
RGBAf colf, color;
|
||||
if(prelight)
|
||||
convColor(&color, &prelight[idx]);
|
||||
else{
|
||||
color.red = color.green = color.blue = 0.0f;
|
||||
color.alpha = 1.0f;
|
||||
}
|
||||
color = add(color, ambLight);
|
||||
if(normals)
|
||||
for(int32 k = 0; k < numDirectionals; k++){
|
||||
float32 f = dot(normals[idx], neg(directionals[k].at));
|
||||
if(f <= 0.0f) continue;
|
||||
colf = scale(directionals[k].color, f);
|
||||
color = add(color, colf);
|
||||
}
|
||||
convColor(&colf, &m[i].material->color);
|
||||
color = modulate(color, colf);
|
||||
clamp(&color);
|
||||
convColor(&col, &color);
|
||||
im2dverts[idx].setColor(col.red, col.green, col.blue, col.alpha);
|
||||
}
|
||||
|
||||
engine->imtexture = m[i].material->texture;
|
||||
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
|
||||
}
|
||||
|
||||
rwFree(xvert);
|
||||
rwFree(im2dverts);
|
||||
}
|
||||
|
||||
void
|
||||
tlTest(Clump *clump)
|
||||
{
|
||||
FORLIST(lnk, clump->atomics){
|
||||
Atomic *a = Atomic::fromClump(lnk);
|
||||
drawAtomic(a);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user