diff --git a/src/anim.cpp b/src/anim.cpp index ee6e923..4bcd2ef 100644 --- a/src/anim.cpp +++ b/src/anim.cpp @@ -232,7 +232,9 @@ AnimInterpolator::setCurrentAnim(Animation *anim) kf2 = this->getAnimFrame(i+numNodes); intf->keyFrame1 = kf1; intf->keyFrame2 = kf2; - this->interpCB(intf, kf1, kf2, 0.0f, anim->customData); + // TODO: perhaps just implement all interpolator infos? + if(this->interpCB) + this->interpCB(intf, kf1, kf2, 0.0f, anim->customData); } this->nextFrame = this->getAnimFrame(numNodes*2); return 1; diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp index 4a4b782..2ecf781 100644 --- a/src/d3d/d3d.cpp +++ b/src/d3d/d3d.cpp @@ -421,6 +421,16 @@ rasterNumLevels(Raster *raster) void rasterFromImage(Raster *raster, Image *image) { + // Unpalettize image if necessary but don't change original + Image *truecolimg = nil; + if(image->depth <= 8 && !isP8supported){ + truecolimg = Image::create(image->width, image->height, image->depth); + truecolimg->pixels = image->pixels; + truecolimg->palette = image->palette; + truecolimg->unindex(); + image = truecolimg; + } + int32 format; D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); switch(image->depth){ @@ -502,6 +512,9 @@ rasterFromImage(Raster *raster, Image *image) break; } raster->unlock(0); + + if(truecolimg) + truecolimg->destroy(); } Image* diff --git a/src/d3d/d3d8.cpp b/src/d3d/d3d8.cpp index 7b41500..5227129 100644 --- a/src/d3d/d3d8.cpp +++ b/src/d3d/d3d8.cpp @@ -435,15 +435,22 @@ Raster* readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format, int32 numLevels) { uint8 palette[256*4]; + int32 pallen = 0; uint8 *data = nil; Image *img = Image::create(width, height, 32); img->allocate(); - if(format & Raster::PAL4) + if(format & Raster::PAL4){ + pallen = 16; stream->read(palette, 4*32); - else if(format & Raster::PAL8) + }else if(format & Raster::PAL8){ + pallen = 256; stream->read(palette, 4*256); + } + if(!Raster::formatHasAlpha(format)) + for(int32 i = 0; i < pallen; i++) + palette[i*4+3] = 0xFF; // Only read one mipmap for(int32 i = 0; i < numLevels; i++){ diff --git a/src/d3d/d3d9.cpp b/src/d3d/d3d9.cpp index f403abd..6be8429 100644 --- a/src/d3d/d3d9.cpp +++ b/src/d3d/d3d9.cpp @@ -533,6 +533,7 @@ defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header) uint8 *verts[2]; verts[0] = lockVertices(header->vertexStream[0].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); verts[1] = lockVertices(header->vertexStream[1].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + getDeclaration(header->vertexDeclaration, dcl); int i; for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++) diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp index ee4ddd2..8a6550a 100644 --- a/src/d3d/d3d9render.cpp +++ b/src/d3d/d3d9render.cpp @@ -23,11 +23,15 @@ void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) { RawMatrix world; - - d3d::lightingCB(); - Geometry *geo = atomic->geometry; - d3d::setRenderState(D3DRS_LIGHTING, !!(geo->flags & rw::Geometry::LIGHT)); + + int lighting = !!(geo->flags & rw::Geometry::LIGHT); + if(lighting) + d3d::lightingCB(); + else + return; + + d3d::setRenderState(D3DRS_LIGHTING, lighting); Frame *f = atomic->getFrame(); convMatrix(&world, f->getLTM()); @@ -42,12 +46,14 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) for(uint32 i = 0; i < header->numMeshes; i++){ d3d::setTexture(0, inst->material->texture); d3d::setMaterial(inst->material); + d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); if(geo->flags & Geometry::PRELIT) d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); else d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + d3d::flushCache(); d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, 0, inst->numVertices, diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index ecf1972..207c4fc 100755 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -328,6 +328,31 @@ setTexture(uint32 stage, Texture *tex) setRasterStage(stage, tex->raster); } +void +setD3dMaterial(D3DMATERIAL9 *mat9) +{ + if(d3dmaterial.Diffuse.r != mat9->Diffuse.r || + d3dmaterial.Diffuse.g != mat9->Diffuse.g || + d3dmaterial.Diffuse.b != mat9->Diffuse.b || + d3dmaterial.Diffuse.a != mat9->Diffuse.a || + d3dmaterial.Ambient.r != mat9->Ambient.r || + d3dmaterial.Ambient.g != mat9->Ambient.g || + d3dmaterial.Ambient.b != mat9->Ambient.b || + d3dmaterial.Ambient.a != mat9->Ambient.a || + d3dmaterial.Specular.r != mat9->Specular.r || + d3dmaterial.Specular.g != mat9->Specular.g || + d3dmaterial.Specular.b != mat9->Specular.b || + d3dmaterial.Specular.a != mat9->Specular.a || + d3dmaterial.Emissive.r != mat9->Emissive.r || + d3dmaterial.Emissive.g != mat9->Emissive.g || + d3dmaterial.Emissive.b != mat9->Emissive.b || + d3dmaterial.Emissive.a != mat9->Emissive.a || + d3dmaterial.Power != mat9->Power){ + d3ddevice->SetMaterial(mat9); + d3dmaterial = *mat9; + } +} + void setMaterial(Material *mat) { @@ -346,17 +371,7 @@ setMaterial(Material *mat) mat9.Power = 0.0f; mat9.Emissive = black; mat9.Specular = black; - if(d3dmaterial.Diffuse.r != mat9.Diffuse.r || - d3dmaterial.Diffuse.g != mat9.Diffuse.g || - d3dmaterial.Diffuse.b != mat9.Diffuse.b || - d3dmaterial.Diffuse.a != mat9.Diffuse.a || - d3dmaterial.Ambient.r != mat9.Ambient.r || - d3dmaterial.Ambient.g != mat9.Ambient.g || - d3dmaterial.Ambient.b != mat9.Ambient.b || - d3dmaterial.Ambient.a != mat9.Ambient.a){ - d3ddevice->SetMaterial(&mat9); - d3dmaterial = mat9; - } + setD3dMaterial(&mat9); } static void @@ -599,14 +614,20 @@ initD3D(void) // setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT); // Save the current states - for(s = 0; s < MAXNUMSTATES; s++) + for(s = 0; s < MAXNUMSTATES; s++){ d3ddevice->GetRenderState((D3DRENDERSTATETYPE)s, (DWORD*)&d3dStates[s]); + stateCache[s].value = d3dStates[s]; + } for(t = 0; t < MAXNUMSTATES; t++) - for(s = 0; s < MAXNUMSTAGES; s++) + for(s = 0; s < MAXNUMSTAGES; s++){ d3ddevice->GetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, (DWORD*)&d3dTextureStageStates[t][s]); + textureStageStateCache[t][s].value = d3dTextureStageStates[t][s]; + } for(t = 0; t < MAXNUMSAMPLERSTATES; t++) - for(s = 0; s < MAXNUMSTAGES; s++) + for(s = 0; s < MAXNUMSTAGES; s++){ d3ddevice->GetSamplerState(s, (D3DSAMPLERSTATETYPE)t, (DWORD*)&d3dSamplerStates[t][s]); + d3dSamplerStates[t][s] = d3dSamplerStates[t][s]; + } openIm2D(); openIm3D(); diff --git a/src/d3d/d3drender.cpp b/src/d3d/d3drender.cpp index 828b4ce..1f2cdad 100644 --- a/src/d3d/d3drender.cpp +++ b/src/d3d/d3drender.cpp @@ -44,6 +44,8 @@ lightingCB(void) // only unpositioned lights right now FORLIST(lnk, world->directionalLights){ Light *l = Light::fromWorld(lnk); + if((l->getFlags() & Light::LIGHTATOMICS) == 0) + continue; if(l->getType() == Light::DIRECTIONAL){ if(n >= MAX_LIGHTS) continue; diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h index 82aaa04..99af1d8 100644 --- a/src/d3d/rwd3d.h +++ b/src/d3d/rwd3d.h @@ -55,6 +55,8 @@ struct Im2DVertex void setV(float32 v) { this->v = v; } }; +void setD3dMaterial(D3DMATERIAL9 *mat9); + #else enum { D3DLOCK_NOSYSLOCK = 0, // ignored @@ -103,6 +105,7 @@ enum { D3DDECLUSAGE_DEPTH, // 12 D3DDECLUSAGE_SAMPLE, // 13 }; + #endif extern int vertFormatMap[]; @@ -141,8 +144,8 @@ void registerNativeRaster(void); void setRenderState(uint32 state, uint32 value); void setTextureStageState(uint32 stage, uint32 type, uint32 value); -void flushCache(void); void setSamplerState(uint32 stage, uint32 type, uint32 value); +void flushCache(void); void setTexture(uint32 stage, Texture *tex); void setMaterial(Material *mat); diff --git a/src/frame.cpp b/src/frame.cpp index 8387730..b3e0071 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -370,7 +370,8 @@ FrameList_::streamRead(Stream *stream) f->matrix.at = buf.at; f->matrix.pos = buf.pos; f->matrix.optimize(); - //f->matflag = buf.matflag; + // RW always removes identity flag + f->matrix.flags &= ~Matrix::IDENTITY; if(buf.parent >= 0) this->frames[buf.parent]->addChild(f, rw::streamAppendFrames); } diff --git a/src/prim.cpp b/src/prim.cpp index c8a43d6..4c94a99 100644 --- a/src/prim.cpp +++ b/src/prim.cpp @@ -22,15 +22,15 @@ BBox::calculate(V3d *points, int32 n) if(points->x < this->inf.x) this->inf.x = points->x; if(points->y < this->inf.y) - this->inf.x = points->y; + this->inf.y = points->y; if(points->z < this->inf.z) - this->inf.x = points->z; + this->inf.z = points->z; if(points->x > this->sup.x) this->sup.x = points->x; if(points->y > this->sup.y) - this->sup.x = points->y; + this->sup.y = points->y; if(points->z > this->sup.z) - this->sup.x = points->z; + this->sup.z = points->z; } } diff --git a/src/rwobjects.h b/src/rwobjects.h index e31a4f5..bf52678 100755 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -191,6 +191,7 @@ struct Raster void unlock(int32 level); int32 getNumLevels(void); static int32 calculateNumLevels(int32 width, int32 height); + static bool formatHasAlpha(int32 format); enum Format { DEFAULT = 0, @@ -269,8 +270,8 @@ struct Texture static Texture *(*findCB)(const char *name); static Texture *(*readCB)(const char *name, const char *mask); - static void setLoadTextures(bool32); - static void setCreateDummies(bool32); + static void setLoadTextures(bool32); // default: true + static void setCreateDummies(bool32); // default: false #ifndef RWPUBLIC static void registerModule(void); diff --git a/src/texture.cpp b/src/texture.cpp index 80c3185..bd8eda0 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -290,6 +290,7 @@ Texture::read(const char *name, const char *mask) if(tex == nil) goto dummytex; }else dummytex: if(TEXTUREGLOBAL(makeDummies)){ +//printf("missing texture %s %s\n", name ? name : "", mask ? mask : ""); tex = Texture::create(nil); if(tex == nil) return nil; @@ -498,6 +499,14 @@ Raster::calculateNumLevels(int32 width, int32 height) return n; } +bool +Raster::formatHasAlpha(int32 format) +{ + return (format & 0xF00) == Raster::C8888 || + (format & 0xF00) == Raster::C1555 || + (format & 0xF00) == Raster::C4444; +} + Raster* Raster::createFromImage(Image *image, int32 platform) { diff --git a/src/uvanim.cpp b/src/uvanim.cpp index c3a569b..fba042c 100644 --- a/src/uvanim.cpp +++ b/src/uvanim.cpp @@ -263,8 +263,11 @@ makeDummyAnimation(const char *name) strncpy(custom->name, name, 32); memset(custom->nodeToUVChannel, 0, sizeof(custom->nodeToUVChannel)); custom->refCount = 1; - // TODO: init the frames -// UVAnimKeyFrame *frames = (UVAnimKeyFrame*)anim->keyframes; + UVAnimKeyFrame *frames = (UVAnimKeyFrame*)anim->keyframes; + frames[0].time = 0.0; + frames[0].prev = nil; + frames[1].time = 1.0; + frames[1].prev = &frames[0]; return anim; } diff --git a/tools/clumpview/main.cpp b/tools/clumpview/main.cpp index 484146b..c77c676 100644 --- a/tools/clumpview/main.cpp +++ b/tools/clumpview/main.cpp @@ -10,7 +10,7 @@ struct SceneGlobals { rw::Camera *camera; rw::Clump *clump; } Scene; -rw::Texture *tex; +rw::Texture *tex, *tex2; rw::EngineStartParams engineStartParams; void tlTest(rw::Clump *clump); @@ -166,6 +166,7 @@ InitRW(void) initFont(); tex = rw::Texture::read("maze", nil); + tex2 = rw::Texture::read("checkers", nil); const char *filename = "teapot.dff"; if(sk::args.argc > 1) @@ -181,11 +182,11 @@ InitRW(void) in.close(); // 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); - } +// 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); +// } Scene.clump->getFrame()->translate(&zero, rw::COMBINEREPLACE); @@ -234,10 +235,16 @@ im2dtest(void) 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 }, +*/ + { 0.0f, 0.0f, 255, 0, 0, 128, 0.0f, 1.0f }, + { 640.0f, 0.0f, 0, 255, 0, 128, 0.0f, 0.0f }, + { 0.0f, 480.0f, 0, 0, 255, 128, 1.0f, 1.0f }, + { 640.0f, 480.0f, 0, 255, 255, 128, 1.0f, 0.0f }, }; Im2DVertex verts[4]; static short indices[] = { @@ -255,7 +262,7 @@ im2dtest(void) verts[i].setV(vs[i].v); } - rw::engine->imtexture = tex; + rw::engine->imtexture = tex2; rw::SetRenderState(rw::VERTEXALPHA, 1); rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP, &verts, 4, &indices, 4);