From 0e0cc1156c5ff190926cb53e5baf2469da69cea1 Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 13 Feb 2016 00:52:32 +0100 Subject: [PATCH] worked on rendering and frame ltm synching --- src/clump.cpp | 120 ++++++++++++++++++++++++++-------------------- src/image.cpp | 3 +- src/pipeline.cpp | 7 ++- src/ps2raster.cpp | 3 +- src/rwbase.cpp | 28 +++++++++++ src/rwbase.h | 2 + src/rwobjects.h | 28 ++++++++--- src/rwpipeline.h | 8 ++-- 8 files changed, 132 insertions(+), 67 deletions(-) diff --git a/src/clump.cpp b/src/clump.cpp index c8c55f3..925ebc1 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -18,6 +18,8 @@ using namespace std; namespace rw { +LinkList Frame::dirtyList; + Frame* Frame::create(void) { @@ -27,15 +29,13 @@ Frame::create(void) f->objectList.init(); f->child = NULL; f->next = NULL; - f->root = NULL; + f->root = f; for(int i = 0; i < 16; i++) f->matrix[i] = 0.0f; f->matrix[0] = 1.0f; f->matrix[5] = 1.0f; f->matrix[10] = 1.0f; f->matrix[15] = 1.0f; - f->matflag = 0; - f->dirty = true; f->constructPlugins(); return f; } @@ -88,13 +88,15 @@ Frame::destroyHierarchy(void) Frame* Frame::addChild(Frame *child, bool32 append) { + Frame *c; + if(child->getParent()) + child->removeChild(); if(append){ if(this->child == NULL) this->child = child; else{ - Frame *f; - for(f = this->child; f->next; f = f->next); - f->next = child; + for(c = this->child; c->next; c = c->next); + c->next = child; } child->next = NULL; }else{ @@ -103,6 +105,13 @@ Frame::addChild(Frame *child, bool32 append) } child->object.parent = this; child->root = this->root; + for(c = child->child; c; c = c->next) + c->setHierarchyRoot(this); + if(child->object.privateFlags & Frame::HIERARCHYSYNC){ + child->inDirtyList.remove(); + child->object.privateFlags &= ~Frame::HIERARCHYSYNC; + } + this->updateObjects(); return this; } @@ -110,19 +119,19 @@ Frame* Frame::removeChild(void) { Frame *parent = this->getParent(); - if(parent->child == this) + Frame *child = parent->child; + if(child == this) parent->child = this->next; else{ - Frame *f; - for(f = parent->child; f; f = f->next) - if(f->next == this) - goto found; - // not found -found: - f->next = f->next->next; + while(child->next != this) + child = child->next; + child->next = this->next; } - this->object.parent = NULL; - this->next = this->root = NULL; + this->object.parent = this->next = NULL; + this->root = this; + for(child = this->child; child; child = child->next) + child->setHierarchyRoot(this); + this->updateObjects(); return this; } @@ -150,35 +159,53 @@ Frame::count(void) return count; } -void -Frame::updateLTM(void) +static void +syncRecurse(Frame *frame, uint8 flags) { - if(!this->dirty) - return; - Frame *parent = this->getParent(); - if(parent){ - parent->updateLTM(); - matrixMult(this->ltm, parent->ltm, this->matrix); - this->dirty = false; - }else{ - memcpy(this->ltm, this->matrix, 16*4); - this->dirty = false; + uint8 flg; + for(; frame; frame = frame->next){ + flg = flags | frame->object.privateFlags; + if(flg & Frame::SUBTREESYNCLTM){ + matrixMult(frame->ltm, frame->getParent()->ltm, frame->matrix); + frame->object.privateFlags &= ~Frame::SUBTREESYNCLTM; + } + syncRecurse(frame->child, flg); } } -static Frame* -dirtyCB(Frame *f, void *) +void +Frame::syncHierarchyLTM(void) { - f->dirty = true; - f->forAllChildren(dirtyCB, NULL); - return f; + Frame *child; + uint8 flg; + if(this->object.privateFlags & Frame::SUBTREESYNCLTM) + memcpy(this->ltm, this->matrix, 64); + for(child = this->child; child; child = child->next){ + flg = this->object.privateFlags | child->object.privateFlags; + if(flg & Frame::SUBTREESYNCLTM){ + matrixMult(child->ltm, this->ltm, child->matrix); + child->object.privateFlags &= ~Frame::SUBTREESYNCLTM; + } + syncRecurse(child, flg); + } + this->object.privateFlags &= ~Frame::SYNCLTM; +} + +float* +Frame::getLTM(void) +{ + if(this->root->object.privateFlags & Frame::HIERARCHYSYNCLTM) + this->root->syncHierarchyLTM(); + return this->ltm; } void -Frame::setDirty(void) +Frame::updateObjects(void) { - this->dirty = true; - this->forAllChildren(dirtyCB, NULL); + if((this->root->object.privateFlags & HIERARCHYSYNC) == 0) + Frame::dirtyList.add(&this->inDirtyList); + this->root->object.privateFlags |= HIERARCHYSYNC; + this->object.privateFlags |= SUBTREESYNC; } void @@ -493,7 +520,7 @@ Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf) f->matrix[13] = buf.pos[1]; f->matrix[14] = buf.pos[2]; f->matrix[15] = 1.0f; - f->matflag = buf.matflag; + //f->matflag = buf.matflag; if(buf.parent >= 0) frameList[buf.parent]->addChild(f); } @@ -533,7 +560,7 @@ Clump::frameListStreamWrite(Stream *stream, Frame **frameList, int32 numFrames) buf.pos[2] = f->matrix[14]; buf.parent = findPointer(f->getParent(), (void**)frameList, numFrames); - buf.matflag = f->matflag; + buf.matflag = 0; //f->matflag; stream->write(&buf, sizeof(buf)); } for(int32 i = 0; i < numFrames; i++) @@ -552,6 +579,7 @@ Atomic::create(void) atomic->object.init(Atomic::ID, 0); atomic->geometry = NULL; atomic->pipeline = NULL; + atomic->renderCB = Atomic::defaultRenderCB; atomic->constructPlugins(); // flags: @@ -670,21 +698,9 @@ Atomic::getPipeline(void) } void -Atomic::init(void) +Atomic::defaultRenderCB(Atomic *atomic) { - ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL); - for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) - defaultPipelines[i] = defpipe; - defaultPipelines[PLATFORM_PS2] = - ps2::makeDefaultPipeline(); - defaultPipelines[PLATFORM_OGL] = - gl::makeDefaultPipeline(); - defaultPipelines[PLATFORM_XBOX] = - xbox::makeDefaultPipeline(); - defaultPipelines[PLATFORM_D3D8] = - d3d8::makeDefaultPipeline(); - defaultPipelines[PLATFORM_D3D9] = - d3d9::makeDefaultPipeline(); + atomic->getPipeline()->render(atomic); } // Atomic Rights plugin diff --git a/src/image.cpp b/src/image.cpp index 752c261..788edb7 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -149,7 +149,8 @@ Texture::read(const char *name, const char *mask) } tex = Texture::create(NULL); strncpy(tex->name, name, 32); - strncpy(tex->mask, mask, 32); + if(mask) + strncpy(tex->mask, mask, 32); Image *img = NULL; if(loadTextures){ char *n = (char*)malloc(strlen(name) + 5); diff --git a/src/pipeline.cpp b/src/pipeline.cpp index e2f6867..9e27505 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -16,6 +16,8 @@ using namespace std; namespace rw { +void (*defaultRenderCBs[rw::NUM_PLATFORMS])(Atomic*); + Pipeline::Pipeline(uint32 platform) { this->pluginID = 0; @@ -50,9 +52,10 @@ ObjPipeline::uninstance(Atomic*) } void -ObjPipeline::render(Atomic*) +ObjPipeline::render(Atomic *atomic) { - fprintf(stderr, "This pipeline can't render\n"); + if(defaultRenderCBs[rw::platform]) + defaultRenderCBs[rw::platform](atomic); } // helper functions diff --git a/src/ps2raster.cpp b/src/ps2raster.cpp index f414bb1..7f06f9c 100644 --- a/src/ps2raster.cpp +++ b/src/ps2raster.cpp @@ -237,9 +237,8 @@ Ps2Raster::create(Raster *raster) if(pageWidth*nPagW > raster->width || pageHeight*nPagH > raster->height) ras->tex1[0] = (ras->gsSize >> 6) - 4; - else{ + else ras->tex1[0] = ras->gsSize >> 6; - } nPagW = (paletteWidth + palettePagewidth-1)/palettePagewidth; nPagH = (paletteHeight + palettePageheight-1)/palettePageheight; ras->gsSize += (nPagW*nPagH*0x800)&~0x7FF; diff --git a/src/rwbase.cpp b/src/rwbase.cpp index b20ac3d..9314606 100644 --- a/src/rwbase.cpp +++ b/src/rwbase.cpp @@ -5,6 +5,13 @@ #include "rwbase.h" #include "rwplugin.h" +#include "rwpipeline.h" +#include "rwobjects.h" +#include "rwps2.h" +#include "rwogl.h" +#include "rwxbox.h" +#include "rwd3d8.h" +#include "rwd3d9.h" using namespace std; @@ -23,6 +30,27 @@ int32 build = 0xFFFF; #endif char *debugFile = NULL; +void +initialize(void) +{ + // Atomic pipelines + ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL); + for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) + defaultPipelines[i] = defpipe; + defaultPipelines[PLATFORM_PS2] = + ps2::makeDefaultPipeline(); + defaultPipelines[PLATFORM_OGL] = + gl::makeDefaultPipeline(); + defaultPipelines[PLATFORM_XBOX] = + xbox::makeDefaultPipeline(); + defaultPipelines[PLATFORM_D3D8] = + d3d8::makeDefaultPipeline(); + defaultPipelines[PLATFORM_D3D9] = + d3d9::makeDefaultPipeline(); + + Frame::dirtyList.init(); +} + void matrixIdentity(float32 *mat) { diff --git a/src/rwbase.h b/src/rwbase.h index fb33218..44977a3 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -153,6 +153,8 @@ extern int build; extern int platform; extern char *debugFile; +void initialize(void); + void matrixIdentity(float32 *mat); int matrixEqual(float32 *m1, float32 *m2); int matrixIsIdentity(float32 *mat); diff --git a/src/rwobjects.h b/src/rwobjects.h index 6ad176e..f9c942f 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -115,9 +115,20 @@ struct Object struct Frame : PluginBase { typedef Frame *(*Callback)(Frame *f, void *data); - enum { ID = 0 }; + enum { // private flags + HIERARCHYSYNCLTM = 0x01, + HIERARCHYSYNCOBJ = 0x02, + HIERARCHYSYNC = HIERARCHYSYNCLTM | HIERARCHYSYNCOBJ, + SUBTREESYNCLTM = 0x04, + SUBTREESYNCOBJ = 0x08, + SUBTREESYNC = SUBTREESYNCLTM | SUBTREESYNCOBJ, + SYNCLTM = HIERARCHYSYNCLTM | SUBTREESYNCLTM, + SYNCOBJ = HIERARCHYSYNCOBJ | SUBTREESYNCOBJ, + }; + Object object; + LLLink inDirtyList; LinkList objectList; float32 matrix[16]; float32 ltm[16]; @@ -126,9 +137,7 @@ struct Frame : PluginBase Frame *next; Frame *root; - // temporary - int32 matflag; - bool dirty; + static LinkList dirtyList; static Frame *create(void); Frame *cloneHierarchy(void); @@ -140,9 +149,10 @@ struct Frame : PluginBase Frame *getParent(void){ return (Frame*)this->object.parent; } int32 count(void); - void updateLTM(void); - void setDirty(void); + float *getLTM(void); + void updateObjects(void); + void syncHierarchyLTM(void); void setHierarchyRoot(Frame *root); Frame *cloneAndLink(Frame *clonedroot); void purgeClone(void); @@ -578,12 +588,15 @@ struct Clump; struct Atomic : PluginBase { + typedef void (*RenderCB)(Atomic *atomic); enum { ID = 1 }; + ObjectWithFrame object; Geometry *geometry; Clump *clump; LLLink inClump; ObjPipeline *pipeline; + RenderCB renderCB; static Atomic *create(void); Atomic *clone(void); @@ -598,8 +611,9 @@ struct Atomic : PluginBase Frame **frameList, int32 numframes); uint32 streamGetSize(void); ObjPipeline *getPipeline(void); + void render(void) { this->renderCB(this); } - static void init(void); + static void defaultRenderCB(Atomic *atomic); }; extern ObjPipeline *defaultPipelines[NUM_PLATFORMS]; diff --git a/src/rwpipeline.h b/src/rwpipeline.h index 6785f9b..e7c8ec7 100644 --- a/src/rwpipeline.h +++ b/src/rwpipeline.h @@ -25,11 +25,13 @@ class ObjPipeline : public Pipeline { public: ObjPipeline(uint32 platform) : Pipeline(platform) {} - virtual void instance(Atomic *atomic); - virtual void uninstance(Atomic *atomic); - virtual void render(Atomic *atomic); + virtual void instance(Atomic *atomic); // TODO?: make these callbacks instead of virtual + virtual void uninstance(Atomic *atomic); // TODO?: make these callbacks instead of virtual + virtual void render(Atomic *atomic); // TODO?: make these callbacks instead of virtual }; +extern void (*defaultRenderCBs[rw::NUM_PLATFORMS])(Atomic*); + void findMinVertAndNumVertices(uint16 *indices, uint32 numIndices, uint32 *minVert, int32 *numVertices); // everything xbox, d3d8 and d3d9 may want to use