#include "inc.h" using namespace rw; using namespace rw; float angle = 0.0f; //float angle = 90.0f; //float angle = 90.0197f; //float angle = 147.5f; //float angle = 152.0f; //float angle = 187.5f; //float pos = -7.0f; float pos = 0.0f; //float pos = 0.0f; float yaw, pitch; rw::V3d xaxis = { 1.0f, 0.0f, 0.0f }; rw::V3d yaxis = { 0.0f, 1.0f, 0.0f }; rw::V3d zaxis = { 0.0f, 0.0f, 1.0f }; rw::Matrix worldMat; void modeltest(void) { /* worldMat.rotate(&xaxis, angle, rw::COMBINEREPLACE); worldMat.rotate(&yaxis, angle); worldMat.rotate(&zaxis, angle); angle += 0.5f; rw::V3d trans = yaxis; trans.y = pos; worldMat.translate(&trans); rw::Atomic *atm = nil; FORLIST(lnk, Scene.clump->atomics){ atm = rw::Atomic::fromClump(lnk); break; } if(atm){ atm->getFrame()->transform(&worldMat, rw::COMBINEREPLACE); } */ rw::SetRenderState(rw::ZTESTENABLE, 1); if(Scene.backgroundClump) Scene.backgroundClump->render(); Scene.clump->render(); } void applyLight(rw::Light *light, rw::Matrix *mat, rw::V3d *pos, rw::V3d *norm, rw::RGBAf *color) { switch(light->getType()){ case rw::Light::AMBIENT: *color = rw::add(*color, light->color); break; case rw::Light::DIRECTIONAL: if(norm){ rw::V3d n; rw::V3d::transformVectors(&n, norm, 1, mat); float l = -dot(n, light->getFrame()->getLTM()->at); if(l < 0.0f) l = 0.0f; *color = rw::add(*color, rw::scale(light->color, l)); } break; } } void im3dtest_2(void) { rw::Atomic *atm = nil; FORLIST(lnk, Scene.clump->atomics){ atm = rw::Atomic::fromClump(lnk); break; } if(atm == nil) return; rw::SetRenderState(rw::ZTESTENABLE, 1); worldMat.rotate(&xaxis, angle, rw::COMBINEREPLACE); worldMat.rotate(&yaxis, angle); worldMat.rotate(&zaxis, angle); angle += 0.5f; rw::V3d trans = yaxis; trans.y = pos; worldMat.translate(&trans); // pos -= 0.01f; // printf("pos: %f\n", pos); rw::RWDEVICE::Im3DVertex *verts; rw::Geometry *geo = atm->geometry; rw::MorphTarget *mt = &geo->morphTargets[0]; rw::TexCoords *tex = geo->texCoords[0]; verts = rwNewT(rw::RWDEVICE::Im3DVertex, geo->numVertices, rw::MEMDUR_EVENT); for(int i = 0; i < geo->numVertices; i++){ rw::V3d *v = &mt->vertices[i]; rw::V3d *n = mt->normals ? &mt->normals[i] : nil; // this is inefficient AS FUCK // rw::RGBAf color = { 1.0f, 1.0f, 1.0f, 1.0f }; rw::RGBAf color = { 0.0f, 0.0f, 0.0f, 1.0f }; applyLight(Scene.ambient, &worldMat, v, n, &color); applyLight(Scene.direct, &worldMat, v, n, &color); rw::clamp(&color); verts[i].setX(v->x); verts[i].setY(v->y); verts[i].setZ(v->z); verts[i].setColor((int)(color.red*255), (int)(color.green*255), (int)(color.blue*255), (int)(color.alpha*255)); if(tex){ verts[i].setU(tex[i].u); verts[i].setV(tex[i].v); }else{ verts[i].setU(0.0f); verts[i].setV(0.0f); } } rw::im3d::Transform(verts, geo->numVertices, &worldMat, rw::im3d::EVERYTHING); rw::MeshHeader *header = geo->meshHeader; rw::Mesh *m = header->getMeshes(); #if 1 rw::PrimitiveType type = header->flags == rw::MeshHeader::TRISTRIP ? rw::PRIMTYPETRISTRIP : rw::PRIMTYPETRILIST; for(int i = 0; i < header->numMeshes; i++){ if(m->material->texture) rw::SetRenderStatePtr(rw::TEXTURERASTER, m->material->texture->raster); else rw::SetRenderStatePtr(rw::TEXTURERASTER, nil); rw::im3d::RenderIndexedPrimitive(type, m->indices, m->numIndices); // rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPEPOINTLIST, m->indices, m->numIndices); // rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPEPOLYLINE, m->indices, m->numIndices); m++; } #else int numTris, inc; if(header->flags == rw::MeshHeader::TRISTRIP){ numTris = m->numIndices-2; inc = 1; }else{ numTris = m->numIndices/3; inc = 3; } for(int i = 0; i < header->numMeshes; i++){ if(m->material->texture) rw::SetRenderStatePtr(rw::TEXTURERASTER, m->material->texture->raster); else rw::SetRenderStatePtr(rw::TEXTURERASTER, nil); #if 1 int numActualTris = 0; uint16 *indices = rwNewT(uint16, numTris*6, 0); uint16 *src = m->indices; uint16 *dst = indices; for(int j = 0; j < numTris; j++){ if(src[0] != src[1] && src[0] != src[2] && src[1] != src[2]){ *dst++ = src[0]; *dst++ = src[1]; *dst++ = src[1]; *dst++ = src[2]; *dst++ = src[2]; *dst++ = src[0]; numActualTris++; } src += inc; } rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPELINELIST, indices, numActualTris*6); rwFree(indices); #else uint16 *indices = rwNewT(uint16, (m->numIndices-1)*2, 0); uint16 *src = m->indices; uint16 *dst = indices; for(int j = 0; j < m->numIndices-1; j++){ *dst++ = src[0]; *dst++ = src[1]; src++; } rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPELINELIST, indices, (m->numIndices-1)*2); rwFree(indices); #endif m++; } #endif rw::im3d::End(); rwFree(verts); } void im3dtest(void) { using namespace rw::RWDEVICE; int i; static struct { float x, y, z; rw::uint8 r, g, b, a; float u, v; } vs[8] = { { -1.0f, -1.0f, -1.0f, 255, 0, 0, 128, 0.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, 0, 255, 0, 128, 0.0f, 1.0f }, { 1.0f, -1.0f, -1.0f, 0, 0, 255, 128, 1.0f, 0.0f }, { 1.0f, 1.0f, -1.0f, 255, 0, 255, 128, 1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f, 255, 0, 0, 128, 0.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, 0, 255, 0, 128, 0.0f, 1.0f }, { 1.0f, -1.0f, 1.0f, 0, 0, 255, 128, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 255, 0, 255, 128, 1.0f, 1.0f }, }; Im3DVertex verts[8]; static short indices[2*6] = { 0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7 }; for(i = 0; i < 8; i++){ verts[i].setX(vs[i].x); verts[i].setY(vs[i].y); verts[i].setZ(vs[i].z); 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::SetRenderStatePtr(rw::TEXTURERASTER, Scene.tex->raster); // rw::SetRenderStatePtr(rw::TEXTURERASTER, nil); rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP); rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST); rw::SetRenderState(rw::ZTESTENABLE, 1); worldMat.rotate(&xaxis, angle, rw::COMBINEREPLACE); worldMat.rotate(&yaxis, angle); worldMat.rotate(&zaxis, angle); angle += 0.5f; rw::im3d::Transform(verts, 8, &worldMat, rw::im3d::EVERYTHING); rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indices, 12); rw::im3d::End(); } struct Im2dBuffer { int numVerts; int numIndices; rw::RWDEVICE::Im2DVertex verts[1024]; int16 indices[1024]; }; void MakeQuad(Im2dBuffer *buf, float x1, float y1, float x2, float y2, float z, int r, int g, int b, int a) { rw::Camera *cam = rw::engine->currentCamera; float camZ = z; float recipZ = 1.0f/camZ; float screenZ = recipZ * cam->zScale + cam->zShift; rw::RWDEVICE::Im2DVertex *vs = &buf->verts[buf->numVerts]; int16 *is = &buf->indices[buf->numIndices]; vs[0].setScreenX(x1); vs[0].setScreenY(y1); vs[0].setScreenZ(screenZ); vs[0].setCameraZ(camZ); vs[0].setRecipCameraZ(recipZ); vs[0].setColor(r, g, b, a); vs[0].setU(-0.5f, recipZ); vs[0].setV(-0.5f, recipZ); vs[1].setScreenX(x2); vs[1].setScreenY(y1); vs[1].setScreenZ(screenZ); vs[1].setCameraZ(camZ); vs[1].setRecipCameraZ(recipZ); vs[1].setColor(r, g, b, a); vs[1].setU(1.5f, recipZ); vs[1].setV(-0.5f, recipZ); vs[2].setScreenX(x2); vs[2].setScreenY(y2); vs[2].setScreenZ(screenZ); vs[2].setCameraZ(camZ); vs[2].setRecipCameraZ(recipZ); vs[2].setColor(r, g, b, a); vs[2].setU(1.5f, recipZ); vs[2].setV(1.5f, recipZ); vs[3].setScreenX(x1); vs[3].setScreenY(y2); vs[3].setScreenZ(screenZ); vs[3].setCameraZ(camZ); vs[3].setRecipCameraZ(recipZ); vs[3].setColor(r, g, b, a); vs[3].setU(-0.5f, recipZ); vs[3].setV(1.5f, recipZ); is[0] = buf->numVerts + 0; is[1] = buf->numVerts + 1; is[2] = buf->numVerts + 2; is[3] = buf->numVerts + 0; is[4] = buf->numVerts + 2; is[5] = buf->numVerts + 3; buf->numVerts += 4; buf->numIndices += 6; } static Im2dBuffer buf; void im2dtest_4(void) { buf.numIndices = 0; buf.numVerts = 0; MakeQuad(&buf, 20, 20, 400, 400, 50.0f, 255, 255, 255, 255); MakeQuad(&buf, 100, 100, 500, 440, 51.0f, 0, 0, 255, 128); rw::SetRenderStatePtr(rw::TEXTURERASTER, nil); rw::SetRenderState(rw::VERTEXALPHA, 1); rw::SetRenderState(rw::BLENDSRCALPHA, rw::BLENDSRCALPHA); rw::SetRenderState(rw::BLENDDESTALPHA, rw::BLENDINVSRCALPHA); rw::SetRenderState(rw::ZTESTENABLE, 0); rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, &buf.verts, buf.numVerts, &buf.indices, buf.numIndices); } void im2dtest_3(void) { float z = rw::engine->currentCamera->nearPlane; buf.numIndices = 0; buf.numVerts = 0; MakeQuad(&buf, 20, 20, 400, 400, z, 255, 255, 255, 255); rw::SetRenderStatePtr(rw::TEXTURERASTER, Scene.tex->raster); rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::LINEAR); rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP); rw::SetRenderState(rw::VERTEXALPHA, 1); rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, &buf.verts, buf.numVerts, &buf.indices, buf.numIndices); } void im2dtest_2(void) { int i; int n = 50; int size = 50; float dx = (float)(SCREEN_WIDTH-20 - size)/(n-1); float dy = (float)(SCREEN_HEIGHT-20 - size)/(n-1); float x = 0.0f; float y = 0.0f; float z = rw::engine->currentCamera->nearPlane; float r = 255.0f; float g = 0.0f; float b = 0.0f; float a = 255.0f; float dc = 255.0f/(n-1); buf.numIndices = 0; buf.numVerts = 0; for(i = 0; i < n; i++){ MakeQuad(&buf, x, y, x+size, y+size, z, (int)r, (int)g, (int)b, (int)a); x += dx; y += dy; g += dc; a -= dc; } rw::SetRenderStatePtr(rw::TEXTURERASTER, Scene.tex->raster); rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::LINEAR); rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP); rw::SetRenderState(rw::VERTEXALPHA, 1); rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, &buf.verts, buf.numVerts, &buf.indices, buf.numIndices); } void im2dtest(void) { using namespace rw::RWDEVICE; int i; rw::Camera *cam = Scene.camera; float n = cam->nearPlane; float f = cam->farPlane; // float mid = (n+f)/4.0f; float mid = (n+f)/100.0f; struct { float x, y, z; rw::uint8 r, g, b, a; float u, v; } vs[4] = { { 0.5f, 0.5f, n, 0, 255, 0, 255, 0.0f, 0.0f }, { 0.5f, 0.5f, mid, 255, 0, 0, 255, 1.0f, 0.0f }, { 0.5f, -0.5f, n, 0, 255, 0, 255, 0.0f, 1.0f }, { 0.5f, -0.5f, mid, 255, 0, 0, 255, 1.0f, 1.0f }, }; Im2DVertex verts[4]; static short indices[] = { 0, 1, 2, 3 }; for(i = 0; i < 4; i++){ float recipZ = 1.0f/vs[i].z; verts[i].setScreenX((vs[i].x*recipZ + 0.5f) * SCREEN_WIDTH); verts[i].setScreenY((vs[i].y*recipZ + 0.5f) * SCREEN_HEIGHT); verts[i].setScreenZ(recipZ * cam->zScale + cam->zShift); verts[i].setCameraZ(vs[i].z); verts[i].setRecipCameraZ(recipZ); verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a); verts[i].setU(vs[i].u + 0.5f/SCREEN_WIDTH, recipZ); verts[i].setV(vs[i].v + 0.5f/SCREEN_HEIGHT, recipZ); } /* rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster); rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP); rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST); rw::SetRenderState(rw::VERTEXALPHA, 1); */ rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP, &verts, 4, &indices, 4); } void drawbg(void) { buf.numIndices = 0; buf.numVerts = 0; int width = SCREEN_WIDTH; int height = SCREEN_HEIGHT; MakeQuad(&buf, width/4, height/4, width/4 + width/2, height/4 + height/2, rw::engine->currentCamera->farPlane, 0, 0, 0, 255); rw::SetRenderStatePtr(rw::TEXTURERASTER, nil); rw::SetRenderState(rw::VERTEXALPHA, 0); rw::SetRenderState(rw::ZTESTENABLE, 0); rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, &buf.verts, buf.numVerts, &buf.indices, buf.numIndices); } void draw(void) { /* rw::SetRenderState(rw::FOGENABLE, 0); drawbg(); rw::SetRenderState(rw::FOGENABLE, 0); */ // im2dtest(); // im2dtest_2(); // im2dtest_3(); // im2dtest_4(); // rw::SetRenderState(rw::FOGENABLE, 1); // im3dtest(); // im3dtest_2(); modeltest(); }