Allow objects to use a mesh instead of pixel-based graphics

stable-5.2
Armin Burgmeier 2009-07-11 01:10:18 +02:00
parent a3f1ccf66e
commit 01f2da1366
14 changed files with 307 additions and 27 deletions

View File

@ -85,6 +85,8 @@
#define C4CFN_IconPNG "Icon.png"
#define C4CFN_ScenarioObjects "Objects.txt"
#define C4CFN_ScenarioDesc "Desc%s.rtf"
#define C4CFN_DefMaterials "*.material"
#define C4CFN_DefMesh "Graphics.mesh.xml"
#define C4CFN_DefGraphics "Graphics.bmp"
#define C4CFN_DefGraphicsPNG "Graphics.png"
#define C4CFN_ClrByOwnerPNG "Overlay.png"

View File

@ -44,16 +44,30 @@ class C4DefGraphics
C4DefGraphics *GetLast(); // get last graphics in list
public:
C4Surface *Bitmap, *BitmapClr;
enum GraphicsType {
TYPE_Bitmap,
TYPE_Mesh
};
GraphicsType Type;
union {
struct {
C4Surface *Bitmap, *BitmapClr;
};
StdMesh *Mesh;
};
bool fColorBitmapAutoCreated; // if set, the color-by-owner-bitmap has been created automatically by all blue shades of the bitmap
inline C4Surface *GetBitmap(DWORD dwClr=0) { if (BitmapClr) { BitmapClr->SetClr(dwClr); return BitmapClr; } else return Bitmap; }
inline C4Surface *GetBitmap(DWORD dwClr=0) { if(Type != TYPE_Bitmap) return NULL; if (BitmapClr) { BitmapClr->SetClr(dwClr); return BitmapClr; } else return Bitmap; }
C4DefGraphics(C4Def *pOwnDef=NULL); // ctor
virtual ~C4DefGraphics() { Clear(); }; // dtor
bool LoadBitmap(C4Group &hGroup, const char *szFilename, const char *szFilenamePNG, const char *szOverlayPNG, bool fColorByOwner); // load specified graphics from group
bool LoadBitmaps(C4Group &hGroup, bool fColorByOwner); // load graphics from group
bool LoadMesh(C4Group &hGroup, StdMeshSkeletonLoader& loader);
bool Load(C4Group &hGroup, bool fColorByOwner); // load graphics from group
bool ColorizeByMaterial(int32_t iMat, C4MaterialMap &rMats, BYTE bGBM); // colorize all graphics by material
C4DefGraphics *Get(const char *szGrpName); // get graphics by name
void Clear(); // clear fields; delete additional graphics

View File

@ -24,7 +24,7 @@
#ifndef INC_C4Game
#define INC_C4Game
#include <StdMeshMaterial.h>
#include <C4GameParameters.h>
#include <C4PlayerInfo.h>
#include <C4RoundResults.h>
@ -82,7 +82,7 @@ class C4Game
C4PathFinder PathFinder;
C4TransferZones TransferZones;
C4Group ScenarioFile;
C4Group ScenarioFile;
C4GroupSet GroupSet;
C4Group *pParentGroup;
C4Extra Extra;
@ -94,6 +94,7 @@ class C4Game
#endif
C4Scoreboard Scoreboard;
C4VideoPlayer VideoPlayer;
StdMeshMatManager MaterialManager;
class C4Network2Stats *pNetworkStatistics; // may be NULL if no statistics are recorded
class C4KeyboardInput &KeyboardInput;
class C4FileMonitor *pFileMonitor;

View File

@ -178,6 +178,7 @@ class C4Object
C4NotifyingObjectList Contents;
C4MaterialList *MaterialContents; // SyncClearance-NoSave //
C4DefGraphics *pGraphics; // currently set object graphics
StdMeshInstance* pMeshInstance; // Instance for mesh-type objects
C4Effect *pEffects; // linked list of effects
C4ParticleList FrontParticles, BackParticles; // lists of object local particles
@ -260,6 +261,7 @@ class C4Object
void DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal);
void DrawActionFace(C4TargetFacet &cgo, float offX, float offY);
void DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPhaseX=0, int32_t iPhaseY=0);
void DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy, float fwdt, float fhgt, float tx, float ty, float twdt, float thgt, C4DrawTransform* transform);
void Execute();
void ClearPointers(C4Object *ptr);
BOOL ExecMovement();

View File

@ -605,7 +605,7 @@ BOOL C4Def::Load(C4Group &hGroup,
// Read surface bitmap
if (dwLoadWhat & C4D_Load_Bitmap)
if (!Graphics.LoadBitmaps(hGroup, !!ColorByOwner))
if (!Graphics.Load(hGroup, !!ColorByOwner))
{
DebugLogF(" Error loading graphics of %s (%s)", hGroup.GetFullName().getData(), C4IdText(id));
return FALSE;
@ -866,14 +866,30 @@ void C4Def::Draw(C4Facet &cgo, BOOL fSelected, DWORD iColor, C4Object *pObj, int
// if assigned: use object specific rect and graphics
if (pObj) if(pObj->PictureRect.Wdt) fctPicRect = pObj->PictureRect;
fctPicture.Set((pObj ? *pObj->GetGraphics() : Graphics).GetBitmap(iColor),fctPicRect.x,fctPicRect.y,fctPicRect.Wdt,fctPicRect.Hgt);
if (fSelected)
Application.DDraw->DrawBox(cgo.Surface,cgo.X,cgo.Y,cgo.X+cgo.Wdt-1,cgo.Y+cgo.Hgt-1,CRed);
C4DefGraphics* graphics = pObj ? pObj->GetGraphics() : &Graphics;
// specific object color?
if (pObj) pObj->PrepareDrawing();
fctPicture.Draw(cgo,TRUE,iPhaseX,iPhaseY,TRUE);
switch(graphics->Type)
{
case C4DefGraphics::TYPE_Bitmap:
fctPicture.Set((pObj ? *pObj->GetGraphics() : Graphics).GetBitmap(iColor),fctPicRect.x,fctPicRect.y,fctPicRect.Wdt,fctPicRect.Hgt);
fctPicture.Draw(cgo,TRUE,iPhaseX,iPhaseY,TRUE);
break;
case C4DefGraphics::TYPE_Mesh:
{
// TODO: Allow rendering of a mesh directly, without instance
StdMeshInstance dummy(*graphics->Mesh);
// TODO: Keep aspect ratio of mesh dimensions
lpDDraw->RenderMesh(dummy, cgo.Surface, cgo.X, cgo.Y, cgo.Wdt, cgo.Hgt);
}
break;
}
if (pObj) pObj->FinishedDrawing();
// draw overlays

View File

@ -42,6 +42,35 @@
#include <C4GameObjects.h>
#endif
// Helper class to load additional ressources required for meshes from
// a C4Group.
class AdditionalRessourcesLoader:
public StdMeshMaterialTextureLoader, public StdMeshSkeletonLoader
{
public:
AdditionalRessourcesLoader(C4Group& hGroup): Group(hGroup) {}
virtual bool LoadTexture(const char* filename, CPNGFile& dest)
{
char* buf;
size_t size;
if(!Group.LoadEntry(filename, &buf, &size, 1)) return false;
bool ret = dest.Load(reinterpret_cast<BYTE*>(buf), size);
delete[] buf;
return ret;
}
virtual StdStrBuf LoadSkeleton(const char* filename)
{
StdStrBuf ret;
if(!Group.LoadEntryString(filename, ret)) return StdStrBuf();
return ret;
}
private:
C4Group& Group;
};
//-------------------------------- C4DefGraphics -----------------------------------------------
C4DefGraphics::C4DefGraphics(C4Def *pOwnDef)
@ -49,6 +78,7 @@ C4DefGraphics::C4DefGraphics(C4Def *pOwnDef)
// store def
pDef = pOwnDef;
// zero fields
Type = TYPE_Bitmap;
Bitmap = BitmapClr = NULL;
pNext = NULL;
fColorBitmapAutoCreated = false;
@ -64,8 +94,17 @@ C4DefGraphics *C4DefGraphics::GetLast()
void C4DefGraphics::Clear()
{
// zero own fields
if (BitmapClr) { delete BitmapClr; BitmapClr=NULL; }
if (Bitmap) { delete Bitmap; Bitmap=NULL; }
switch (Type)
{
case TYPE_Bitmap:
if (BitmapClr) { delete BitmapClr; BitmapClr=NULL; }
if (Bitmap) { delete Bitmap; Bitmap=NULL; }
break;
case TYPE_Mesh:
if (Mesh) { delete Mesh; Mesh = NULL; }
break;
}
// delete additonal graphics
C4AdditionalDefGraphics *pGrp2N = pNext, *pGrp2;
while (pGrp2=pGrp2N) { pGrp2N = pGrp2->pNext; pGrp2->pNext = NULL; delete pGrp2; }
@ -116,17 +155,74 @@ bool C4DefGraphics::LoadBitmap(C4Group &hGroup, const char *szFilename, const ch
if (!BitmapClr->CreateColorByOwner(Bitmap)) return false;
fColorBitmapAutoCreated = true;
}
Type = TYPE_Bitmap;
// success
return true;
}
bool C4DefGraphics::LoadBitmaps(C4Group &hGroup, bool fColorByOwner)
bool C4DefGraphics::LoadMesh(C4Group &hGroup, StdMeshSkeletonLoader& loader)
{
char* buf;
size_t size;
if(!hGroup.LoadEntry(C4CFN_DefMesh, &buf, &size, 1)) return false;
Mesh = new StdMesh;
bool result;
try
{
Mesh->InitXML(C4CFN_DefMesh, buf, loader, Game.MaterialManager);
result = true;
}
catch(const StdMeshError& ex)
{
DebugLogF("Failed to load mesh: %s\n", ex.what());
result = false;
}
delete[] buf;
if(!result)
{
delete Mesh;
Mesh = NULL;
return false;
}
Type = TYPE_Mesh;
return true;
}
bool C4DefGraphics::Load(C4Group &hGroup, bool fColorByOwner)
{
char Filename[_MAX_PATH+1]; *Filename=0;
AdditionalRessourcesLoader loader(hGroup);
// Load all materials for this definition:
hGroup.ResetSearch();
while (hGroup.FindNextEntry(C4CFN_DefMaterials, Filename, NULL, NULL, !!*Filename))
{
StdStrBuf material;
if(hGroup.LoadEntryString(Filename, material))
{
try
{
Game.MaterialManager.Parse(material.getData(), Filename, loader);
}
catch(const StdMeshMaterialError& ex)
{
DebugLogF("Failed to read material script: %s\n", ex.what());
}
}
}
// Try from Mesh first
if (LoadMesh(hGroup, loader)) return true;
// load basic graphics
if (!LoadBitmap(hGroup, C4CFN_DefGraphics, C4CFN_DefGraphicsPNG, C4CFN_ClrByOwnerPNG, fColorByOwner)) return false;
// load additional graphics
// first, search all png-graphics in NewGfx
char Filename[_MAX_PATH+1]; *Filename=0;
C4DefGraphics *pLastGraphics = this;
int32_t iWildcardPos;
iWildcardPos = SCharPos('*', C4CFN_DefGraphicsExPNG);
@ -229,6 +325,8 @@ bool C4DefGraphics::LoadBitmaps(C4Group &hGroup, bool fColorByOwner)
bool C4DefGraphics::ColorizeByMaterial(int32_t iMat, C4MaterialMap &rMats, BYTE bGBM)
{
if(Type != TYPE_Bitmap) return false;
SURFACE sfcBitmap = GetBitmap(); // first bitmap only
if (sfcBitmap)
{
@ -265,6 +363,7 @@ C4PortraitGraphics *C4PortraitGraphics::Get(const char *szGrpName)
bool C4DefGraphics::CopyGraphicsFrom(C4DefGraphics &rSource)
{
if (Type != TYPE_Bitmap) return false; // TODO!
// clear previous
if (BitmapClr) { delete BitmapClr; BitmapClr=NULL; }
if (Bitmap) { delete Bitmap; Bitmap=NULL; }
@ -291,6 +390,7 @@ bool C4DefGraphics::CopyGraphicsFrom(C4DefGraphics &rSource)
void C4DefGraphics::DrawClr(C4Facet &cgo, BOOL fAspect, DWORD dwClr)
{
if(Type != TYPE_Bitmap) return; // TODO
// create facet and draw it
C4Surface *pSfc = BitmapClr ? BitmapClr : Bitmap; if (!pSfc) return;
C4Facet fct(pSfc, 0,0,pSfc->Wdt, pSfc->Hgt);
@ -507,7 +607,7 @@ bool C4Portrait::Link(C4DefGraphics *pGfxPortrait)
bool C4Portrait::SavePNG(C4Group &rGroup, const char *szFilename, const char *szOverlayFN)
{
// safety
if (!pGfxPortrait || !szFilename || !pGfxPortrait->Bitmap) return false;
if (!pGfxPortrait || !szFilename || pGfxPortrait->Type != C4DefGraphics::TYPE_Bitmap || !pGfxPortrait->Bitmap) return false;
// save files
if (pGfxPortrait->fColorBitmapAutoCreated)
{
@ -616,6 +716,7 @@ void C4GraphicsOverlay::UpdateFacet()
if (eMode == MODE_Object) return;
// otherwise, source graphics must be specified
if (!pSourceGfx) return;
if (pSourceGfx->Type != C4DefGraphics::TYPE_Bitmap) return;
C4Def *pDef = pSourceGfx->pDef;
assert(pDef);
fZoomToShape = false;

View File

@ -594,6 +594,7 @@ void C4Game::Clear()
KeyboardInput.Clear();
SetMusicLevel(100);
PlayList.Clear();
MaterialManager.Clear();
// global fullscreen class is not cleared, because it holds the carrier window
// but the menu must be cleared (maybe move Fullscreen.Menu somewhere else?)

View File

@ -157,6 +157,7 @@ void C4Object::Default()
pLayer=NULL;
pSolidMaskData=NULL;
pGraphics=NULL;
pMeshInstance=NULL;
pDrawTransform=NULL;
pEffects=NULL;
FirstRef=NULL;
@ -186,6 +187,10 @@ BOOL C4Object::Init(C4Def *pDef, C4Object *pCreator,
// graphics
pGraphics = &Def->Graphics;
if(pGraphics->Type == C4DefGraphics::TYPE_Mesh)
pMeshInstance = new StdMeshInstance(*pGraphics->Mesh);
else
pMeshInstance = NULL;
BlitMode = Def->BlitMode;
// Position
@ -418,6 +423,13 @@ void C4Object::UpdateGraphics(bool fGraphicsChanged, bool fTemp)
// ensure SolidMask-rect lies within new graphics-rect
CheckSolidMaskRect();
}
delete pMeshInstance;
if(pGraphics->Type == C4DefGraphics::TYPE_Mesh)
pMeshInstance = new StdMeshInstance(*pGraphics->Mesh);
else
pMeshInstance = NULL;
// update face - this also puts any SolidMask
UpdateFace(false);
}
@ -459,6 +471,25 @@ void C4Object::UpdateFlipDir()
}
}
void C4Object::DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy, float fwdt, float fhgt, float tx, float ty, float twdt, float thgt, C4DrawTransform* transform)
{
CSurface* sfc;
switch(GetGraphics()->Type)
{
case C4DefGraphics::TYPE_Bitmap:
sfc = action ? Action.Facet.Surface : GetGraphics()->GetBitmap(Color);
lpDDraw->Blit(sfc,
fx, fy, fwdt, fhgt,
cgo.Surface, tx, ty, twdt, thgt,
TRUE, transform);
break;
case C4DefGraphics::TYPE_Mesh:
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, tx, ty, twdt, thgt);
break;
}
}
void C4Object::DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPhaseX, int32_t iPhaseY)
{
const float swdt = float(Def->Shape.Wdt);
@ -488,10 +519,11 @@ void C4Object::DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPha
// Straight
if ((!Def->Rotateable || (r==0)) && !pDrawTransform)
{
lpDDraw->Blit(GetGraphics()->GetBitmap(Color),
DrawFaceImpl(cgo, false, fx, fy, fwdt, fhgt, tx, ty, twdt, thgt, NULL);
/* lpDDraw->Blit(GetGraphics()->GetBitmap(Color),
fx, fy, fwdt, fhgt,
cgo.Surface, tx, ty, twdt, thgt,
TRUE, NULL);
TRUE, NULL);*/
}
// Rotated or transformed
else
@ -506,10 +538,11 @@ void C4Object::DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPha
{
rot.SetRotate(r * 100, offX, offY);
}
lpDDraw->Blit(GetGraphics()->GetBitmap(Color),
DrawFaceImpl(cgo, false, fx, fy, fwdt, fhgt, tx, ty, twdt, thgt, &rot);
/* lpDDraw->Blit(GetGraphics()->GetBitmap(Color),
fx, fy, fwdt, fhgt,
cgo.Surface, tx, ty, twdt, thgt,
TRUE, &rot);
TRUE, &rot);*/
}
}
@ -554,10 +587,11 @@ void C4Object::DrawActionFace(C4TargetFacet &cgo, float offX, float offY)
// Straight
if ((!Def->Rotateable || (r==0)) && !pDrawTransform)
{
lpDDraw->Blit(Action.Facet.Surface,
DrawFaceImpl(cgo, true, fx, fy, fwdt, fhgt, tx, ty, twdt, thgt, NULL);
/*lpDDraw->Blit(Action.Facet.Surface,
fx, fy, fwdt, fhgt,
cgo.Surface, tx, ty, twdt, thgt,
TRUE, NULL);
TRUE, NULL);*/
}
// Rotated or transformed
else
@ -574,10 +608,11 @@ void C4Object::DrawActionFace(C4TargetFacet &cgo, float offX, float offY)
{
rot.SetRotate(r * 100, offX, offY);
}
lpDDraw->Blit(Action.Facet.Surface,
DrawFaceImpl(cgo, true, fx, fy, fwdt, fhgt, tx, ty, twdt, thgt, &rot);
/* lpDDraw->Blit(Action.Facet.Surface,
fx, fy, fwdt, fhgt,
cgo.Surface, tx, ty, twdt, thgt,
TRUE, &rot);
TRUE, &rot);*/
}
}
@ -2264,7 +2299,8 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
{ if (FrontParticles && !Contained) FrontParticles.Draw(cgo,this); return; }
// ensure correct color is set
if (GetGraphics()->BitmapClr) GetGraphics()->BitmapClr->SetClr(Color);
if (GetGraphics()->Type == C4DefGraphics::TYPE_Bitmap)
if (GetGraphics()->BitmapClr) GetGraphics()->BitmapClr->SetClr(Color);
// Debug Display //////////////////////////////////////////////////////////////////////
if (::GraphicsSystem.ShowCommand && !eDrawMode)
@ -2416,7 +2452,7 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
(fixtof(Action.Target->fix_y) + Action.Target->Shape.GetY()) - (fixtof(fix_y) + Shape.GetY() + Action.FacetY),
TRUE);
}
else if (Action.Facet.Surface)
else if (Action.Facet.Surface || GetGraphics()->Type != C4DefGraphics::TYPE_Bitmap)
DrawActionFace(cgo, offX, offY);
}
@ -3185,7 +3221,7 @@ void C4Object::Clear()
if (pEffects) { delete pEffects; pEffects=NULL; }
if (FrontParticles) FrontParticles.Clear();
if (BackParticles) BackParticles.Clear();
if (pSolidMaskData) { delete pSolidMaskData; pSolidMaskData=NULL; }
if (pSolidMaskData) { delete pSolidMaskData; pSolidMaskData=NULL; }
if (Menu) delete Menu; Menu=NULL;
if (MaterialContents) delete MaterialContents; MaterialContents=NULL;
// clear commands!
@ -3196,7 +3232,8 @@ void C4Object::Clear()
}
if (pDrawTransform) { delete pDrawTransform; pDrawTransform=NULL; }
if (pGfxOverlay) { delete pGfxOverlay; pGfxOverlay=NULL; }
while (FirstRef) FirstRef->Set(0);
if (pMeshInstance) { delete pMeshInstance; pMeshInstance = NULL; }
while (FirstRef) FirstRef->Set(0);
}
BOOL C4Object::ContainedControl(BYTE byCom)
@ -3756,6 +3793,9 @@ void C4Object::SetSolidMask(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt,
bool C4Object::CheckSolidMaskRect()
{
// SolidMasks are only supported for bitmap graphics
if(GetGraphics()->Type != C4DefGraphics::TYPE_Bitmap) return false;
// check NewGfx only, because invalid SolidMask-rects are OK in OldGfx
// the bounds-check is done in CStdDDraw::GetPixel()
CSurface *sfcGraphics = GetGraphics()->GetBitmap();

View File

@ -27,6 +27,7 @@
#include <StdSurface8.h>
#include <StdFont.h>
#include <StdBuf.h>
#include <StdMesh.h>
// texref-predef
class CStdDDraw;
@ -295,7 +296,9 @@ class CStdDDraw
BOOL Blit(SURFACE sfcSource, float fx, float fy, float fwdt, float fhgt,
SURFACE sfcTarget, float tx, float ty, float twdt, float thgt,
BOOL fSrcColKey=FALSE, CBltTransform *pTransform=NULL);
BOOL RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt);
virtual void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact) = 0;
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt) = 0;
BOOL Blit8(SURFACE sfcSource, int fx, int fy, int fwdt, int fhgt, // force 8bit-blit (inline)
SURFACE sfcTarget, int tx, int ty, int twdt, int thgt,
BOOL fSrcColKey=FALSE, CBltTransform *pTransform=NULL);

View File

@ -109,7 +109,8 @@ class CStdGL : public CStdDDraw
virtual CStdGLCtx *CreateContext(HWND hWindow, CStdApp *pApp);
#endif
// Blit
void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact);
virtual void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact);
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt);
virtual void BlitLandscape(SURFACE sfcSource, SURFACE sfcSource2, SURFACE sfcLiquidAnimation, float fx, float fy,
SURFACE sfcTarget, float tx, float ty, float wdt, float hgt);
void FillBG(DWORD dwClr=0);

View File

@ -41,6 +41,7 @@ public:
virtual bool PrepareRendering(SURFACE) { return true; }
virtual void FillBG(DWORD dwClr=0) { }
virtual void PerformBlt(CBltData &, CTexRef *, DWORD, bool, bool) { }
virtual void PerformMesh(StdMeshInstance &, float, float, float, float) { }
virtual void PerformLine(SURFACE, float, float, float, float, DWORD) { }
virtual void DrawQuadDw(SURFACE, float *, DWORD, DWORD, DWORD, DWORD) { }
virtual void PerformPix(SURFACE, float, float, DWORD) { }

View File

@ -1050,6 +1050,26 @@ BOOL CStdDDraw::Blit(SURFACE sfcSource, float fx, float fy, float fwdt, float fh
return TRUE;
}
BOOL CStdDDraw::RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt)
{
// TODO: Emulate rendering
if (!sfcTarget->IsRenderTarget()) return FALSE;
// TODO: Clip
// prepare rendering to surface
if (!PrepareRendering(sfcTarget)) return FALSE;
// store current state
StoreStateBlock();
PerformMesh(instance, tx, ty, twdt, thgt);
// restore state
RestoreStateBlock();
// success
return TRUE;
}
BOOL CStdDDraw::Blit8(SURFACE sfcSource, int fx, int fy, int fwdt, int fhgt,
SURFACE sfcTarget, int tx, int ty, int twdt, int thgt,
BOOL fSrcColKey, CBltTransform *pTransform)

View File

@ -306,6 +306,82 @@ void CStdGL::PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool
}
}
void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt)
{
const StdMesh& mesh = instance.Mesh;
const StdMeshBox& box = mesh.GetBoundingBox();
glPushMatrix();
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glDisable(GL_BLEND); // TODO: Invert alpha instead in material loader
glEnable(GL_LIGHTING);
// TODO: Zoom, ClrMod, ...
//glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
// Scale so that the mesh fits in (tx,ty,twdt,thgt)
double rx = -box.x1 / (box.x2 - box.x1);
double ry = -box.y1 / (box.y2 - box.y1);
glTranslatef(tx + rx*twdt, ty + ry*thgt, 0.0f);
glScalef(twdt/(box.x2 - box.x1), thgt/(box.y2 - box.y1), 1.0f);
// Put a light source in front of the object
GLfloat light_position[] = { 0.0f, 0.0f, 6.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
// TODO: Find a working technique, we currently always use the
// first one:
const StdMeshMaterial& material = mesh.GetMaterial();
const StdMeshMaterialTechnique& technique = material.Techniques[0];
// Render each pass
for(unsigned int i = 0; i < technique.Passes.size(); ++i)
{
const StdMeshMaterialPass& pass = technique.Passes[i];
// Set up material
glMaterialfv(GL_FRONT, GL_AMBIENT, pass.Ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, pass.Diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, pass.Specular);
glMaterialfv(GL_FRONT, GL_EMISSION, pass.Emissive);
glMaterialf(GL_FRONT, GL_SHININESS, pass.Shininess);
// TODO: Set up texture units
// Render mesh
glBegin(GL_TRIANGLES);
for(unsigned int j = 0; j < mesh.GetNumFaces(); ++j)
{
const StdMeshFace& face = mesh.GetFace(j);
const StdMeshVertex& vtx1 = instance.GetVertex(face.Vertices[0]);
const StdMeshVertex& vtx2 = instance.GetVertex(face.Vertices[1]);
const StdMeshVertex& vtx3 = instance.GetVertex(face.Vertices[2]);
glTexCoord2f(vtx1.u, vtx1.v);
glNormal3f(vtx1.nx, vtx1.ny, vtx1.nz);
glVertex3f(vtx1.x, vtx1.y, vtx1.z);
glTexCoord2f(vtx2.u, vtx2.v);
glNormal3f(vtx2.nx, vtx2.ny, vtx2.nz);
glVertex3f(vtx2.x, vtx2.y, vtx2.z);
glTexCoord2f(vtx3.u, vtx3.v);
glNormal3f(vtx3.nx, vtx3.ny, vtx3.nz);
glVertex3f(vtx3.x, vtx3.y, vtx3.z);
}
glEnd(); // GL_TRIANGLES
}
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glDisable(GL_NORMALIZE);
glEnable(GL_BLEND);
glPopMatrix();
// TODO: glScissor, so that we only clear the area the mesh covered.
glClear(GL_DEPTH_BUFFER_BIT);
}
void CStdGL::BlitLandscape(SURFACE sfcSource, SURFACE sfcSource2, SURFACE sfcLiquidAnimation, float fx, float fy,
SURFACE sfcTarget, float tx, float ty, float wdt, float hgt)
{

View File

@ -116,6 +116,7 @@ bool CStdGLCtx::Select(bool verbose)
pGL->lpPrimary->Wdt=cx; pGL->lpPrimary->Hgt=cy;
// set some default states
glDisable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glShadeModel(GL_FLAT);
glDisable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE);
@ -266,6 +267,7 @@ bool CStdGLCtx::Select(bool verbose)
pGL->lpPrimary->Wdt=cx; pGL->lpPrimary->Hgt=cy;
// set some default states
glDisable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glShadeModel(GL_FLAT);
glDisable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE);