12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222 |
- #include "pch.h"
- //////////////////////////////////////////////////////////////////////////////
- //
- // Plane
- //
- //////////////////////////////////////////////////////////////////////////////
- float Plane::Distance(const HVector& vec) const
- {
- return
- vec.X() * m_hvec.X()
- + vec.Y() * m_hvec.Y()
- + vec.Z() * m_hvec.Z()
- + vec.W() * m_hvec.W();
- }
- float Plane::Intersect(const HVector& v0, const HVector& v1) const
- {
- HVector vd = v1 - v0;
- float a = m_hvec * v0;
- float b = m_hvec * vd;
- float alpha = -a / b;
- return bound(alpha, 0.0f, 1.0f);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // State
- //
- //////////////////////////////////////////////////////////////////////////////
- class StateChangeBase {};
- typedef TBitMask<StateChangeBase, DWORD> StateChange;
- class StateChangeMatrix : public StateChange { public: StateChangeMatrix () : StateChange(0x000001) {} };
- class StateChangePerspectiveMatrix : public StateChange { public: StateChangePerspectiveMatrix () : StateChange(0x000002) {} };
- class StateChangeMaterial : public StateChange { public: StateChangeMaterial () : StateChange(0x000004) {} };
- class StateChangeTexture : public StateChange { public: StateChangeTexture () : StateChange(0x000008) {} };
- class StateChangeShadeMode : public StateChange { public: StateChangeShadeMode () : StateChange(0x000010) {} };
- class StateChangeBlendMode : public StateChange { public: StateChangeBlendMode () : StateChange(0x000020) {} };
- class StateChangeZTest : public StateChange { public: StateChangeZTest () : StateChange(0x000040) {} };
- class StateChangeZWrite : public StateChange { public: StateChangeZWrite () : StateChange(0x000080) {} };
- class StateChangeLinearFilter : public StateChange { public: StateChangeLinearFilter () : StateChange(0x000100) {} };
- class StateChangePerspectiveCorrection : public StateChange { public: StateChangePerspectiveCorrection() : StateChange(0x000200) {} };
- class StateChangeDither : public StateChange { public: StateChangeDither () : StateChange(0x000400) {} };
- class StateChangeWrapMode : public StateChange { public: StateChangeWrapMode () : StateChange(0x000800) {} };
- class StateChangeCullMode : public StateChange { public: StateChangeCullMode () : StateChange(0x001000) {} };
- class StateChangeClipRect : public StateChange { public: StateChangeClipRect () : StateChange(0x002000) {} };
- class StateChangeClipPlanes : public StateChange { public: StateChangeClipPlanes () : StateChange(0x004000) {} };
- class StateChangeColor : public StateChange { public: StateChangeColor () : StateChange(0x008000) {} };
- class StateChangeAmbientLevel : public StateChange { public: StateChangeAmbientLevel () : StateChange(0x010000) {} };
- class StateChangeLineWidth : public StateChange { public: StateChangeLineWidth () : StateChange(0x020000) {} };
- class StateChangeColorKey : public StateChange { public: StateChangeColorKey () : StateChange(0x040000) {} };
- class StateChangeDeformation : public StateChange { public: StateChangeDeformation () : StateChange(0x080000) {} };
- class StateChangeAll : public StateChange { public: StateChangeAll () : StateChange(0xffffff) {} };
- const StateChange stCommon =
- StateChangeMatrix()
- | StateChangeMaterial()
- | StateChangeTexture();
- const StateChange stUncommon = StateChangeAll().Clear(stCommon);
- class State : public IObjectSingle {
- public:
- TRef<State> m_pnext;
- TRef<Material> m_pmaterial;
- TRef<Surface> m_psurfaceTexture;
- TRef<Deformation> m_pdeform;
- Matrix m_mat;
- Matrix m_matPerspective;
- Rect m_rectClip;
- int m_countClipPlanes;
- bool m_bZTest;
- bool m_bZWrite;
- bool m_bDither;
- bool m_bColorKey;
- bool m_bLinearFilter;
- bool m_bPerspectiveCorrection;
- ShadeMode m_shadeMode;
- BlendMode m_blendMode;
- WrapMode m_wrapMode;
- CullMode m_cullMode;
- Color m_color;
- float m_ambientLevel;
- float m_lineWidth;
- StateChange m_maskChanges;
- StateChange m_maskOverride;
- State()
- {
- }
- State(State* pstate) :
- m_pnext(pstate),
- m_maskChanges(),
- m_maskOverride()
- {
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Drawing Context
- //
- //////////////////////////////////////////////////////////////////////////////
- class ContextImpl : public PrivateContext {
- private:
- //////////////////////////////////////////////////////////////////////////////
- //
- // types
- //
- //////////////////////////////////////////////////////////////////////////////
- class WhiteSurfaceSite : public SurfaceSite {
- public:
- void UpdateSurface(Surface* psurface)
- {
- psurface->FillSurface(Color::White());
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // members
- //
- //////////////////////////////////////////////////////////////////////////////
- TRef<IDevice3D> m_pdevice3D;
- TRef<State> m_pstate;
- TRef<State> m_pstateDevice;
- PrivateSurface* m_psurface;
- //
- // Vertex buffers
- //
- Vertex* m_pvertexBuffer;
- int m_countVertexBuffer;
- MeshIndex* m_pindexBuffer;
- int m_countIndexBuffer;
- //
- // What mode is the device in?
- //
- bool m_bRendering;
- bool m_bIn3DLayer;
- bool m_bInScene;
- bool m_bRenderingCallbacks;
- //
- // Culling
- //
- float m_focus;
- float m_near;
- float m_far;
- float m_aspect;
- float m_rxscale;
- float m_ryscale;
- float m_yscale;
- //
- // Level of detail
- //
- float m_lod;
- //////////////////////////////////////////////////////////////////////////////
- //
- // Decal Data
- //
- //////////////////////////////////////////////////////////////////////////////
- class Decal {
- public:
- Vector m_position;
- Color m_color;
- float m_scale;
- float m_angle;
- Vector m_forward;
- Vector m_right;
- bool GetVertices(VertexL* pvertex) const
- {
- Vector v0;
- Vector v1;
- Vector v2;
- Vector v3;
- if (m_forward.IsZero()) {
- float c = cos(m_angle) * m_scale;
- float s = sin(m_angle) * m_scale;
- float dx = c - s;
- float dy = c + s;
- float x = m_position.X();
- float y = m_position.Y();
- float z = m_position.Z();
- v0 = Vector(x - dy, y + dx, z);
- v1 = Vector(x - dx, y - dy, z);
- v2 = Vector(x + dy, y - dx, z);
- v3 = Vector(x + dx, y + dy, z);
- } else {
- v0 = m_position - m_forward - m_right;
- v1 = m_position + m_forward - m_right;
- v2 = m_position + m_forward + m_right;
- v3 = m_position - m_forward + m_right;
- }
- float r = m_color.R();
- float g = m_color.G();
- float b = m_color.B();
- float a = m_color.A();
- pvertex[0] = VertexL(v0.X(), v0.Y(), v0.Z(), r, g, b, a, 0, 1);
- pvertex[1] = VertexL(v1.X(), v1.Y(), v1.Z(), r, g, b, a, 0, 0);
- pvertex[2] = VertexL(v2.X(), v2.Y(), v2.Z(), r, g, b, a, 1, 0);
- pvertex[3] = VertexL(v3.X(), v3.Y(), v3.Z(), r, g, b, a, 1, 1);
- return true;
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Decal Sets
- //
- //////////////////////////////////////////////////////////////////////////////
- class DecalSet {
- public:
- TRef<Surface> m_psurface;
- TVector<Decal> m_vdecal;
- };
- TVector<DecalSet> m_vdecalSet;
- TVector<DecalSet> m_vdecalSetOpaque;
- //
- // Delayed 3D Rendering
- //
- class GeoCallbackData {
- public:
- TRef<IGeoCallback> m_pgeoCallback;
- Matrix m_mat;
- float m_distance;
- };
- class CompareDistance {
- public:
- bool operator () (const GeoCallbackData& value1, const GeoCallbackData& value2)
- {
- return value1.m_distance < value2.m_distance;
- }
- };
- typedef TList<GeoCallbackData, DefaultNoEquals, CompareDistance> GeoCallbackDataList;
- GeoCallbackDataList m_listGeoCallbacks;
- GeoCallbackDataList m_listGeoCallbacksSorted;
- //
- // Counters
- //
- #ifdef EnablePerformanceCounters
- int m_countDrawString;
- int m_countDrawStringChars;
- #endif
- public:
- //////////////////////////////////////////////////////////////////////////////
- //
- // Constructor
- //
- //////////////////////////////////////////////////////////////////////////////
- ContextImpl(PrivateSurface* psurface) :
- #ifdef EnablePerformanceCounters
- m_countDrawString(0),
- m_countDrawStringChars(0),
- #endif
- m_pvertexBuffer(NULL),
- m_countVertexBuffer(0),
- m_pindexBuffer(NULL),
- m_countIndexBuffer(0),
- m_psurface(psurface),
- m_bRendering(false),
- m_bIn3DLayer(false),
- m_bInScene(false),
- m_bRenderingCallbacks(false)
- {
- //
- // Create a rasterizer and a 3D device
- //
-
- if (psurface->GetSurfaceType().Test(SurfaceType3D())) {
- TRef<Engine> pengine = psurface->GetEngine();
- TRef<Rasterizer> prasterizer;
- bool bAlwaysUseD3D = false;
- if (
- bAlwaysUseD3D
- || (
- pengine->GetUsing3DAcceleration()
- && psurface->GetSurfaceType().Test(SurfaceTypeVideo())
- )
- ) {
- prasterizer = CreateD3DRasterizer(m_psurface);
- } else {
- prasterizer = CreateSoftwareRasterizer(m_psurface);
- }
- if (prasterizer == NULL) {
- return;
- }
- m_pdevice3D = CreateDevice3D(prasterizer);
- }
- //
- // Setup the initial state
- //
- m_pstateDevice = new State();
- m_pstateDevice->m_mat.SetIdentity();
- m_pstateDevice->m_matPerspective.SetIdentity();
- m_pstateDevice->m_pmaterial = NULL;
- m_pstateDevice->m_bZTest = false;
- m_pstateDevice->m_bZWrite = false;
- m_pstateDevice->m_bPerspectiveCorrection = false;
- m_pstateDevice->m_bDither = true;
- m_pstateDevice->m_bColorKey = true;
- m_pstateDevice->m_bLinearFilter = true;
- m_pstateDevice->m_shadeMode = ShadeModeGouraud;
- m_pstateDevice->m_blendMode = BlendModeSource;
- m_pstateDevice->m_wrapMode = WrapModeNone;
- m_pstateDevice->m_cullMode = CullModeCCW;
- m_pstateDevice->m_maskChanges = StateChangeAll();
- m_pstateDevice->m_maskOverride = StateChange();
- m_pstateDevice->m_countClipPlanes = 0;
- m_pstateDevice->m_rectClip =
- Rect(
- Point(0, 0),
- Point::Cast(m_psurface->GetSize())
- );
- m_pstateDevice->m_color = Color::White();
- m_pstateDevice->m_lineWidth = 1;
- }
- bool IsValid()
- {
- return m_pdevice3D != NULL && m_pdevice3D->IsValid();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Destructor
- //
- //////////////////////////////////////////////////////////////////////////////
- ~ContextImpl()
- {
- if (m_pvertexBuffer) {
- free(m_pvertexBuffer);
- }
- if (m_pindexBuffer) {
- free(m_pindexBuffer);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Capabilities
- //
- //////////////////////////////////////////////////////////////////////////////
- bool Has3DAcceleration()
- {
- return m_pdevice3D->Has3DAcceleration();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Rendering Initialization
- //
- //////////////////////////////////////////////////////////////////////////////
- void BeginRendering()
- {
- ZAssert(!m_bRendering);
- ZAssert(!m_bInScene);
- ZAssert(!m_bIn3DLayer);
- m_bRendering = true;
- PushState();
- }
- void EndRendering()
- {
- ZAssert(m_bRendering);
- PopState();
- if (m_bIn3DLayer) {
- End3DLayer();
- }
- EndScene();
- m_bRendering = false;
- }
- PrivateSurface* GetSurface()
- {
- return m_psurface;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Attributes
- //
- //////////////////////////////////////////////////////////////////////////////
- bool GetClipping()
- {
- return m_pdevice3D->GetClipping();
- }
- void SetClipping(bool bClip)
- {
- m_pdevice3D->SetClipping(bClip);
- }
- bool IsCulled(
- const Vector& vecOrigin,
- float radius,
- bool& bNotClipped
- ) {
- // , this code assumes there are no non-uniform scales
- // actualy it doesn't handle scales at all since radius isn't
- // scaled.
- Vector vecEye = TransformLocalToEye(vecOrigin);
- float x = vecEye.X();
- float y = vecEye.Y();
- float z = vecEye.Z();
- float back = z - m_far;
- float front = m_near - z;
- float rx;
- float ry;
- float left;
- float right;
- float bottom;
- float top;
- if (m_focus == 0) {
- rx = radius;
- ry = radius;
- left = x - 1;
- right = -x - 1;
- bottom = y - 1;
- top = -y - 1;
- } else {
- rx = radius * m_rxscale;
- ry = radius * m_ryscale;
- left = m_focus * x - z;
- right = -m_focus * x - z;
- bottom = m_yscale * y - z;
- top = -m_yscale * y - z;
- }
- //
- // Is the sphere completely outside the frustum?
- //
- if (
- left < -rx
- || right < -rx
- || bottom < -ry
- || top < -ry
- || back < -radius
- || front < -radius
- ) {
- bNotClipped = false;
- return true;
- }
- //
- // Is the sphere completely inside the frustum?
- //
- if (
- left > rx
- && right > rx
- && bottom > ry
- && top > ry
- && back > radius
- && front > radius
- ) {
- bNotClipped = true;
- return false;
- }
- //
- // The sphere intersects the frustum's boundary.
- //
- bNotClipped = false;
- return false;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // 2D Image Rendering
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawImage(
- Surface* psurface,
- const Rect& rectSource,
- bool bCentered,
- const Point& point
- ) {
- // !!! should really look at the device mode and the current transform
- // !!! this uses upper left as (0, 0) on psurface and DrawImage3D() uses lower left as (0, 0)
- // !!! this doesn't scale or rotate the image
- ZAssert(!m_bIn3DLayer);
- ZAssert(m_pstateDevice->m_matPerspective.GetType() < TransformRotate);
- DD2D();
- Point pointImage;
- if (TransformLocalToImage(Vector(point.X(), point.Y(), 0), pointImage)) {
- WinPoint pointScreen = TransformImageToSurface(pointImage);
- if (bCentered) {
- pointScreen.SetX(pointScreen.X() - (int)(rectSource.XSize() / 2.0f));
- pointScreen.SetY(pointScreen.Y() - (int)(rectSource.YSize() / 2.0f));
- } else {
- pointScreen.SetY(pointScreen.Y() - (int)rectSource.YSize());
- }
- m_psurface->BitBlt(
- pointScreen,
- psurface,
- WinRect::Cast(rectSource)
- );
- };
- }
- void DrawImage(
- Surface* psurface,
- bool bCentered,
- const Point& point
- ) {
- DrawImage(
- psurface,
- WinRect(
- WinPoint(0, 0),
- psurface->GetSize()
- ),
- bCentered,
- point
- );
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // 3D Image Rendering
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawImage3D(
- Surface* psurface,
- const Rect& rectSource,
- const Color& color,
- bool bCentered,
- const Point& point
- ) {
- ZAssert(m_bRendering);
- if (!m_bInScene) {
- Texture2D();
- }
- Point sizeSource(Point::Cast(psurface->GetSize()));
- float xOffset = point.X() - (bCentered ? rectSource.XSize() / 2 : 0);
- float yOffset = point.Y() - (bCentered ? rectSource.YSize() / 2 : 0);
- float xmin = xOffset ;
- float xmax = xOffset + rectSource.XSize();
- float ymin = yOffset;
- float ymax = yOffset + rectSource.YSize();
- float xt;
- float yt;
- //if (psurface->GetSurfaceType().Test(SurfaceTypeTile())) {
- xt = 1.0f / sizeSource.X();
- yt = 1.0f / sizeSource.Y();
- //} else {
- // // , this is broken if the texture size is smaller that the surface size
- // Point pointTextureSize(Point::Cast(psurface->GetTextureRect().Size()));
- //
- // xt = 1.0f / pointTextureSize.X();
- // yt = 1.0f / pointTextureSize.Y();
- //}
- float xtmin = xt * rectSource.XMin();
- float xtmax = xt * rectSource.XMax();
- float ytmin = yt * (sizeSource.Y() - rectSource.YMin());
- float ytmax = yt * (sizeSource.Y() - rectSource.YMax());
- static MeshIndex indices[6] = { 0, 2, 1, 0, 3, 2 };
- UpdateState();
- m_pdevice3D->SetTexture(psurface);
- switch (GetShadeMode()) {
- case ShadeModeCopy:
- {
- Vertex vertices[4] = {
- Vertex(xmin, ymax, 0, 0, 0, 1, xtmin, ytmax),
- Vertex(xmin, ymin, 0, 0, 0, 1, xtmin, ytmin),
- Vertex(xmax, ymin, 0, 0, 0, 1, xtmax, ytmin),
- Vertex(xmax, ymax, 0, 0, 0, 1, xtmax, ytmax)
- };
- m_pdevice3D->DrawTriangles(vertices, 4, indices, 6);
- }
- break;
- case ShadeModeFlat:
- case ShadeModeGouraud:
- {
- float r = color.R();
- float g = color.G();
- float b = color.B();
- float a = color.A();
- VertexL vertices[4] = {
- VertexL(xmin, ymax, 0, r, g, b, a, xtmin, ytmax),
- VertexL(xmin, ymin, 0, r, g, b, a, xtmin, ytmin),
- VertexL(xmax, ymin, 0, r, g, b, a, xtmax, ytmin),
- VertexL(xmax, ymax, 0, r, g, b, a, xtmax, ytmax)
- };
- m_pdevice3D->SetShadeMode(ShadeModeFlat);
- m_pdevice3D->DrawTriangles(vertices, 4, indices, 6);
- m_pdevice3D->SetShadeMode(m_pstateDevice->m_shadeMode);
- }
- break;
- default:
- ZError("Invalid shade mode");
- break;
- }
- m_pdevice3D->SetTexture(m_pstateDevice->m_psurfaceTexture);
- }
- void DrawImage3D(
- Surface* psurface,
- const Color& color,
- bool bCentered,
- const Point& point
- ) {
- DrawImage3D(
- psurface,
- Rect(
- Point(0, 0),
- Point::Cast(psurface->GetSize())
- ),
- color,
- bCentered,
- point
- );
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Text Rendering
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawString(
- IEngineFont* pfont,
- const Color& color,
- const Point& point,
- const ZString& str
- ) {
- #ifdef EnablePerformanceCounters
- m_countDrawString++;
- m_countDrawStringChars += str.GetLength();
- #endif
- DD2D();
- Point pointImage;
- if (TransformLocalToImage(Vector(point.X(), point.Y(), 0), pointImage)) {
- WinPoint pointScreen = TransformImageToSurface(pointImage);
- WinPoint size = pfont->GetTextExtent(str);
- pointScreen.SetY(pointScreen.Y() - size.Y());
- m_psurface->DrawString(pfont, color, pointScreen, str);
- };
- }
- void DrawRectangle(const Rect& rect, const Color& color)
- {
- Texture2D();
- static MeshIndex indices[8] = { 0, 1, 1, 2, 2, 3, 3, 0 };
- float xmin = rect.XMin();
- float xmax = rect.XMax();
- float ymin = rect.YMin();
- float ymax = rect.YMax();
- float r = color.R();
- float g = color.G();
- float b = color.B();
- float a = color.A();
- VertexL vertices[4] = {
- VertexL(xmin, ymax, 0, r, g, b, a, 0, 0),
- VertexL(xmin, ymin, 0, r, g, b, a, 0, 0),
- VertexL(xmax, ymin, 0, r, g, b, a, 0, 0),
- VertexL(xmax, ymax, 0, r, g, b, a, 0, 0)
- };
- m_pdevice3D->DrawLines(vertices, 4, indices, 8);
- }
- void FillRect(const Rect& rect, const Color& color)
- {
- Texture2D();
- static MeshIndex indices[6] = { 0, 2, 1, 0, 3, 2 };
- float xmin = rect.XMin();
- float xmax = rect.XMax();
- float ymin = rect.YMin();
- float ymax = rect.YMax();
- float r = color.R();
- float g = color.G();
- float b = color.B();
- float a = color.A();
- VertexL vertices[4] = {
- VertexL(xmin, ymax, 0, r, g, b, a, 0, 1),
- VertexL(xmin, ymin, 0, r, g, b, a, 0, 0),
- VertexL(xmax, ymin, 0, r, g, b, a, 1, 0),
- VertexL(xmax, ymax, 0, r, g, b, a, 1, 1)
- };
- UpdateState();
- m_pdevice3D->SetShadeMode(ShadeModeFlat);
- m_pdevice3D->DrawTriangles(vertices, 4, indices, 6);
- m_pdevice3D->SetShadeMode(m_pstateDevice->m_shadeMode);
- }
- void FillInfinite(const Color& color)
- {
- DD2D();
- m_psurface->FillSurface(color);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // 3D Layers
- //
- //////////////////////////////////////////////////////////////////////////////
- void Begin3DLayer(Camera* pcamera, bool bZBuffer)
- {
- ZEnter("Context::Begin3DLayer");
- ZAssert(m_bRendering);
- ZAssert(!m_bIn3DLayer);
- //
- // Push the state so we can undo all the state changes
- //
- PushState();
- //
- // Integrate the 2D transforms up until this point with the 3D transform
- //
- pcamera->Update();
- SetPerspectiveMatrix(pcamera->GetPerspectiveMatrix());
- //
- // Change this flag after we change the prespective matrix
- //
- m_bIn3DLayer = true;
- //
- // Apply the camera's transform
- //
- SetTransform(pcamera->GetModelMatrix());
- //
- // start the 3D Layer
- //
- BeginScene();
- //
- // Save some information needed for culling
- //
- WinPoint point = m_psurface->GetSize();
- m_focus = pcamera->GetFocus();
- m_near = pcamera->GetNear();
- m_far = pcamera->GetFar();
- m_aspect = float(point.Y()) / float(point.X());
- m_yscale = m_focus / m_aspect;
- m_rxscale = sqrt(m_focus * m_focus + 1.0f);
- m_ryscale = sqrt(m_yscale * m_yscale + 1.0f);
- //
- // Default to being frustum clipped
- //
- SetClipping(true);
- //
- // Initialize state
- //
- m_lod = FLT_MAX;
- //
- // Clear the ZBuffer
- //
- if (bZBuffer) {
- ZTrace("Clearing ZBuffer");
- UpdateState();
- m_pdevice3D->ClearZBuffer();
- SetZWrite(true, false);
- SetZTest(true, false);
- } else {
- //
- // turn off zbuffering for any future drawing
- //
- SetZWrite(false, false);
- SetZTest(false, false);
- }
- PushState();
- }
- void RenderCallbackGeos(GeoCallbackDataList& list)
- {
- GeoCallbackDataList::Iterator iter(list);
- while (!iter.End()) {
- GeoCallbackData& data = iter.Value();
- PushState();
- SetTransform(data.m_mat);
- data.m_pgeoCallback->RenderCallback(this);
- PopState();
- iter.Next();
- }
- list.SetEmpty();
- }
- void End3DLayer()
- {
- ZExit("Context::Begin3DLayer");
- ZAssert(m_bRendering);
- ZAssert(m_bIn3DLayer);
- ZAssert(m_bInScene);
- //
- // Restore the original state
- //
- PopState();
- //
- // Render any GeoCallbacks
- //
- m_bRenderingCallbacks = true;
- RenderCallbackGeos(m_listGeoCallbacksSorted);
- RenderCallbackGeos(m_listGeoCallbacks);
- m_bRenderingCallbacks = false;
- //
- // Draw decals
- //
- DrawCachedDecals();
- //
- // End the 3D layer
- //
- PopState();
- m_bIn3DLayer = false;
- }
- void BeginScene()
- {
- if (!m_bInScene) {
- m_pdevice3D->BeginScene();
- m_bInScene = true;
- }
- }
- void EndScene()
- {
- if (m_bInScene) {
- m_pdevice3D->EndScene();
- m_bInScene = false;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Level of detail
- //
- //////////////////////////////////////////////////////////////////////////////
- void SetLOD(float lod)
- {
- m_lod = lod;
- }
- float GetLOD()
- {
- return m_lod;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Get State
- //
- //////////////////////////////////////////////////////////////////////////////
- const Color& GetGlobalColor() const { return m_pstateDevice->m_color ; }
- bool GetZTest() const { return m_pstateDevice->m_bZTest ; }
- bool GetZWrite() const { return m_pstateDevice->m_bZWrite ; }
- bool GetPerspectiveCorrection() const { return m_pstateDevice->m_bPerspectiveCorrection; }
- bool GetDither() const { return m_pstateDevice->m_bDither ; }
- bool GetColorKey() const { return m_pstateDevice->m_bColorKey ; }
- bool GetLinearFilter() const { return m_pstateDevice->m_bLinearFilter ; }
- ShadeMode GetShadeMode() const { return m_pstateDevice->m_shadeMode ; }
- BlendMode GetBlendMode() const { return m_pstateDevice->m_blendMode ; }
- WrapMode GetWrapMode() const { return m_pstateDevice->m_wrapMode ; }
- CullMode GetCullMode() const { return m_pstateDevice->m_cullMode ; }
- Surface* GetTexture() const { return m_pstateDevice->m_psurfaceTexture ; }
- Material* GetMaterial() const { return m_pstateDevice->m_pmaterial ; }
- Deformation* GetDeformation() const { return m_pstateDevice->m_pdeform ; }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Efficient State Changes
- //
- //////////////////////////////////////////////////////////////////////////////
- template<class ValueType>
- void DoSetState(
- const ValueType& value,
- ValueType& valueDevice,
- ValueType& valueState,
- bool bOverride,
- const StateChange& st
- ) {
- if (!m_pstateDevice->m_maskOverride.Test(st)) {
- if (value != valueDevice) {
- if (!m_pstate->m_maskChanges.Test(st)) {
- valueState = valueDevice;
- m_pstate->m_maskChanges.Set(st);
- }
- valueDevice = value;
- m_pstateDevice->m_maskChanges.Set(st);
- }
- if (bOverride) {
- m_pstate->m_maskOverride.Set(st);
- m_pstateDevice->m_maskOverride.Set(st);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Efficient State Changes
- //
- //////////////////////////////////////////////////////////////////////////////
- void SetGlobalColor(const Color& color, bool bOverride)
- {
- DoSetState(
- color,
- m_pstateDevice->m_color,
- m_pstate->m_color,
- bOverride,
- StateChangeColor()
- );
- }
- void SetLinearFilter(bool b, bool bOverride)
- {
- DoSetState(
- b,
- m_pstateDevice->m_bLinearFilter,
- m_pstate->m_bLinearFilter,
- bOverride,
- StateChangeLinearFilter()
- );
- }
- void SetPerspectiveCorrection(bool b, bool bOverride)
- {
- DoSetState(
- b,
- m_pstateDevice->m_bPerspectiveCorrection,
- m_pstate->m_bPerspectiveCorrection,
- bOverride,
- StateChangePerspectiveCorrection()
- );
- }
- void SetDither(bool b, bool bOverride)
- {
- DoSetState(
- b,
- m_pstateDevice->m_bDither,
- m_pstate->m_bDither,
- bOverride,
- StateChangeDither()
- );
- }
- void SetColorKey(bool b, bool bOverride)
- {
- DoSetState(
- b,
- m_pstateDevice->m_bColorKey,
- m_pstate->m_bColorKey,
- bOverride,
- StateChangeColorKey()
- );
- }
- void SetZTest(bool b, bool bOverride)
- {
- DoSetState(
- b,
- m_pstateDevice->m_bZTest,
- m_pstate->m_bZTest,
- bOverride,
- StateChangeZTest()
- );
- }
- void SetZWrite(bool b, bool bOverride)
- {
- DoSetState(
- b,
- m_pstateDevice->m_bZWrite,
- m_pstate->m_bZWrite,
- bOverride,
- StateChangeZWrite()
- );
- }
- void SetShadeMode(ShadeMode shadeMode, bool bOverride)
- {
- DoSetState(
- shadeMode,
- m_pstateDevice->m_shadeMode,
- m_pstate->m_shadeMode,
- bOverride,
- StateChangeShadeMode()
- );
- }
- void SetBlendMode(BlendMode blendMode, bool bOverride)
- {
- DoSetState(
- blendMode,
- m_pstateDevice->m_blendMode,
- m_pstate->m_blendMode,
- bOverride,
- StateChangeBlendMode()
- );
- }
- void SetWrapMode(WrapMode wrapMode, bool bOverride)
- {
- DoSetState(
- wrapMode,
- m_pstateDevice->m_wrapMode,
- m_pstate->m_wrapMode,
- bOverride,
- StateChangeWrapMode()
- );
- }
- void SetCullMode(CullMode cullMode, bool bOverride)
- {
- DoSetState(
- cullMode,
- m_pstateDevice->m_cullMode,
- m_pstate->m_cullMode,
- bOverride,
- StateChangeCullMode()
- );
- }
- void SetMaterial(Material* pmaterial, bool bOverride)
- {
- DoSetState(
- TRef<Material>(pmaterial),
- m_pstateDevice->m_pmaterial,
- m_pstate->m_pmaterial,
- bOverride,
- StateChangeMaterial()
- );
- }
- void SetTexture(Surface* psurface, bool bOverride)
- {
- DoSetState(
- TRef<Surface>(psurface),
- m_pstateDevice->m_psurfaceTexture,
- m_pstate->m_psurfaceTexture,
- bOverride,
- StateChangeTexture()
- );
- }
- void SetDeformation(Deformation* pdeform, bool bOverride)
- {
- DoSetState(
- TRef<Deformation>(pdeform),
- m_pstateDevice->m_pdeform,
- m_pstate->m_pdeform,
- bOverride,
- StateChangeDeformation()
- );
- }
- void SetLineWidth(float width, bool bOverride = false)
- {
- DoSetState(
- width,
- m_pstateDevice->m_lineWidth,
- m_pstate->m_lineWidth,
- bOverride,
- StateChangeLineWidth()
- );
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Update the device states
- //
- //////////////////////////////////////////////////////////////////////////////
- void UpdateState()
- {
- const StateChange& maskChanges = m_pstateDevice->m_maskChanges;
- if (maskChanges.Test(stCommon)) {
- if (maskChanges.Test(StateChangeMatrix())) {
- m_pdevice3D->SetMatrix(m_pstateDevice->m_mat);
- }
- if (maskChanges.Test(StateChangeMaterial())) {
- m_pdevice3D->SetMaterial(m_pstateDevice->m_pmaterial);
- }
- if (maskChanges.Test(StateChangeTexture())) {
- m_pdevice3D->SetTexture(m_pstateDevice->m_psurfaceTexture);
- }
- }
- if (maskChanges.Test(stUncommon)) {
- if (maskChanges.Test(StateChangeDeformation())) {
- m_pdevice3D->SetDeformation(m_pstateDevice->m_pdeform);
- }
- if (maskChanges.Test(StateChangePerspectiveMatrix())) {
- m_pdevice3D->SetPerspectiveMatrix(m_pstateDevice->m_matPerspective);
- }
- if (maskChanges.Test(StateChangeColor())) {
- m_pdevice3D->SetGlobalColor(m_pstateDevice->m_color);
- }
- if (maskChanges.Test(StateChangeClipRect())) {
- m_pdevice3D->SetClipRect(m_pstateDevice->m_rectClip);
- }
- if (maskChanges.Test(StateChangeShadeMode())) {
- m_pdevice3D->SetShadeMode(m_pstateDevice->m_shadeMode);
- }
- if (maskChanges.Test(StateChangeBlendMode())) {
- m_pdevice3D->SetBlendMode(m_pstateDevice->m_blendMode);
- }
- if (maskChanges.Test(StateChangeWrapMode())) {
- m_pdevice3D->SetWrapMode(m_pstateDevice->m_wrapMode);
- }
- if (maskChanges.Test(StateChangeCullMode())) {
- m_pdevice3D->SetCullMode(m_pstateDevice->m_cullMode);
- }
- if (maskChanges.Test(StateChangeZTest())) {
- m_pdevice3D->SetZTest(m_pstateDevice->m_bZTest);
- }
- if (maskChanges.Test(StateChangeZWrite())) {
- m_pdevice3D->SetZWrite(m_pstateDevice->m_bZWrite);
- }
- if (maskChanges.Test(StateChangeLinearFilter())) {
- m_pdevice3D->SetLinearFilter(m_pstateDevice->m_bLinearFilter);
- }
- if (maskChanges.Test(StateChangePerspectiveCorrection())) {
- m_pdevice3D->SetPerspectiveCorrection(m_pstateDevice->m_bPerspectiveCorrection);
- }
- if (maskChanges.Test(StateChangeDither())) {
- m_pdevice3D->SetDither(m_pstateDevice->m_bDither);
- }
- if (maskChanges.Test(StateChangeColorKey())) {
- m_pdevice3D->SetColorKey(m_pstateDevice->m_bColorKey);
- }
- if (maskChanges.Test(StateChangeLineWidth())) {
- m_pdevice3D->SetLineWidth(m_pstateDevice->m_lineWidth);
- }
- }
- m_pstateDevice->m_maskChanges.Clear(StateChangeAll());
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Push and Pop
- //
- //////////////////////////////////////////////////////////////////////////////
- void PushState()
- {
- m_pstate = new State(m_pstate);
- }
- void PopState()
- {
- const StateChange& maskChanges = m_pstate->m_maskChanges;
- if (maskChanges.Test(stCommon)) {
- if (maskChanges.Test(StateChangeMatrix())) {
- m_pstateDevice->m_mat = m_pstate->m_mat;
- }
- if (maskChanges.Test(StateChangeMaterial())) {
- m_pstateDevice->m_pmaterial = m_pstate->m_pmaterial;
- }
- if (maskChanges.Test(StateChangeTexture())) {
- m_pstateDevice->m_psurfaceTexture = m_pstate->m_psurfaceTexture;
- }
- }
- if (maskChanges.Test(stUncommon)) {
- if (maskChanges.Test(StateChangeDeformation())) {
- m_pstateDevice->m_pdeform = m_pstate->m_pdeform;
- }
- if (maskChanges.Test(StateChangeClipPlanes())) {
- while (m_pstateDevice->m_countClipPlanes > m_pstate->m_countClipPlanes) {
- m_pdevice3D->RemoveClipPlane(0);
- m_pstateDevice->m_countClipPlanes--;
- }
- }
- if (maskChanges.Test(StateChangeColor())) {
- m_pstateDevice->m_color = m_pstate->m_color;
- }
- if (maskChanges.Test(StateChangeClipRect())) {
- m_pstateDevice->m_rectClip = m_pstate->m_rectClip;
- }
- if (maskChanges.Test(StateChangePerspectiveMatrix())) {
- m_pstateDevice->m_matPerspective = m_pstate->m_matPerspective;
- }
- if (maskChanges.Test(StateChangeShadeMode())) {
- m_pstateDevice->m_shadeMode = m_pstate->m_shadeMode;
- }
- if (maskChanges.Test(StateChangeBlendMode())) {
- m_pstateDevice->m_blendMode = m_pstate->m_blendMode;
- }
- if (maskChanges.Test(StateChangeWrapMode())) {
- m_pstateDevice->m_wrapMode = m_pstate->m_wrapMode;
- }
- if (maskChanges.Test(StateChangeCullMode())) {
- m_pstateDevice->m_cullMode = m_pstate->m_cullMode;
- }
- if (maskChanges.Test(StateChangeZTest())) {
- m_pstateDevice->m_bZTest = m_pstate->m_bZTest;
- }
- if (maskChanges.Test(StateChangeZWrite())) {
- m_pstateDevice->m_bZWrite = m_pstate->m_bZWrite;
- }
- if (maskChanges.Test(StateChangeLinearFilter())) {
- m_pstateDevice->m_bLinearFilter = m_pstate->m_bLinearFilter;
- }
- if (maskChanges.Test(StateChangePerspectiveCorrection())) {
- m_pstateDevice->m_bPerspectiveCorrection = m_pstate->m_bPerspectiveCorrection;
- }
- if (maskChanges.Test(StateChangeDither())) {
- m_pstateDevice->m_bDither = m_pstate->m_bDither;
- }
- if (maskChanges.Test(StateChangeColorKey())) {
- m_pstateDevice->m_bColorKey = m_pstate->m_bColorKey;
- }
- if (maskChanges.Test(StateChangeLineWidth())) {
- m_pstateDevice->m_lineWidth = m_pstate->m_lineWidth;
- }
- }
- m_pstateDevice->m_maskChanges.Set(m_pstate->m_maskChanges);
- m_pstateDevice->m_maskOverride.Clear(m_pstate->m_maskOverride);
- m_pstate = m_pstate->m_pnext;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Clipping Rect
- //
- //////////////////////////////////////////////////////////////////////////////
- Point Transform2D(const Point& point)
- {
- Point pointImage;
- ZVerify(TransformLocalToImage(Vector(point.X(), point.Y(), 0), pointImage));
- return pointImage;
- }
- WinRect GetSurfaceClipRect()
- {
- return
- WinRect(
- int(m_pstateDevice->m_rectClip.XMin()),
- m_psurface->GetSize().Y() - int(m_pstateDevice->m_rectClip.YMax()),
- int(m_pstateDevice->m_rectClip.XMax()),
- m_psurface->GetSize().Y() - int(m_pstateDevice->m_rectClip.YMin())
- );
- }
- void Clip(const Rect& rect)
- {
- ZAssert(!m_bIn3DLayer);
- if (!m_pstate->m_maskChanges.Test(StateChangeClipRect())) {
- m_pstate->m_rectClip = m_pstateDevice->m_rectClip;
- m_pstate->m_maskChanges.Set(StateChangeClipRect());
- }
- m_pstateDevice->m_rectClip.Intersect(
- Rect(
- Transform2D(rect.Min()),
- Transform2D(rect.Max())
- )
- );
- m_pstateDevice->m_maskChanges.Set(StateChangeClipRect());
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Clipping planes
- //
- //////////////////////////////////////////////////////////////////////////////
- void AddClipPlane(const Plane& plane)
- {
- if (!m_pstate->m_maskChanges.Test(StateChangeClipPlanes())) {
- m_pstate->m_countClipPlanes = m_pstateDevice->m_countClipPlanes;
- m_pstate->m_maskChanges.Set(StateChangeClipPlanes());
- }
- UpdateState();
- m_pdevice3D->AddClipPlane(plane);
- m_pstateDevice->m_countClipPlanes++;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // 3D Modeling Transforms
- //
- //////////////////////////////////////////////////////////////////////////////
- void PreMatrixChanged()
- {
- ZAssert(m_bIn3DLayer);
- if (!m_pstate->m_maskChanges.Test(StateChangeMatrix())) {
- m_pstate->m_mat = m_pstateDevice->m_mat;
- m_pstate->m_maskChanges.Set(StateChangeMatrix());
- }
- m_pstateDevice->m_maskChanges.Set(StateChangeMatrix());
- }
- void SetTransform(const Matrix& mat)
- {
- PreMatrixChanged();
- m_pstateDevice->m_mat = mat;
- }
- void Multiply(const Matrix& mat)
- {
- PreMatrixChanged();
- m_pstateDevice->m_mat.PreMultiply(mat);
- }
- void Rotate(const Vector& vec, float angle)
- {
- PreMatrixChanged();
- m_pstateDevice->m_mat.PreRotate(vec, angle);
- }
- void Translate(const Vector& vec)
- {
- PreMatrixChanged();
- m_pstateDevice->m_mat.PreTranslate(vec);
- }
- void Scale(const Vector& vec)
- {
- PreMatrixChanged();
- m_pstateDevice->m_mat.PreScale(vec);
- }
- void Scale3(float scale)
- {
- PreMatrixChanged();
- m_pstateDevice->m_mat.PreScale(scale);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // 2D Modeling Transforms
- //
- //////////////////////////////////////////////////////////////////////////////
- void PrePerspectiveMatrixChanged()
- {
- ZAssert(!m_bIn3DLayer);
- if (!m_pstate->m_maskChanges.Test(StateChangePerspectiveMatrix())) {
- m_pstate->m_matPerspective = m_pstateDevice->m_matPerspective;
- m_pstate->m_maskChanges.Set(StateChangePerspectiveMatrix());
- }
- m_pstateDevice->m_maskChanges.Set(StateChangePerspectiveMatrix());
- }
- void SetMatrix(const Matrix2& mat)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective = mat;
- }
- void Multiply(const Matrix2& mat)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective.PreMultiply(mat);
- }
- void Rotate(float angle)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective.PreRotate(Vector(0, 0, 1), angle);
- }
- void Translate(const Point& point)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective.PreTranslate(Vector(point.X(), point.Y(), 0));
- }
- void Scale(const Point& point)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective.PreScale(Vector(point.X(), point.Y(), 0));
- }
- void Scale2(float scale)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective.PreScale(Vector(scale, scale, 1));
- }
- void SetPerspectiveMatrix(const Matrix& mat)
- {
- PrePerspectiveMatrixChanged();
- m_pstateDevice->m_matPerspective.PreMultiply(mat);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Transform Operations
- //
- //////////////////////////////////////////////////////////////////////////////
- const Matrix& GetLocalToEyeMatrix()
- {
- return m_pstateDevice->m_mat;
- }
- const Matrix& GetEyeToLocalMatrix()
- {
- UpdateState();
- return m_pdevice3D->GetInverseModelMatrix();
- }
- Vector TransformEyeToLocal(const Vector& vec)
- {
- return GetEyeToLocalMatrix().Transform(vec);
- }
- Vector TransformLocalToEye(const Vector& vec)
- {
- return GetLocalToEyeMatrix().Transform(vec);
- }
- Vector TransformDirectionToEye(const Vector& vec)
- {
- HVector hvec = m_pstateDevice->m_mat.Transform(HVector(vec.X(), vec.Y(), vec.Z(), 0));
- return Vector(hvec.X(), hvec.Y(), hvec.Z());
- }
- bool TransformEyeToImage(const Vector& vecEye, Point& point)
- {
- HVector hvecImage = m_pstateDevice->m_matPerspective.Transform(HVector(vecEye));
- if (hvecImage.W() < 0) {
- return false;
- }
- float rhw = 1.0f / hvecImage.W();
- point =
- Point(
- rhw * hvecImage.X(),
- rhw * hvecImage.Y()
- );
- return true;
- }
- bool TransformDirectionToImage(const Vector& vec, Point& point)
- {
- return TransformEyeToImage(TransformDirectionToEye(vec), point);
- }
- bool TransformLocalToImage(const Vector& vec, Point& point)
- {
- return TransformEyeToImage(TransformLocalToEye(vec), point);
- }
- WinPoint TransformImageToSurface(const Point& point)
- {
- const WinPoint& size = m_psurface->GetSize();
- return
- WinPoint(
- MakeInt(point.X()),
- size.Y() - MakeInt(point.Y())
- );
- }
- float GetImageRadius(const Vector& vec, float radius)
- {
- Vector vecEye = TransformLocalToEye(vec);
- Point point;
- if (TransformEyeToImage(vecEye, point)) {
- Point pointRadius;
- if (TransformEyeToImage(vecEye + Vector(radius, 0, 0), pointRadius)) {
- return pointRadius.X() - point.X();
- }
- }
- return radius;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Lighting
- //
- //////////////////////////////////////////////////////////////////////////////
- void DirectionalLight(const Vector& vec, const Color& color)
- {
- UpdateState();
- m_pdevice3D->DirectionalLight(vec, color);
- }
- void BidirectionalLight(const Vector& direction, const Color& color, const Color& colorAlt)
- {
- UpdateState();
- m_pdevice3D->BidirectionalLight(direction, color, colorAlt);
- }
- void SetAmbientLevel(float ambientLevel)
- {
- // , this should be on the state stack
- m_pdevice3D->SetAmbientLevel(ambientLevel);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Callbacks
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawCallbackGeo(IGeoCallback* pgeoCallback, bool bSortObject)
- {
- if (m_bIn3DLayer) {
- if (m_bRenderingCallbacks) {
- PushState();
- pgeoCallback->RenderCallback(this);
- PopState();
- } else {
- if (bSortObject) {
- GeoCallbackData dataNew;
- dataNew.m_mat = m_pstateDevice->m_mat;
- dataNew.m_pgeoCallback = pgeoCallback;
- dataNew.m_distance = m_pstateDevice->m_mat.GetTranslate().LengthSquared();
- m_listGeoCallbacksSorted.InsertSorted(dataNew);
- } else {
- m_listGeoCallbacks.PushFront();
- GeoCallbackData& data = m_listGeoCallbacks.GetFront();
- data.m_mat = m_pstateDevice->m_mat;
- data.m_pgeoCallback = pgeoCallback;
- }
- }
- } else {
- //
- // Drawing a geo in 2D. Draw it now even though it is a callback geo
- //
- pgeoCallback->RenderCallback(this);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Buffers
- //
- //////////////////////////////////////////////////////////////////////////////
- void SizeVertexBuffer(int count)
- {
- if (m_countVertexBuffer < count) {
- m_countVertexBuffer = count;
- m_pvertexBuffer = (Vertex*)realloc(m_pvertexBuffer, sizeof(Vertex) * count);
- }
- }
- void SizeIndexBuffer(int count)
- {
- if (m_countIndexBuffer < count) {
- m_countIndexBuffer = count;
- m_pindexBuffer = (MeshIndex*)realloc(m_pindexBuffer, sizeof(MeshIndex) * count);
- }
- }
- Vertex* GetVertexBuffer(int count)
- {
- SizeVertexBuffer(count);
- return m_pvertexBuffer;
- }
- MeshIndex* GetIndexBuffer(int count)
- {
- SizeIndexBuffer(count);
- return m_pindexBuffer;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Buffers implemented by Device3D
- //
- //////////////////////////////////////////////////////////////////////////////
- VertexL* GetVertexLBuffer(int count)
- {
- return m_pdevice3D->GetVertexLBuffer(count);
- }
- VertexScreen* GetVertexScreenBuffer(int count)
- {
- return m_pdevice3D->GetVertexScreenBuffer(count);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Context Drawing modes
- //
- //////////////////////////////////////////////////////////////////////////////
- void DD2D()
- {
- ZAssert(m_bRendering);
- ZAssert(!m_bIn3DLayer);
- EndScene();
- UpdateState();
- }
- void Texture2D()
- {
- ZAssert(m_bRendering);
- ZAssert(!m_bIn3DLayer);
- BeginScene();
- UpdateState();
- }
- void Mode3D()
- {
- ZAssert(m_bRendering);
- if (!m_bIn3DLayer) {
- Texture2D();
- } else {
- ZAssert(m_bInScene);
- UpdateState();
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // External Rendering Calls
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawTriangles(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- if (icount != 0) {
- Mode3D();
- m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
- }
- }
- void DrawTriangles(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- if (icount != 0) {
- Mode3D();
- m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
- }
- }
- void DrawTriangles(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- if (icount != 0) {
- Mode3D();
- m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
- }
- }
- void DrawTriangles(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- Mode3D();
- m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
- }
- void DrawLineStrip(const Vertex* pvertex, int vcount)
- {
- int icount = (vcount - 1) * 2;
- MeshIndex* pindex = GetIndexBuffer(icount);
- for (int index = 0; index < vcount - 1; index++) {
- pindex[index * 2 ] = index;
- pindex[index * 2 + 1] = index + 1;
- }
- DrawLines(pvertex, vcount, pindex, icount);
- }
- void DrawLineStrip(const VertexL* pvertex, int vcount)
- {
- int icount = (vcount - 1) * 2;
- MeshIndex* pindex = GetIndexBuffer(icount);
- for (int index = 0; index < vcount - 1; index++) {
- pindex[index * 2 ] = index;
- pindex[index * 2 + 1] = index + 1;
- }
- DrawLines(pvertex, vcount, pindex, icount);
- }
- void DrawLineStrip(const VertexScreen* pvertex, int vcount)
- {
- int icount = (vcount - 1) * 2;
- MeshIndex* pindex = GetIndexBuffer(icount);
- for (int index = 0; index < vcount - 1; index++) {
- pindex[index * 2 ] = index;
- pindex[index * 2 + 1] = index + 1;
- }
- DrawLines(pvertex, vcount, pindex, icount);
- }
- void DrawLineStrip(const D3DVertex* pvertex, int vcount)
- {
- int icount = (vcount - 1) * 2;
- MeshIndex* pindex = GetIndexBuffer(icount);
- for (int index = 0; index < vcount - 1; index++) {
- pindex[index * 2 ] = index;
- pindex[index * 2 + 1] = index + 1;
- }
- DrawLines(pvertex, vcount, pindex, icount);
- }
- void DrawLines(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- if (icount != 0) {
- Mode3D();
- m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
- }
- }
- void DrawLines(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- if (icount != 0) {
- Mode3D();
- m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
- }
- }
- void DrawLines(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- if (icount != 0) {
- Mode3D();
- m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
- }
- }
- void DrawLines(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
- {
- Mode3D();
- m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
- }
- void DrawPoints(const Vertex* pvertex, int vcount)
- {
- if (vcount != 0) {
- Mode3D();
- m_pdevice3D->DrawPoints(pvertex, vcount);
- }
- }
- void DrawPoints(const VertexL* pvertex, int vcount)
- {
- if (vcount != 0) {
- Mode3D();
- m_pdevice3D->DrawPoints(pvertex, vcount);
- }
- }
- void DrawPoints(const VertexScreen* pvertex, int vcount)
- {
- if (vcount != 0) {
- Mode3D();
- m_pdevice3D->DrawPoints(pvertex, vcount);
- }
- }
- void DrawPoints(const D3DVertex* pvertex, int vcount)
- {
- Mode3D();
- m_pdevice3D->DrawPoints(pvertex, vcount);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Vector Rendering Calls
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawTriangles(const TVector<Vertex>& vertices, const TVector<MeshIndex>& indices)
- {
- DrawTriangles(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
- }
- void DrawTriangles(const TVector<VertexL>& vertices, const TVector<MeshIndex>& indices)
- {
- DrawTriangles(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
- }
- void DrawTriangles(const TVector<D3DVertex>& vertices, const TVector<MeshIndex>& indices)
- {
- DrawTriangles(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
- }
- void DrawLines(const TVector<Vertex>& vertices, const TVector<MeshIndex>& indices)
- {
- DrawLines(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
- }
- void DrawLines(const TVector<VertexL>& vertices, const TVector<MeshIndex>& indices)
- {
- DrawLines(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
- }
- void DrawLines(const TVector<D3DVertex>& vertices, const TVector<MeshIndex>& indices)
- {
- DrawLines(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
- }
- void DrawPoints(const TVector<Vertex>& vertices)
- {
- DrawPoints(&(vertices[0]), vertices.GetCount());
- }
- void DrawPoints(const TVector<VertexL>& vertices)
- {
- DrawPoints(&(vertices[0]), vertices.GetCount());
- }
- void DrawPoints(const TVector<D3DVertex>& vertices)
- {
- DrawPoints(&(vertices[0]), vertices.GetCount());
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // Add a new Decal
- //
- //////////////////////////////////////////////////////////////////////////////
- Decal& AddDecal(TVector<DecalSet>& vdecalSet, Surface* psurface)
- {
- //
- // find the associated decal set
- //
- int countDecalSets = vdecalSet.GetCount();
- for(int indexSet = 0; indexSet < countDecalSets; indexSet++) {
- const DecalSet& set = vdecalSet[indexSet];
- if (psurface == set.m_psurface) {
- break;
- }
- }
- //
- // Add a new decal set
- //
- if (indexSet == countDecalSets) {
- vdecalSet.PushEnd();
- vdecalSet.Get(indexSet).m_psurface = psurface;
- }
- DecalSet& set = vdecalSet.Get(indexSet);
- //
- // Return a reference to the newly created decal
- //
- set.m_vdecal.PushEnd();
- return set.m_vdecal.Get(set.m_vdecal.GetCount() - 1);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Draw a Decal so that it faces the eye point and lies along a direction vector
- //
- //////////////////////////////////////////////////////////////////////////////
- float DrawDecal(
- Surface* psurface,
- const Color& color,
- const Vector& positionLocal,
- const Vector& forwardLocal,
- const Vector& rightLocal,
- float scale,
- float angle,
- BlendMode blendMode
- ) {
- ZAssert(
- blendMode == BlendModeSource
- || blendMode == BlendModeAdd
- );
- const Matrix& mat = GetLocalToEyeMatrix();
- Vector position = mat.Transform(positionLocal);
- if (position.Z() < 0) {
- Decal& decal =
- AddDecal(
- blendMode == BlendModeSource
- ? m_vdecalSetOpaque
- : m_vdecalSet,
- psurface
- );
- float sizeScale = 4.0f / (position.Z() * position.Z());
- float scaleMat = mat.GetScale();
- decal.m_position = position;
- decal.m_color = color;
- decal.m_angle = angle;
- decal.m_scale = scaleMat * scale;
- if (forwardLocal.IsZero()) {
- decal.m_forward = Vector(0, 0, 0);
- return sizeScale * decal.m_scale * decal.m_scale;
- } else {
- decal.m_forward = scaleMat * mat.TransformDirection(forwardLocal);
- if (rightLocal.IsZero()) {
- Vector right = decal.m_forward.GetOrthogonalVector();
- float lengthForward = forwardLocal.Length();
- float lengthRight = decal.m_scale * lengthForward;
- decal.m_right = lengthRight * right.Normalize();
- return sizeScale * lengthForward * lengthRight;
- } else {
- decal.m_right = scaleMat * mat.TransformDirection(rightLocal);
- return sizeScale * decal.m_right.Length() * decal.m_forward.Length();
- }
- }
- }
- return 0;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Decal Drawing
- //
- //////////////////////////////////////////////////////////////////////////////
- void DrawVDecalSet(TVector<DecalSet>& vdecalSet)
- {
- //
- // Iterate through the decal sets
- //
- int countDecalSets = vdecalSet.GetCount();
- for(int indexSet = 0; indexSet < countDecalSets; indexSet++) {
- DecalSet& set = vdecalSet.Get(indexSet);
- int countDecal = set.m_vdecal.GetCount();
- if (countDecal > 0) {
- SetTexture(set.m_psurface, false);
- VertexL* pvertex = GetVertexLBuffer(countDecal * 4);
- MeshIndex* pindex = GetIndexBuffer(countDecal * 6);
- for (int index = 0; index < countDecal; index++) {
- set.m_vdecal[index].GetVertices(pvertex + index * 4);
- pindex[index * 6 + 0] = index * 4 + 0;
- pindex[index * 6 + 1] = index * 4 + 2;
- pindex[index * 6 + 2] = index * 4 + 1;
- pindex[index * 6 + 3] = index * 4 + 0;
- pindex[index * 6 + 4] = index * 4 + 3;
- pindex[index * 6 + 5] = index * 4 + 2;
- }
- UpdateState();
- m_pdevice3D->DrawTriangles(
- &pvertex[0],
- index * 4,
- &pindex[0],
- index * 6
- );
- set.m_vdecal.SetCount(0);
- }
- }
- }
- void DrawCachedDecals()
- {
- //
- // Render States
- //
- SetCullMode(CullModeNone, false);
- SetShadeMode(ShadeModeFlat, false);
- SetTransform(Matrix::GetIdentity());
- //
- // Opaque decals first
- //
- SetBlendMode(BlendModeSource, false);
- SetZWrite(true, false);
- DrawVDecalSet(m_vdecalSetOpaque);
- //
- // Emissive Transparent decals
- //
- SetBlendMode(BlendModeAdd, false);
- SetZWrite(false, false);
- DrawVDecalSet(m_vdecalSet);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Performance Counters
- //
- //////////////////////////////////////////////////////////////////////////////
- #ifdef EnablePerformanceCounters
- int GetPerformanceCounter(Counter counter)
- {
- if (counter == CounterDrawStrings)
- return m_countDrawString;
- else if (counter == CounterDrawStringChars)
- return m_countDrawStringChars;
- return m_pdevice3D->GetPerformanceCounter(counter);
- }
- void ResetPerformanceCounters()
- {
- m_countDrawString = 0;
- m_countDrawStringChars = 0;
- m_pdevice3D->ResetPerformanceCounters();
- }
- #endif
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Constructor
- //
- //////////////////////////////////////////////////////////////////////////////
- TRef<PrivateContext> CreateContextImpl(PrivateSurface* psurface)
- {
- return new ContextImpl(psurface);
- }
|