1
0
forked from 0ad/0ad

ran everything though mark's newline stomper.

This was SVN commit r322.
This commit is contained in:
janwas 2004-05-30 00:46:58 +00:00
parent a929a3506b
commit 1eaadd38aa
171 changed files with 18571 additions and 18580 deletions

View File

@ -1,146 +1,146 @@
//***********************************************************
//
// Name: Camera.Cpp
// Last Update: 24/2/02
// Author: Poya Manouchehri
//
// Description: CCamera holds a view and a projection matrix.
// It also has a frustum which can be used to
// cull objects for rendering.
//
//***********************************************************
#include "Camera.h"
CCamera::CCamera ()
{
// set viewport to something anything should handle, but should be initialised
// to window size before use
m_ViewPort.m_X = 0;
m_ViewPort.m_Y = 0;
m_ViewPort.m_Width = 800;
m_ViewPort.m_Height = 600;
}
CCamera::~CCamera ()
{
}
void CCamera::SetProjection (float nearp, float farp, float fov)
{
float h, w, Q;
m_NearPlane = nearp;
m_FarPlane = farp;
m_FOV = fov;
float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height;
w = 1/tanf (fov*0.5f*Aspect);
h = 1/tanf (fov*0.5f);
Q = m_FarPlane / (m_FarPlane - m_NearPlane);
m_ProjMat.SetZero ();
m_ProjMat._11 = w;
m_ProjMat._22 = h;
m_ProjMat._33 = (m_FarPlane+m_NearPlane)/(m_FarPlane-m_NearPlane);;
m_ProjMat._34 = -2*m_FarPlane*m_NearPlane/(m_FarPlane-m_NearPlane);
m_ProjMat._43 = 1.0f;
}
//Updates the frustum planes. Should be called
//everytime the view or projection matrices are
//altered.
void CCamera::UpdateFrustum ()
{
CMatrix3D MatFinal;
CMatrix3D MatView;
m_Orientation.GetInverse(MatView);
MatFinal = m_ProjMat * MatView;
//get the RIGHT plane
m_ViewFrustum.SetNumPlanes (6);
m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11;
m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12;
m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13;
m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14;
//get the LEFT plane
m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11;
m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12;
m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13;
m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14;
//get the BOTTOM plane
m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21;
m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22;
m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23;
m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24;
//get the TOP plane
m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21;
m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22;
m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23;
m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24;
//get the FAR plane
m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31;
m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32;
m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33;
m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34;
//get the NEAR plane
m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31;
m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32;
m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33;
m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34;
}
void CCamera::SetViewPort (SViewPort *viewport)
{
m_ViewPort.m_X = viewport->m_X;
m_ViewPort.m_Y = viewport->m_Y;
m_ViewPort.m_Width = viewport->m_Width;
m_ViewPort.m_Height = viewport->m_Height;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetCameraPlanePoints: return four points in camera space at given distance from camera
void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const
{
float aspect=float(m_ViewPort.m_Width)/float(m_ViewPort.m_Height);
float x=dist*float(tan(GetFOV()*aspect*0.5));
float y=dist*float(tan(GetFOV()*0.5));
pts[0].X=-x;
pts[0].Y=-y;
pts[0].Z=dist;
pts[1].X=x;
pts[1].Y=-y;
pts[1].Z=dist;
pts[2].X=x;
pts[2].Y=y;
pts[2].Z=dist;
pts[3].X=-x;
pts[3].Y=y;
pts[3].Z=dist;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetFrustumPoints: calculate and return the position of the 8 points of the frustum in world space
void CCamera::GetFrustumPoints(CVector3D pts[8]) const
{
// get camera space points for near and far planes
CVector3D cpts[8];
GetCameraPlanePoints(m_NearPlane,pts);
GetCameraPlanePoints(m_FarPlane,pts+4);
// transform to world space
for (int i=0;i<8;i++) {
m_Orientation.Transform(cpts[i],pts[i]);
}
}
//***********************************************************
//
// Name: Camera.Cpp
// Last Update: 24/2/02
// Author: Poya Manouchehri
//
// Description: CCamera holds a view and a projection matrix.
// It also has a frustum which can be used to
// cull objects for rendering.
//
//***********************************************************
#include "Camera.h"
CCamera::CCamera ()
{
// set viewport to something anything should handle, but should be initialised
// to window size before use
m_ViewPort.m_X = 0;
m_ViewPort.m_Y = 0;
m_ViewPort.m_Width = 800;
m_ViewPort.m_Height = 600;
}
CCamera::~CCamera ()
{
}
void CCamera::SetProjection (float nearp, float farp, float fov)
{
float h, w, Q;
m_NearPlane = nearp;
m_FarPlane = farp;
m_FOV = fov;
float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height;
w = 1/tanf (fov*0.5f*Aspect);
h = 1/tanf (fov*0.5f);
Q = m_FarPlane / (m_FarPlane - m_NearPlane);
m_ProjMat.SetZero ();
m_ProjMat._11 = w;
m_ProjMat._22 = h;
m_ProjMat._33 = (m_FarPlane+m_NearPlane)/(m_FarPlane-m_NearPlane);;
m_ProjMat._34 = -2*m_FarPlane*m_NearPlane/(m_FarPlane-m_NearPlane);
m_ProjMat._43 = 1.0f;
}
//Updates the frustum planes. Should be called
//everytime the view or projection matrices are
//altered.
void CCamera::UpdateFrustum ()
{
CMatrix3D MatFinal;
CMatrix3D MatView;
m_Orientation.GetInverse(MatView);
MatFinal = m_ProjMat * MatView;
//get the RIGHT plane
m_ViewFrustum.SetNumPlanes (6);
m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11;
m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12;
m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13;
m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14;
//get the LEFT plane
m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11;
m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12;
m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13;
m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14;
//get the BOTTOM plane
m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21;
m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22;
m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23;
m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24;
//get the TOP plane
m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21;
m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22;
m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23;
m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24;
//get the FAR plane
m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31;
m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32;
m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33;
m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34;
//get the NEAR plane
m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31;
m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32;
m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33;
m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34;
}
void CCamera::SetViewPort (SViewPort *viewport)
{
m_ViewPort.m_X = viewport->m_X;
m_ViewPort.m_Y = viewport->m_Y;
m_ViewPort.m_Width = viewport->m_Width;
m_ViewPort.m_Height = viewport->m_Height;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetCameraPlanePoints: return four points in camera space at given distance from camera
void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const
{
float aspect=float(m_ViewPort.m_Width)/float(m_ViewPort.m_Height);
float x=dist*float(tan(GetFOV()*aspect*0.5));
float y=dist*float(tan(GetFOV()*0.5));
pts[0].X=-x;
pts[0].Y=-y;
pts[0].Z=dist;
pts[1].X=x;
pts[1].Y=-y;
pts[1].Z=dist;
pts[2].X=x;
pts[2].Y=y;
pts[2].Z=dist;
pts[3].X=-x;
pts[3].Y=y;
pts[3].Z=dist;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetFrustumPoints: calculate and return the position of the 8 points of the frustum in world space
void CCamera::GetFrustumPoints(CVector3D pts[8]) const
{
// get camera space points for near and far planes
CVector3D cpts[8];
GetCameraPlanePoints(m_NearPlane,pts);
GetCameraPlanePoints(m_FarPlane,pts+4);
// transform to world space
for (int i=0;i<8;i++) {
m_Orientation.Transform(cpts[i],pts[i]);
}
}

View File

@ -50,12 +50,12 @@ class CCamera
float GetNearPlane() const { return m_NearPlane; }
float GetFarPlane() const { return m_FarPlane; }
float GetFOV() const { return m_FOV; }
// calculate and return the position of the 8 points of the frustum in world space
void GetFrustumPoints(CVector3D pts[8]) const;
// return four points in camera space at given distance from camera
void GetCameraPlanePoints(float dist,CVector3D pts[4]) const;
// calculate and return the position of the 8 points of the frustum in world space
void GetFrustumPoints(CVector3D pts[8]) const;
// return four points in camera space at given distance from camera
void GetCameraPlanePoints(float dist,CVector3D pts[4]) const;
public:
//This is the orientation matrix. The inverse of this

View File

@ -1,177 +1,177 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: HFTracer.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "HFTracer.h"
#include "Terrain.h"
#include "Bound.h"
#include "Vector3D.h"
extern CTerrain g_Terrain;
///////////////////////////////////////////////////////////////////////////////
// CHFTracer constructor
CHFTracer::CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale)
: m_Heightfield(hf), m_MapSize(mapsize), m_CellSize(cellsize),
m_HeightScale(heightscale)
{
}
///////////////////////////////////////////////////////////////////////////////
// RayTriIntersect: intersect a ray with triangle defined by vertices
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
// or false otherwise
bool CHFTracer::RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
const CVector3D& origin,const CVector3D& dir,float& dist) const
{
const float EPSILON=0.00001f;
// calculate edge vectors
CVector3D edge0=v1-v0;
CVector3D edge1=v2-v0;
// begin calculating determinant - also used to calculate U parameter
CVector3D pvec=dir.Cross(edge1);
// if determinant is near zero, ray lies in plane of triangle
float det = edge0.Dot(pvec);
if (fabs(det)<EPSILON)
return false;
float inv_det = 1.0f/det;
// calculate vector from vert0 to ray origin
CVector3D tvec=origin-v0;
// calculate U parameter, test bounds
float u=tvec.Dot(pvec)*inv_det;
if (u<-0.01f || u>1.01f)
return false;
// prepare to test V parameter
CVector3D qvec=tvec.Cross(edge0);
// calculate V parameter and test bounds
float v=dir.Dot(qvec)*inv_det;
if (v<0.0f || u+v>1.0f)
return false;
// calculate distance to intersection point from ray origin
float d=edge1.Dot(qvec)*inv_det;
if (d>=0 && d<dist) {
dist=d;
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
// CellIntersect: test if ray intersects either of the triangles in the given
// cell - return hit result, and distance to hit, if hit occurred
bool CHFTracer::CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const
{
bool res=false;
// get vertices for this cell
CVector3D vpos[4];
g_Terrain.CalcPosition(cx,cz,vpos[0]);
g_Terrain.CalcPosition(cx+1,cz,vpos[1]);
g_Terrain.CalcPosition(cx+1,cz+1,vpos[2]);
g_Terrain.CalcPosition(cx,cz+1,vpos[3]);
dist=1.0e30f;
if (RayTriIntersect(vpos[0],vpos[1],vpos[2],origin,dir,dist)) {
res=true;
}
if (RayTriIntersect(vpos[0],vpos[2],vpos[3],origin,dir,dist)) {
res=true;
}
return res;
}
///////////////////////////////////////////////////////////////////////////////
// RayIntersect: intersect ray with this heightfield; return true if
// intersection occurs (and fill in grid coordinates of intersection), or false
// otherwise
bool CHFTracer::RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const
{
// intersect first against bounding box
CBound bound;
bound[0]=CVector3D(0,0,0);
bound[1]=CVector3D(m_MapSize*m_CellSize,65535*m_HeightScale,m_MapSize*m_CellSize);
float tmin,tmax;
if (!bound.RayIntersect(origin,dir,tmin,tmax)) {
// ray missed world bounds; no intersection
return false;
}
// project origin onto grid, if necessary, to get starting point for traversal
CVector3D traversalPt;
if (tmin>0) {
traversalPt=origin+dir*tmin;
} else {
traversalPt=origin;
}
// setup traversal variables
int sx=dir.X<0 ? -1 : 1;
int sz=dir.Z<0 ? -1 : 1;
float invCellSize=1.0f/float(m_CellSize);
float fcx=traversalPt.X*invCellSize;
int cx=int(fcx);
float fcz=traversalPt.Z*invCellSize;
int cz=int(fcz);
float invdx=float(1.0/fabs(dir.X));
float invdz=float(1.0/fabs(dir.Z));
float dist;
do {
// test current cell
if (cx>=0 && cx<int(m_MapSize-1) && cz>=0 && cz<int(m_MapSize-1)) {
if (CellIntersect(cx,cz,origin,dir,dist)) {
x=cx;
z=cz;
ipt=origin+dir*dist;
return true;
}
}
// get coords of current cell
fcx=traversalPt.X*invCellSize;
fcz=traversalPt.Z*invCellSize;
// get distance to next cell in x,z
float dx=(sx==-1) ? fcx-float(cx) : 1-(fcx-float(cx));
dx*=invdx;
float dz=(sz==-1) ? fcz-float(cz) : 1-(fcz-float(cz));
dz*=invdz;
// advance ..
float dist;
if (dx<dz) {
cx+=sx;
dist=dx;
} else {
cz+=sz;
dist=dz;
}
traversalPt+=dir*dist;
} while (traversalPt.Y>=0);
// fell off end of heightmap with no intersection; return a miss
return false;
}
///////////////////////////////////////////////////////////////////////////////
//
// Name: HFTracer.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "HFTracer.h"
#include "Terrain.h"
#include "Bound.h"
#include "Vector3D.h"
extern CTerrain g_Terrain;
///////////////////////////////////////////////////////////////////////////////
// CHFTracer constructor
CHFTracer::CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale)
: m_Heightfield(hf), m_MapSize(mapsize), m_CellSize(cellsize),
m_HeightScale(heightscale)
{
}
///////////////////////////////////////////////////////////////////////////////
// RayTriIntersect: intersect a ray with triangle defined by vertices
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
// or false otherwise
bool CHFTracer::RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
const CVector3D& origin,const CVector3D& dir,float& dist) const
{
const float EPSILON=0.00001f;
// calculate edge vectors
CVector3D edge0=v1-v0;
CVector3D edge1=v2-v0;
// begin calculating determinant - also used to calculate U parameter
CVector3D pvec=dir.Cross(edge1);
// if determinant is near zero, ray lies in plane of triangle
float det = edge0.Dot(pvec);
if (fabs(det)<EPSILON)
return false;
float inv_det = 1.0f/det;
// calculate vector from vert0 to ray origin
CVector3D tvec=origin-v0;
// calculate U parameter, test bounds
float u=tvec.Dot(pvec)*inv_det;
if (u<-0.01f || u>1.01f)
return false;
// prepare to test V parameter
CVector3D qvec=tvec.Cross(edge0);
// calculate V parameter and test bounds
float v=dir.Dot(qvec)*inv_det;
if (v<0.0f || u+v>1.0f)
return false;
// calculate distance to intersection point from ray origin
float d=edge1.Dot(qvec)*inv_det;
if (d>=0 && d<dist) {
dist=d;
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
// CellIntersect: test if ray intersects either of the triangles in the given
// cell - return hit result, and distance to hit, if hit occurred
bool CHFTracer::CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const
{
bool res=false;
// get vertices for this cell
CVector3D vpos[4];
g_Terrain.CalcPosition(cx,cz,vpos[0]);
g_Terrain.CalcPosition(cx+1,cz,vpos[1]);
g_Terrain.CalcPosition(cx+1,cz+1,vpos[2]);
g_Terrain.CalcPosition(cx,cz+1,vpos[3]);
dist=1.0e30f;
if (RayTriIntersect(vpos[0],vpos[1],vpos[2],origin,dir,dist)) {
res=true;
}
if (RayTriIntersect(vpos[0],vpos[2],vpos[3],origin,dir,dist)) {
res=true;
}
return res;
}
///////////////////////////////////////////////////////////////////////////////
// RayIntersect: intersect ray with this heightfield; return true if
// intersection occurs (and fill in grid coordinates of intersection), or false
// otherwise
bool CHFTracer::RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const
{
// intersect first against bounding box
CBound bound;
bound[0]=CVector3D(0,0,0);
bound[1]=CVector3D(m_MapSize*m_CellSize,65535*m_HeightScale,m_MapSize*m_CellSize);
float tmin,tmax;
if (!bound.RayIntersect(origin,dir,tmin,tmax)) {
// ray missed world bounds; no intersection
return false;
}
// project origin onto grid, if necessary, to get starting point for traversal
CVector3D traversalPt;
if (tmin>0) {
traversalPt=origin+dir*tmin;
} else {
traversalPt=origin;
}
// setup traversal variables
int sx=dir.X<0 ? -1 : 1;
int sz=dir.Z<0 ? -1 : 1;
float invCellSize=1.0f/float(m_CellSize);
float fcx=traversalPt.X*invCellSize;
int cx=int(fcx);
float fcz=traversalPt.Z*invCellSize;
int cz=int(fcz);
float invdx=float(1.0/fabs(dir.X));
float invdz=float(1.0/fabs(dir.Z));
float dist;
do {
// test current cell
if (cx>=0 && cx<int(m_MapSize-1) && cz>=0 && cz<int(m_MapSize-1)) {
if (CellIntersect(cx,cz,origin,dir,dist)) {
x=cx;
z=cz;
ipt=origin+dir*dist;
return true;
}
}
// get coords of current cell
fcx=traversalPt.X*invCellSize;
fcz=traversalPt.Z*invCellSize;
// get distance to next cell in x,z
float dx=(sx==-1) ? fcx-float(cx) : 1-(fcx-float(cx));
dx*=invdx;
float dz=(sz==-1) ? fcz-float(cz) : 1-(fcz-float(cz));
dz*=invdz;
// advance ..
float dist;
if (dx<dz) {
cx+=sx;
dist=dx;
} else {
cz+=sz;
dist=dz;
}
traversalPt+=dir*dist;
} while (traversalPt.Y>=0);
// fell off end of heightmap with no intersection; return a miss
return false;
}

View File

@ -1,48 +1,48 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: HFTracer.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _HFTRACER_H
#define _HFTRACER_H
class CVector3D;
#include "res/res.h"
///////////////////////////////////////////////////////////////////////////////
// CHFTracer: a class for determining ray intersections with a heightfield
class CHFTracer
{
public:
// constructor; setup data
CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale);
// intersect ray with this heightfield; return true if intersection
// occurs (and fill in grid coordinates and point of intersection), or false otherwise
bool RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const;
private:
// intersect a ray with triangle defined by vertices
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
// or false otherwise
bool RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
const CVector3D& origin,const CVector3D& dir,float& dist) const;
// test if ray intersects either of the triangles in the given
bool CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const;
// the heightfield were tracing
const u16* m_Heightfield;
// size of the heightfield
u32 m_MapSize;
// cell size - size of each cell in x and z
float m_CellSize;
// vertical scale - size of each cell in y
float m_HeightScale;
};
///////////////////////////////////////////////////////////////////////////////
//
// Name: HFTracer.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _HFTRACER_H
#define _HFTRACER_H
class CVector3D;
#include "res/res.h"
///////////////////////////////////////////////////////////////////////////////
// CHFTracer: a class for determining ray intersections with a heightfield
class CHFTracer
{
public:
// constructor; setup data
CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale);
// intersect ray with this heightfield; return true if intersection
// occurs (and fill in grid coordinates and point of intersection), or false otherwise
bool RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const;
private:
// intersect a ray with triangle defined by vertices
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
// or false otherwise
bool RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
const CVector3D& origin,const CVector3D& dir,float& dist) const;
// test if ray intersects either of the triangles in the given
bool CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const;
// the heightfield were tracing
const u16* m_Heightfield;
// size of the heightfield
u32 m_MapSize;
// cell size - size of each cell in x and z
float m_CellSize;
// vertical scale - size of each cell in y
float m_HeightScale;
};
#endif

View File

@ -1,341 +1,336 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Name: Model.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Model.h"
#include "Quaternion.h"
#include "Bound.h"
#include "SkeletonAnim.h"
#include "SkeletonAnimDef.h"
#include "SkeletonAnimManager.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor
CModel::CModel()
: m_pModelDef(0), m_Anim(0), m_AnimTime(0),
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Destructor
CModel::~CModel()
{
ReleaseData();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ReleaseData: delete anything allocated by the model
void CModel::ReleaseData()
{
delete[] m_BoneMatrices;
delete[] m_InvBoneMatrices;
for (size_t i=0;i<m_Props.size();i++) {
delete m_Props[i].m_Model;
}
m_Props.clear();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// InitModel: setup model from given geometry
bool CModel::InitModel(CModelDef* modeldef)
{
// clean up any existing data first
ReleaseData();
m_pModelDef = modeldef;
u32 numBones=modeldef->GetNumBones();
if (numBones>0) {
// allocate matrices for bone transformations
m_BoneMatrices=new CMatrix3D[numBones];
m_InvBoneMatrices=new CMatrix3D[numBones];
// store default pose until animation assigned
CBoneState* defpose=modeldef->GetBones();
for (uint i=0;i<numBones;i++) {
CMatrix3D& m=m_BoneMatrices[i];
m.SetIdentity();
m.Rotate(defpose[i].m_Rotation);
m.Translate(defpose[i].m_Translation);
m.GetInverse(m_InvBoneMatrices[i]);
}
m_BoneMatricesValid=true;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SkinPoint: skin the given point using the given blend and bonestate data
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
const CBoneState* bonestates)
{
CVector3D result(0,0,0);
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
CMatrix3D m;
m.SetIdentity();
m.Rotate(bonestates[blend.m_Bone[i]].m_Rotation);
m.Translate(bonestates[blend.m_Bone[i]].m_Translation);
CVector3D tmp=m.Transform(pos);
result+=tmp*blend.m_Weight[i];
}
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SkinPoint: skin the given point using the given blend and matrix data
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
const CMatrix3D* bonestates)
{
CVector3D result(0,0,0);
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
const CMatrix3D& m=bonestates[blend.m_Bone[i]];
CVector3D tmp=m.Transform(pos);
result+=tmp*blend.m_Weight[i];
}
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalcBound: calculate the world space bounds of this model
void CModel::CalcBounds()
{
m_ObjectBounds.Transform(GetTransform(),m_Bounds);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalcObjectBounds: calculate object space bounds of this model, based solely on vertex positions
void CModel::CalcObjectBounds()
{
m_ObjectBounds.SetEmpty();
int numverts=m_pModelDef->GetNumVertices();
SModelVertex* verts=m_pModelDef->GetVertices();
for (int i=0;i<numverts;i++) {
m_ObjectBounds+=verts[i].m_Coords;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation
void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result)
{
result.SetEmpty();
CSkeletonAnim dummyanim;
dummyanim.m_AnimDef=anim;
if (!SetAnimation(&dummyanim)) return;
int numverts=m_pModelDef->GetNumVertices();
SModelVertex* verts=m_pModelDef->GetVertices();
// iterate through every frame of the animation
for (uint j=0;j<anim->GetNumFrames();j++) {
// extend bounds by vertex positions at the frame
for (int i=0;i<numverts;i++) {
CVector3D tmp=SkinPoint(verts[i].m_Coords,verts[i].m_Blend,GetBoneMatrices());
result+=tmp;
}
// advance to next frame
m_AnimTime+=anim->GetFrameTime();
m_BoneMatricesValid=false;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BuildAnimation: load raw animation frame animation from given file, and build a
// animation specific to this model
CSkeletonAnim* CModel::BuildAnimation(const char* filename,float speed)
{
CSkeletonAnimDef* def=g_SkelAnimMan.GetAnimation(filename);
if (!def) return 0;
CSkeletonAnim* anim=new CSkeletonAnim;
anim->m_AnimDef=def;
anim->m_Speed=speed;
CalcAnimatedObjectBound(def,anim->m_ObjectBounds);
return anim;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update: update this model by the given time, in seconds
void CModel::Update(float time)
{
if (m_Anim && m_BoneMatrices) {
// convert to ms and adjust for animation speed
float animtime=time*1000*m_Anim->m_Speed;
// update animation time, but don't calculate bone matrices - do that (lazily) when
// something requests them; that saves some calculation work for offscreen models,
// and also assures the world space, inverted bone matrices (required for normal
// skinning) are up to date with respect to m_Transform
m_AnimTime+=animtime;
float duration=m_Anim->m_AnimDef->GetDuration();
if (m_AnimTime>duration) {
m_AnimTime=(float) fmod(m_AnimTime,duration);
}
// mark vertices as dirty
SetDirty(RENDERDATA_UPDATE_VERTICES);
// mark matrices as dirty
m_BoneMatricesValid=false;
}
// update props
for (uint i=0;i<m_Props.size();i++) {
m_Props[i].m_Model->Update(time);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GenerateBoneMatrices: calculate necessary bone transformation matrices for skinning
void CModel::GenerateBoneMatrices()
{
if (!m_Anim || !m_BoneMatrices) return;
m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
const CMatrix3D& transform=GetTransform();
for (int i=0;i<m_pModelDef->GetNumBones();i++) {
CMatrix3D m=m_BoneMatrices[i];
m.Concatenate(transform);
m.GetInverse(m_InvBoneMatrices[i]);
}
// update transform of boned props
// TODO, RC - ugh, we'll be doing this twice (for boned props, at least) - once here,
// and once again in SetTransform; better to just do it in Update?
for (size_t i=0;i<m_Props.size();i++) {
const Prop& prop=m_Props[i];
if (prop.m_Point->m_BoneIndex!=0xff) {
CMatrix3D proptransform=prop.m_Point->m_Transform;;
if (prop.m_Point->m_BoneIndex!=0xff) {
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
}
proptransform.Concatenate(transform);
prop.m_Model->SetTransform(proptransform);
}
}
m_BoneMatricesValid=true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SetAnimation: set the given animation as the current animation on this model;
// return false on error, else true
bool CModel::SetAnimation(CSkeletonAnim* anim)
{
m_Anim=anim;
if (m_Anim) {
if (!m_BoneMatrices) {
// not boned, can't animate
return false;
}
if (anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
// mismatch between models skeleton and animations skeleton
return false;
}
// update object bounds to the bounds when given animation applied
m_ObjectBounds=m_Anim->m_ObjectBounds;
// start anim from beginning
m_AnimTime=0;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AddProp: add a prop to the model on the given point
void CModel::AddProp(SPropPoint* point,CModel* model)
{
// position model according to prop point position
CMatrix3D proptransform=point->m_Transform;;
if (m_BoneMatrices && point->m_BoneIndex!=0xff) {
proptransform.Concatenate(m_BoneMatrices[point->m_BoneIndex]);
}
proptransform.Concatenate(m_Transform);
model->SetTransform(proptransform);
// check if we're already using this point, and replace
// model on it if so
uint i;
for (i=0;i<m_Props.size();i++) {
if (m_Props[i].m_Point==point) {
m_Props[i].m_Model=model;
return;
}
}
// not using point; add new prop
Prop prop;
prop.m_Point=point;
prop.m_Model=model;
m_Props.push_back(prop);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RemoveProp: remove a prop from the given point
void CModel::RemoveProp(SPropPoint* point)
{
typedef std::vector<Prop>::iterator Iter;
for (Iter iter=m_Props.begin();iter!=m_Props.end();++iter) {
const Prop& prop=*iter;
if (prop.m_Point==point) {
m_Props.erase(iter);
return;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Clone: return a clone of this model
CModel* CModel::Clone() const
{
CModel* clone=new CModel;
clone->m_ObjectBounds=m_ObjectBounds;
clone->InitModel(m_pModelDef);
clone->SetTexture(m_Texture);
clone->SetAnimation(m_Anim);
for (uint i=0;i<m_Props.size();i++) {
// eek! TODO, RC - need to investigate shallow clone here
clone->AddProp(m_Props[i].m_Point,m_Props[i].m_Model->Clone());
}
return clone;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SetTransform: set the transform on this object, and reorientate props accordingly
void CModel::SetTransform(const CMatrix3D& transform)
{
// call base class to set transform on this object
CRenderableObject::SetTransform(transform);
// now set transforms on props
const CMatrix3D* bonematrices=GetBoneMatrices();
for (size_t i=0;i<m_Props.size();i++) {
const Prop& prop=m_Props[i];
CMatrix3D proptransform=prop.m_Point->m_Transform;;
if (prop.m_Point->m_BoneIndex!=0xff) {
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
}
proptransform.Concatenate(transform);
prop.m_Model->SetTransform(proptransform);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Name: Model.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Model.h"
#include "Quaternion.h"
#include "Bound.h"
#include "SkeletonAnim.h"
#include "SkeletonAnimDef.h"
#include "SkeletonAnimManager.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor
CModel::CModel()
: m_pModelDef(0), m_Anim(0), m_AnimTime(0),
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Destructor
CModel::~CModel()
{
ReleaseData();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ReleaseData: delete anything allocated by the model
void CModel::ReleaseData()
{
delete[] m_BoneMatrices;
delete[] m_InvBoneMatrices;
for (size_t i=0;i<m_Props.size();i++) {
delete m_Props[i].m_Model;
}
m_Props.clear();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// InitModel: setup model from given geometry
bool CModel::InitModel(CModelDef* modeldef)
{
// clean up any existing data first
ReleaseData();
m_pModelDef = modeldef;
u32 numBones=modeldef->GetNumBones();
if (numBones>0) {
// allocate matrices for bone transformations
m_BoneMatrices=new CMatrix3D[numBones];
m_InvBoneMatrices=new CMatrix3D[numBones];
// store default pose until animation assigned
CBoneState* defpose=modeldef->GetBones();
for (uint i=0;i<numBones;i++) {
CMatrix3D& m=m_BoneMatrices[i];
m.SetIdentity();
m.Rotate(defpose[i].m_Rotation);
m.Translate(defpose[i].m_Translation);
m.GetInverse(m_InvBoneMatrices[i]);
}
m_BoneMatricesValid=true;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SkinPoint: skin the given point using the given blend and bonestate data
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
const CBoneState* bonestates)
{
CVector3D result(0,0,0);
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
CMatrix3D m;
m.SetIdentity();
m.Rotate(bonestates[blend.m_Bone[i]].m_Rotation);
m.Translate(bonestates[blend.m_Bone[i]].m_Translation);
CVector3D tmp=m.Transform(pos);
result+=tmp*blend.m_Weight[i];
}
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SkinPoint: skin the given point using the given blend and matrix data
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
const CMatrix3D* bonestates)
{
CVector3D result(0,0,0);
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
const CMatrix3D& m=bonestates[blend.m_Bone[i]];
CVector3D tmp=m.Transform(pos);
result+=tmp*blend.m_Weight[i];
}
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalcBound: calculate the world space bounds of this model
void CModel::CalcBounds()
{
m_ObjectBounds.Transform(GetTransform(),m_Bounds);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalcObjectBounds: calculate object space bounds of this model, based solely on vertex positions
void CModel::CalcObjectBounds()
{
m_ObjectBounds.SetEmpty();
int numverts=m_pModelDef->GetNumVertices();
SModelVertex* verts=m_pModelDef->GetVertices();
for (int i=0;i<numverts;i++) {
m_ObjectBounds+=verts[i].m_Coords;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation
void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result)
{
result.SetEmpty();
CSkeletonAnim dummyanim;
dummyanim.m_AnimDef=anim;
if (!SetAnimation(&dummyanim)) return;
int numverts=m_pModelDef->GetNumVertices();
SModelVertex* verts=m_pModelDef->GetVertices();
// iterate through every frame of the animation
for (uint j=0;j<anim->GetNumFrames();j++) {
// extend bounds by vertex positions at the frame
for (int i=0;i<numverts;i++) {
CVector3D tmp=SkinPoint(verts[i].m_Coords,verts[i].m_Blend,GetBoneMatrices());
result+=tmp;
}
// advance to next frame
m_AnimTime+=anim->GetFrameTime();
m_BoneMatricesValid=false;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BuildAnimation: load raw animation frame animation from given file, and build a
// animation specific to this model
CSkeletonAnim* CModel::BuildAnimation(const char* filename,float speed)
{
CSkeletonAnimDef* def=g_SkelAnimMan.GetAnimation(filename);
if (!def) return 0;
CSkeletonAnim* anim=new CSkeletonAnim;
anim->m_AnimDef=def;
anim->m_Speed=speed;
CalcAnimatedObjectBound(def,anim->m_ObjectBounds);
return anim;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update: update this model by the given time, in seconds
void CModel::Update(float time)
{
if (m_Anim && m_BoneMatrices) {
// convert to ms and adjust for animation speed
float animtime=time*1000*m_Anim->m_Speed;
// update animation time, but don't calculate bone matrices - do that (lazily) when
// something requests them; that saves some calculation work for offscreen models,
// and also assures the world space, inverted bone matrices (required for normal
// skinning) are up to date with respect to m_Transform
m_AnimTime+=animtime;
float duration=m_Anim->m_AnimDef->GetDuration();
if (m_AnimTime>duration) {
m_AnimTime=(float) fmod(m_AnimTime,duration);
}
// mark vertices as dirty
SetDirty(RENDERDATA_UPDATE_VERTICES);
// mark matrices as dirty
m_BoneMatricesValid=false;
}
// update props
for (uint i=0;i<m_Props.size();i++) {
m_Props[i].m_Model->Update(time);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GenerateBoneMatrices: calculate necessary bone transformation matrices for skinning
void CModel::GenerateBoneMatrices()
{
if (!m_Anim || !m_BoneMatrices) return;
m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
const CMatrix3D& transform=GetTransform();
for (int i=0;i<m_pModelDef->GetNumBones();i++) {
CMatrix3D m=m_BoneMatrices[i];
m.Concatenate(transform);
m.GetInverse(m_InvBoneMatrices[i]);
}
// update transform of boned props
// TODO, RC - ugh, we'll be doing this twice (for boned props, at least) - once here,
// and once again in SetTransform; better to just do it in Update?
for (size_t i=0;i<m_Props.size();i++) {
const Prop& prop=m_Props[i];
if (prop.m_Point->m_BoneIndex!=0xff) {
CMatrix3D proptransform=prop.m_Point->m_Transform;;
if (prop.m_Point->m_BoneIndex!=0xff) {
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
}
proptransform.Concatenate(transform);
prop.m_Model->SetTransform(proptransform);
}
}
m_BoneMatricesValid=true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SetAnimation: set the given animation as the current animation on this model;
// return false on error, else true
bool CModel::SetAnimation(CSkeletonAnim* anim)
{
m_Anim=anim;
if (m_Anim) {
if (!m_BoneMatrices) {
// not boned, can't animate
return false;
}
if (anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
// mismatch between models skeleton and animations skeleton
return false;
}
// update object bounds to the bounds when given animation applied
m_ObjectBounds=m_Anim->m_ObjectBounds;
// start anim from beginning
m_AnimTime=0;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AddProp: add a prop to the model on the given point
void CModel::AddProp(SPropPoint* point,CModel* model)
{
// position model according to prop point position
model->SetTransform(point->m_Transform);
// check if we're already using this point, and replace
// model on it if so
uint i;
for (i=0;i<m_Props.size();i++) {
if (m_Props[i].m_Point==point) {
m_Props[i].m_Model=model;
return;
}
}
// not using point; add new prop
Prop prop;
prop.m_Point=point;
prop.m_Model=model;
m_Props.push_back(prop);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RemoveProp: remove a prop from the given point
void CModel::RemoveProp(SPropPoint* point)
{
typedef std::vector<Prop>::iterator Iter;
for (Iter iter=m_Props.begin();iter!=m_Props.end();++iter) {
const Prop& prop=*iter;
if (prop.m_Point==point) {
m_Props.erase(iter);
return;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Clone: return a clone of this model
CModel* CModel::Clone() const
{
CModel* clone=new CModel;
clone->m_ObjectBounds=m_ObjectBounds;
clone->InitModel(m_pModelDef);
clone->SetTexture(m_Texture);
clone->SetAnimation(m_Anim);
for (uint i=0;i<m_Props.size();i++) {
// eek! TODO, RC - need to investigate shallow clone here
clone->AddProp(m_Props[i].m_Point,m_Props[i].m_Model->Clone());
}
return clone;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SetTransform: set the transform on this object, and reorientate props accordingly
void CModel::SetTransform(const CMatrix3D& transform)
{
// call base class to set transform on this object
CRenderableObject::SetTransform(transform);
// now set transforms on props
const CMatrix3D* bonematrices=GetBoneMatrices();
for (size_t i=0;i<m_Props.size();i++) {
const Prop& prop=m_Props[i];
CMatrix3D proptransform=prop.m_Point->m_Transform;;
if (prop.m_Point->m_BoneIndex!=0xff) {
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
}
proptransform.Concatenate(transform);
prop.m_Model->SetTransform(proptransform);
}
}

View File

@ -1,117 +1,117 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: Model.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MODEL_H
#define _MODEL_H
#include "Texture.h"
#include "ModelDef.h"
#include "RenderableObject.h"
#include "SkeletonAnim.h"
///////////////////////////////////////////////////////////////////////////////
// CModel: basically, a mesh object - holds the texturing and skinning
// information for a model in game
class CModel : public CRenderableObject
{
public:
struct Prop {
SPropPoint* m_Point;
CModel* m_Model;
};
public:
// constructor
CModel();
// destructor
~CModel();
// setup model from given geometry
bool InitModel(CModelDef *modeldef);
// calculate the world space bounds of this model
void CalcBounds();
// update this model's state; 'time' is the time since the last update, in MS
void Update(float time);
// get the model's geometry data
CModelDef *GetModelDef() { return m_pModelDef; }
// set the model's texture
void SetTexture(const CTexture& tex) { m_Texture=tex; }
// get the model's texture
CTexture* GetTexture() { return &m_Texture; }
// set the given animation as the current animation on this model
bool SetAnimation(CSkeletonAnim* anim);
// get the currently playing animation, if any
CSkeletonAnim* GetAnimation() { return m_Anim; }
// calculate object space bounds of this model, based solely on vertex positions
void CalcObjectBounds();
// calculate bounds encompassing all vertex positions for given animation
void CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result);
// return object space bounds
const CBound& GetObjectBounds() const { return m_ObjectBounds; }
// set transform of this object, and recurse down into props to update their world space transform
void SetTransform(const CMatrix3D& transform);
// return the models bone matrices
const CMatrix3D* GetBoneMatrices() {
if (!m_BoneMatricesValid) GenerateBoneMatrices();
return m_BoneMatrices;
}
// return the models inverted bone matrices
const CMatrix3D* GetInvBoneMatrices() {
if (!m_BoneMatricesValid) GenerateBoneMatrices();
return m_InvBoneMatrices;
}
// load raw animation frame animation from given file, and build a
// animation specific to this model
CSkeletonAnim* BuildAnimation(const char* filename,float speed);
// add a prop to the model on the given point
void AddProp(SPropPoint* point,CModel* model);
// remove a prop from the given point
void RemoveProp(SPropPoint* point);
// return prop list
const std::vector<Prop>& GetProps() { return m_Props; }
// return a clone of this model
CModel* Clone() const;
private:
// delete anything allocated by the model
void ReleaseData();
// calculate necessary bone transformation matrices for skinning
void GenerateBoneMatrices();
// texture used by model
CTexture m_Texture;
// pointer to the model's raw 3d data
CModelDef* m_pModelDef;
// object space bounds of model - accounts for bounds of all possible animations
// that can play on a model
CBound m_ObjectBounds;
// animation currently playing on this model, if any
CSkeletonAnim* m_Anim;
// time (in MS) into the current animation
float m_AnimTime;
// flag stating whether bone matrices are currently valid
bool m_BoneMatricesValid;
// current state of all bones on this model; null if associated modeldef isn't skeletal
CMatrix3D* m_BoneMatrices;
// inverse of the above world space transform of the above matrices
CMatrix3D* m_InvBoneMatrices;
// list of current props on model
std::vector<Prop> m_Props;
};
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Name: Model.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MODEL_H
#define _MODEL_H
#include "Texture.h"
#include "ModelDef.h"
#include "RenderableObject.h"
#include "SkeletonAnim.h"
///////////////////////////////////////////////////////////////////////////////
// CModel: basically, a mesh object - holds the texturing and skinning
// information for a model in game
class CModel : public CRenderableObject
{
public:
struct Prop {
SPropPoint* m_Point;
CModel* m_Model;
};
public:
// constructor
CModel();
// destructor
~CModel();
// setup model from given geometry
bool InitModel(CModelDef *modeldef);
// calculate the world space bounds of this model
void CalcBounds();
// update this model's state; 'time' is the time since the last update, in MS
void Update(float time);
// get the model's geometry data
CModelDef *GetModelDef() { return m_pModelDef; }
// set the model's texture
void SetTexture(const CTexture& tex) { m_Texture=tex; }
// get the model's texture
CTexture* GetTexture() { return &m_Texture; }
// set the given animation as the current animation on this model
bool SetAnimation(CSkeletonAnim* anim);
// get the currently playing animation, if any
CSkeletonAnim* GetAnimation() { return m_Anim; }
// calculate object space bounds of this model, based solely on vertex positions
void CalcObjectBounds();
// calculate bounds encompassing all vertex positions for given animation
void CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result);
// return object space bounds
const CBound& GetObjectBounds() const { return m_ObjectBounds; }
// set transform of this object, and recurse down into props to update their world space transform
void SetTransform(const CMatrix3D& transform);
// return the models bone matrices
const CMatrix3D* GetBoneMatrices() {
if (!m_BoneMatricesValid) GenerateBoneMatrices();
return m_BoneMatrices;
}
// return the models inverted bone matrices
const CMatrix3D* GetInvBoneMatrices() {
if (!m_BoneMatricesValid) GenerateBoneMatrices();
return m_InvBoneMatrices;
}
// load raw animation frame animation from given file, and build a
// animation specific to this model
CSkeletonAnim* BuildAnimation(const char* filename,float speed);
// add a prop to the model on the given point
void AddProp(SPropPoint* point,CModel* model);
// remove a prop from the given point
void RemoveProp(SPropPoint* point);
// return prop list
const std::vector<Prop>& GetProps() { return m_Props; }
// return a clone of this model
CModel* Clone() const;
private:
// delete anything allocated by the model
void ReleaseData();
// calculate necessary bone transformation matrices for skinning
void GenerateBoneMatrices();
// texture used by model
CTexture m_Texture;
// pointer to the model's raw 3d data
CModelDef* m_pModelDef;
// object space bounds of model - accounts for bounds of all possible animations
// that can play on a model
CBound m_ObjectBounds;
// animation currently playing on this model, if any
CSkeletonAnim* m_Anim;
// time (in MS) into the current animation
float m_AnimTime;
// flag stating whether bone matrices are currently valid
bool m_BoneMatricesValid;
// current state of all bones on this model; null if associated modeldef isn't skeletal
CMatrix3D* m_BoneMatrices;
// inverse of the above world space transform of the above matrices
CMatrix3D* m_InvBoneMatrices;
// list of current props on model
std::vector<Prop> m_Props;
};
#endif

View File

@ -13,7 +13,7 @@
///////////////////////////////////////////////////////////////////////////////
// CModelDef Constructor
CModelDef::CModelDef()
: m_pVertices(0), m_NumVertices(0), m_pFaces(0), m_NumFaces(0), m_Bones(0), m_NumBones(0),
: m_pVertices(0), m_NumVertices(0), m_pFaces(0), m_NumFaces(0), m_Bones(0), m_NumBones(0),
m_NumPropPoints(0), m_PropPoints(0)
{
}
@ -24,23 +24,23 @@ CModelDef::~CModelDef()
{
delete[] m_pVertices;
delete[] m_pFaces;
delete[] m_Bones;
delete[] m_Bones;
delete[] m_PropPoints;
}
///////////////////////////////////////////////////////////////////////////////
// FindPropPoint: find and return pointer to prop point matching given name;
// return null if no match (case insensitive search)
SPropPoint* CModelDef::FindPropPoint(const char* name) const
{
for (uint i=0;i<m_NumPropPoints;i++) {
if (stricmp(name,m_PropPoints[i].m_Name)==0) {
return &m_PropPoints[i];
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// FindPropPoint: find and return pointer to prop point matching given name;
// return null if no match (case insensitive search)
SPropPoint* CModelDef::FindPropPoint(const char* name) const
{
for (uint i=0;i<m_NumPropPoints;i++) {
if (stricmp(name,m_PropPoints[i].m_Name)==0) {
return &m_PropPoints[i];
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Load: read and return a new CModelDef initialised with data from given file
@ -71,26 +71,26 @@ CModelDef* CModelDef::Load(const char* filename)
if (mdef->m_NumBones) {
mdef->m_Bones=new CBoneState[mdef->m_NumBones];
unpacker.UnpackRaw(mdef->m_Bones,mdef->m_NumBones*sizeof(CBoneState));
}
if (unpacker.GetVersion()>=2) {
}
if (unpacker.GetVersion()>=2) {
// versions >=2 also have prop point data
unpacker.UnpackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
if (mdef->m_NumPropPoints) {
mdef->m_PropPoints=new SPropPoint[mdef->m_NumPropPoints];
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
unpacker.UnpackString(mdef->m_PropPoints[i].m_Name);
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
// build prop point transform
mdef->m_PropPoints[i].m_Transform.SetIdentity();
mdef->m_PropPoints[i].m_Transform.Rotate(mdef->m_PropPoints[i].m_Rotation);
mdef->m_PropPoints[i].m_Transform.Translate(mdef->m_PropPoints[i].m_Position);
}
}
}
unpacker.UnpackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
if (mdef->m_NumPropPoints) {
mdef->m_PropPoints=new SPropPoint[mdef->m_NumPropPoints];
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
unpacker.UnpackString(mdef->m_PropPoints[i].m_Name);
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
// build prop point transform
mdef->m_PropPoints[i].m_Transform.SetIdentity();
mdef->m_PropPoints[i].m_Transform.Rotate(mdef->m_PropPoints[i].m_Rotation);
mdef->m_PropPoints[i].m_Transform.Translate(mdef->m_PropPoints[i].m_Position);
}
}
}
} catch (...) {
delete mdef;
throw CFileUnpacker::CFileEOFError();
@ -118,17 +118,17 @@ void CModelDef::Save(const char* filename,const CModelDef* mdef)
if (mdef->m_NumBones) {
packer.PackRaw(mdef->m_Bones,sizeof(CBoneState)*mdef->m_NumBones);
}
packer.PackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
packer.PackString(mdef->m_PropPoints[i].m_Name);
packer.PackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
packer.PackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
packer.PackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
}
packer.PackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
packer.PackString(mdef->m_PropPoints[i].m_Name);
packer.PackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
packer.PackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
packer.PackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
}
// flush everything out to file
packer.Write(filename,FILE_VERSION,"PSMD");
}

View File

@ -10,25 +10,25 @@
#define _MODELDEF_H
#include "res/res.h"
#include "CStr.h"
#include "CStr.h"
#include "Vector3D.h"
#include "SkeletonAnimDef.h"
///////////////////////////////////////////////////////////////////////////////
// SPropPoint: structure describing a prop point
struct SPropPoint
{
// name of the prop point
CStr m_Name;
// position of the point
CVector3D m_Position;
// rotation of the point
CQuaternion m_Rotation;
// object to parent space transformation
CMatrix3D m_Transform;
// index of parent bone; 0xff if unboned
u8 m_BoneIndex;
};
///////////////////////////////////////////////////////////////////////////////
// SPropPoint: structure describing a prop point
struct SPropPoint
{
// name of the prop point
CStr m_Name;
// position of the point
CVector3D m_Position;
// rotation of the point
CQuaternion m_Rotation;
// object to parent space transformation
CMatrix3D m_Transform;
// index of parent bone; 0xff if unboned
u8 m_BoneIndex;
};
///////////////////////////////////////////////////////////////////////////////
// SVertexBlend: structure containing the necessary data for blending vertices
@ -100,10 +100,10 @@ public:
// accessor: get bone data
int GetNumBones() const { return m_NumBones; }
CBoneState *GetBones() const { return m_Bones; }
// find and return pointer to prop point matching given name; return
// null if no match (case insensitive search)
SPropPoint* FindPropPoint(const char* name) const;
// find and return pointer to prop point matching given name; return
// null if no match (case insensitive search)
SPropPoint* FindPropPoint(const char* name) const;
public:
// vertex data
@ -114,9 +114,9 @@ public:
SModelFace* m_pFaces;
// bone data - default model pose
u32 m_NumBones;
CBoneState* m_Bones;
// prop point data
u32 m_NumPropPoints;
CBoneState* m_Bones;
// prop point data
u32 m_NumPropPoints;
SPropPoint* m_PropPoints;
};

View File

@ -1,321 +1,321 @@
#include "ObjectEntry.h"
#include "ObjectManager.h"
#include "Model.h"
#include "ModelDef.h"
#include "UnitManager.h"
// xerces XML stuff
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
// Gee's custom error handler
#include <ps/XercesErrorHandler.h>
#ifdef _MSC_VER
#pragma comment(lib, "xerces-c_2.lib")
#endif
// automatically use namespace ..
XERCES_CPP_NAMESPACE_USE
CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type)
{
m_IdleAnim=0;
m_WalkAnim=0;
m_DeathAnim=0;
m_MeleeAnim=0;
m_RangedAnim=0;
}
CObjectEntry::~CObjectEntry()
{
for (size_t i=0;i<m_Animations.size();i++) {
CSkeletonAnim* anim=m_Animations[i].m_AnimData;
delete anim;
}
delete m_Model;
}
bool CObjectEntry::BuildModel()
{
debug_out("Building model %s\n",(const char*) m_Name);
// check we've enough data to consider building the object
if (m_ModelName.Length()==0 || m_TextureName.Length()==0) {
return false;
}
// get the root directory of this object
CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name;
// remember the old model so we can replace any models using it later on
CModelDef* oldmodel=m_Model ? m_Model->GetModelDef() : 0;
// build filename
CStr modelfilename("mods\\official\\");
modelfilename+=m_ModelName;
// try and create a model
CModelDef* modeldef;
try {
modeldef=CModelDef::Load((const char*) modelfilename);
} catch (...) {
return false;
}
// create new Model
m_Model=new CModel;
m_Model->SetTexture((const char*) m_TextureName);
m_Model->InitModel(modeldef);
// calculate initial object space bounds, based on vertex positions
m_Model->CalcObjectBounds();
// load animations
for( uint t = 0; t < m_Animations.size(); t++ )
{
if( m_Animations[t].m_FileName.Length() > 0 )
{
CStr animfilename( "mods\\official\\" );
animfilename += m_Animations[t].m_FileName;
m_Animations[t].m_AnimData = m_Model->BuildAnimation((const char*) animfilename,m_Animations[t].m_Speed);
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) )
m_IdleAnim = m_Animations[t].m_AnimData;
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) )
m_WalkAnim = m_Animations[t].m_AnimData;
}
else
{
// FIXME, RC - don't store invalid animations
m_Animations[t].m_AnimData=0;
}
}
// start up idling
m_Model->SetAnimation( m_IdleAnim );
// build props - TODO, RC - need to fix up bounds here
for (uint p=0;p<m_Props.size();p++) {
const Prop& prop=m_Props[p];
SPropPoint* proppoint=modeldef->FindPropPoint((const char*) prop.m_PropPointName);
if (proppoint) {
CObjectEntry* oe=g_ObjMan.FindObject(prop.m_ModelName);
if (oe) {
// try and build model if we haven't already got it
if (!oe->m_Model) oe->BuildModel();
if (oe->m_Model) {
CModel* propmodel=oe->m_Model->Clone();
m_Model->AddProp(proppoint,propmodel);
if (oe->m_WalkAnim) propmodel->SetAnimation(oe->m_WalkAnim);
}
}
}
}
// build world space bounds
m_Model->CalcBounds();
// replace any units using old model to now use new model; also reprop models, if necessary
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
for (uint i=0;i<units.size();++i) {
CModel* unitmodel=units[i]->GetModel();
if (unitmodel->GetModelDef()==oldmodel) {
unitmodel->InitModel(m_Model->GetModelDef());
const std::vector<CModel::Prop>& newprops=m_Model->GetProps();
for (uint j=0;j<newprops.size();j++) {
unitmodel->AddProp(newprops[j].m_Point,newprops[j].m_Model->Clone());
}
}
}
// and were done with the old model ..
delete oldmodel;
return true;
}
CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName )
{
for( uint t = 0; t < m_Animations.size(); t++ )
{
if( m_Animations[t].m_AnimName == animationName )
return( m_Animations[t].m_AnimData );
}
return( NULL );
}
CStr Transcode(const XMLCh* xmltext)
{
char* str=XMLString::transcode(xmltext);
CStr result(str);
XMLString::release(&str);
return result;
}
bool CObjectEntry::Load(const char* filename)
{
bool parseOK = false;
// Initialize XML library
XMLPlatformUtils::Initialize();
{
XMLCh* attachpointtext=XMLString::transcode("attachpoint");
XMLCh* modeltext=XMLString::transcode("model");
XMLCh* nametext=XMLString::transcode("name");
XMLCh* filetext=XMLString::transcode("file");
XMLCh* speedtext=XMLString::transcode("speed");
// Create parser instance
XercesDOMParser *parser = new XercesDOMParser();
// Setup parser
parser->setValidationScheme(XercesDOMParser::Val_Auto);
parser->setDoNamespaces(false);
parser->setDoSchema(false);
parser->setCreateEntityReferenceNodes(false);
// Set customized error handler
CXercesErrorHandler *errorHandler = new CXercesErrorHandler();
parser->setErrorHandler(errorHandler);
// Push the CLogger to mark it's reading this file.
// Get main node
XMLCh* xfilename=XMLString::transcode(filename);
LocalFileInputSource source(xfilename);
XMLString::release(&xfilename);
// Parse file
parser->parse(source);
// Check how many errors
parseOK = parser->getErrorCount() == 0;
if (parseOK) {
// parsed successfully - grab our data
DOMDocument *doc = parser->getDocument();
DOMElement *element = doc->getDocumentElement();
// root_name should be Object
CStr root_name = Transcode( element->getNodeName() );
// should have at least 3 children - Name, ModelName and TextureName
DOMNodeList *children = element->getChildNodes();
int numChildren=children->getLength();
for (int i=0; i<numChildren; ++i) {
// Get node
DOMNode *child = children->item(i);
// A child element
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
{
// First get element and not node
DOMElement *child_element = (DOMElement*)child;
CStr element_name = Transcode( child_element->getNodeName() );
DOMNode *value_node= child_element->getChildNodes()->item(0);
CStr element_value=value_node ? Transcode(value_node->getNodeValue()) : "";
if (element_name==CStr("Name")) {
m_Name=element_value;
} else if (element_name==CStr("ModelName")) {
m_ModelName=element_value;
} else if (element_name==CStr("TextureName")) {
m_TextureName=element_value;
} else if (element_name==CStr("Animations")) {
DOMNodeList* animations=(DOMNodeList*) child_element->getChildNodes();
for (uint j=0; j<animations->getLength(); ++j) {
DOMElement *anim_element = (DOMElement*) animations->item(j);
CStr element_name = Transcode( anim_element->getNodeName() );
DOMNamedNodeMap* attributes=anim_element->getAttributes();
if (attributes) {
Anim anim;
DOMNode *nameattr=attributes->getNamedItem(nametext);
anim.m_AnimName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
DOMNode *fileattr=attributes->getNamedItem(filetext);
anim.m_FileName=Transcode(fileattr->getChildNodes()->item(0)->getNodeValue());
DOMNode *speedattr=attributes->getNamedItem(speedtext);
CStr speedstr=Transcode(speedattr->getChildNodes()->item(0)->getNodeValue());
anim.m_Speed=float(atoi((const char*) speedstr))/100.0f;
if (anim.m_Speed<=0) anim.m_Speed=1.0f;
m_Animations.push_back(anim);
}
}
} else if (element_name==CStr("Props")) {
DOMNodeList* props=(DOMNodeList*) child_element->getChildNodes();
for (uint j=0; j<props->getLength(); ++j) {
DOMElement *prop_element = (DOMElement*) props->item(j);
CStr element_name = Transcode( prop_element->getNodeName() );
DOMNamedNodeMap* attributes=prop_element->getAttributes();
if (attributes) {
Prop prop;
DOMNode *nameattr=attributes->getNamedItem(attachpointtext);
prop.m_PropPointName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
DOMNode *modelattr=attributes->getNamedItem(modeltext);
prop.m_ModelName=XMLString::transcode(modelattr->getChildNodes()->item(0)->getNodeValue());
m_Props.push_back(prop);
}
}
}
}
}
}
XMLString::release(&attachpointtext);
XMLString::release(&modeltext);
XMLString::release(&nametext);
XMLString::release(&filetext);
XMLString::release(&speedtext);
delete parser;
delete errorHandler;
}
XMLPlatformUtils::Terminate();
return parseOK;
}
bool CObjectEntry::Save(const char* filename)
{
FILE* fp=fopen(filename,"w");
if (!fp) return false;
// write XML header
fprintf(fp,"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n\n");
fprintf(fp,"<!DOCTYPE Object SYSTEM \"..\\object.dtd\">\n\n");
// write the object itself
fprintf(fp,"<!-- File automatically generated by ScEd -->\n");
fprintf(fp,"<Object>\n");
fprintf(fp,"\t<Name>%s</Name>\n",(const char*) m_Name);
fprintf(fp,"\t<ModelName>%s</ModelName>\n",(const char*) m_ModelName);
fprintf(fp,"\t<TextureName>%s</TextureName>\n",(const char*) m_TextureName);
if (m_Animations.size()>0) {
fprintf(fp,"\t<Animations>\n");
for (uint i=0;i<m_Animations.size();i++) {
fprintf(fp,"\t\t<Animation name=\"%s\" file=\"%s\"> </Animation>\n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName);
}
fprintf(fp,"\t</Animations>\n");
}
fprintf(fp,"</Object>\n");
fclose(fp);
return true;
}
#include "ObjectEntry.h"
#include "ObjectManager.h"
#include "Model.h"
#include "ModelDef.h"
#include "UnitManager.h"
// xerces XML stuff
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
// Gee's custom error handler
#include <ps/XercesErrorHandler.h>
#ifdef _MSC_VER
#pragma comment(lib, "xerces-c_2.lib")
#endif
// automatically use namespace ..
XERCES_CPP_NAMESPACE_USE
CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type)
{
m_IdleAnim=0;
m_WalkAnim=0;
m_DeathAnim=0;
m_MeleeAnim=0;
m_RangedAnim=0;
}
CObjectEntry::~CObjectEntry()
{
for (size_t i=0;i<m_Animations.size();i++) {
CSkeletonAnim* anim=m_Animations[i].m_AnimData;
delete anim;
}
delete m_Model;
}
bool CObjectEntry::BuildModel()
{
debug_out("Building model %s\n",(const char*) m_Name);
// check we've enough data to consider building the object
if (m_ModelName.Length()==0 || m_TextureName.Length()==0) {
return false;
}
// get the root directory of this object
CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name;
// remember the old model so we can replace any models using it later on
CModelDef* oldmodel=m_Model ? m_Model->GetModelDef() : 0;
// build filename
CStr modelfilename("mods\\official\\");
modelfilename+=m_ModelName;
// try and create a model
CModelDef* modeldef;
try {
modeldef=CModelDef::Load((const char*) modelfilename);
} catch (...) {
return false;
}
// create new Model
m_Model=new CModel;
m_Model->SetTexture((const char*) m_TextureName);
m_Model->InitModel(modeldef);
// calculate initial object space bounds, based on vertex positions
m_Model->CalcObjectBounds();
// load animations
for( uint t = 0; t < m_Animations.size(); t++ )
{
if( m_Animations[t].m_FileName.Length() > 0 )
{
CStr animfilename( "mods\\official\\" );
animfilename += m_Animations[t].m_FileName;
m_Animations[t].m_AnimData = m_Model->BuildAnimation((const char*) animfilename,m_Animations[t].m_Speed);
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) )
m_IdleAnim = m_Animations[t].m_AnimData;
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) )
m_WalkAnim = m_Animations[t].m_AnimData;
}
else
{
// FIXME, RC - don't store invalid animations
m_Animations[t].m_AnimData=0;
}
}
// start up idling
m_Model->SetAnimation( m_IdleAnim );
// build props - TODO, RC - need to fix up bounds here
for (uint p=0;p<m_Props.size();p++) {
const Prop& prop=m_Props[p];
SPropPoint* proppoint=modeldef->FindPropPoint((const char*) prop.m_PropPointName);
if (proppoint) {
CObjectEntry* oe=g_ObjMan.FindObject(prop.m_ModelName);
if (oe) {
// try and build model if we haven't already got it
if (!oe->m_Model) oe->BuildModel();
if (oe->m_Model) {
CModel* propmodel=oe->m_Model->Clone();
m_Model->AddProp(proppoint,propmodel);
if (oe->m_WalkAnim) propmodel->SetAnimation(oe->m_WalkAnim);
}
}
}
}
// build world space bounds
m_Model->CalcBounds();
// replace any units using old model to now use new model; also reprop models, if necessary
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
for (uint i=0;i<units.size();++i) {
CModel* unitmodel=units[i]->GetModel();
if (unitmodel->GetModelDef()==oldmodel) {
unitmodel->InitModel(m_Model->GetModelDef());
const std::vector<CModel::Prop>& newprops=m_Model->GetProps();
for (uint j=0;j<newprops.size();j++) {
unitmodel->AddProp(newprops[j].m_Point,newprops[j].m_Model->Clone());
}
}
}
// and were done with the old model ..
delete oldmodel;
return true;
}
CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName )
{
for( uint t = 0; t < m_Animations.size(); t++ )
{
if( m_Animations[t].m_AnimName == animationName )
return( m_Animations[t].m_AnimData );
}
return( NULL );
}
CStr Transcode(const XMLCh* xmltext)
{
char* str=XMLString::transcode(xmltext);
CStr result(str);
XMLString::release(&str);
return result;
}
bool CObjectEntry::Load(const char* filename)
{
bool parseOK = false;
// Initialize XML library
XMLPlatformUtils::Initialize();
{
XMLCh* attachpointtext=XMLString::transcode("attachpoint");
XMLCh* modeltext=XMLString::transcode("model");
XMLCh* nametext=XMLString::transcode("name");
XMLCh* filetext=XMLString::transcode("file");
XMLCh* speedtext=XMLString::transcode("speed");
// Create parser instance
XercesDOMParser *parser = new XercesDOMParser();
// Setup parser
parser->setValidationScheme(XercesDOMParser::Val_Auto);
parser->setDoNamespaces(false);
parser->setDoSchema(false);
parser->setCreateEntityReferenceNodes(false);
// Set customized error handler
CXercesErrorHandler *errorHandler = new CXercesErrorHandler();
parser->setErrorHandler(errorHandler);
// Push the CLogger to mark it's reading this file.
// Get main node
XMLCh* xfilename=XMLString::transcode(filename);
LocalFileInputSource source(xfilename);
XMLString::release(&xfilename);
// Parse file
parser->parse(source);
// Check how many errors
parseOK = parser->getErrorCount() == 0;
if (parseOK) {
// parsed successfully - grab our data
DOMDocument *doc = parser->getDocument();
DOMElement *element = doc->getDocumentElement();
// root_name should be Object
CStr root_name = Transcode( element->getNodeName() );
// should have at least 3 children - Name, ModelName and TextureName
DOMNodeList *children = element->getChildNodes();
int numChildren=children->getLength();
for (int i=0; i<numChildren; ++i) {
// Get node
DOMNode *child = children->item(i);
// A child element
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
{
// First get element and not node
DOMElement *child_element = (DOMElement*)child;
CStr element_name = Transcode( child_element->getNodeName() );
DOMNode *value_node= child_element->getChildNodes()->item(0);
CStr element_value=value_node ? Transcode(value_node->getNodeValue()) : "";
if (element_name==CStr("Name")) {
m_Name=element_value;
} else if (element_name==CStr("ModelName")) {
m_ModelName=element_value;
} else if (element_name==CStr("TextureName")) {
m_TextureName=element_value;
} else if (element_name==CStr("Animations")) {
DOMNodeList* animations=(DOMNodeList*) child_element->getChildNodes();
for (uint j=0; j<animations->getLength(); ++j) {
DOMElement *anim_element = (DOMElement*) animations->item(j);
CStr element_name = Transcode( anim_element->getNodeName() );
DOMNamedNodeMap* attributes=anim_element->getAttributes();
if (attributes) {
Anim anim;
DOMNode *nameattr=attributes->getNamedItem(nametext);
anim.m_AnimName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
DOMNode *fileattr=attributes->getNamedItem(filetext);
anim.m_FileName=Transcode(fileattr->getChildNodes()->item(0)->getNodeValue());
DOMNode *speedattr=attributes->getNamedItem(speedtext);
CStr speedstr=Transcode(speedattr->getChildNodes()->item(0)->getNodeValue());
anim.m_Speed=float(atoi((const char*) speedstr))/100.0f;
if (anim.m_Speed<=0) anim.m_Speed=1.0f;
m_Animations.push_back(anim);
}
}
} else if (element_name==CStr("Props")) {
DOMNodeList* props=(DOMNodeList*) child_element->getChildNodes();
for (uint j=0; j<props->getLength(); ++j) {
DOMElement *prop_element = (DOMElement*) props->item(j);
CStr element_name = Transcode( prop_element->getNodeName() );
DOMNamedNodeMap* attributes=prop_element->getAttributes();
if (attributes) {
Prop prop;
DOMNode *nameattr=attributes->getNamedItem(attachpointtext);
prop.m_PropPointName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
DOMNode *modelattr=attributes->getNamedItem(modeltext);
prop.m_ModelName=XMLString::transcode(modelattr->getChildNodes()->item(0)->getNodeValue());
m_Props.push_back(prop);
}
}
}
}
}
}
XMLString::release(&attachpointtext);
XMLString::release(&modeltext);
XMLString::release(&nametext);
XMLString::release(&filetext);
XMLString::release(&speedtext);
delete parser;
delete errorHandler;
}
XMLPlatformUtils::Terminate();
return parseOK;
}
bool CObjectEntry::Save(const char* filename)
{
FILE* fp=fopen(filename,"w");
if (!fp) return false;
// write XML header
fprintf(fp,"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n\n");
fprintf(fp,"<!DOCTYPE Object SYSTEM \"..\\object.dtd\">\n\n");
// write the object itself
fprintf(fp,"<!-- File automatically generated by ScEd -->\n");
fprintf(fp,"<Object>\n");
fprintf(fp,"\t<Name>%s</Name>\n",(const char*) m_Name);
fprintf(fp,"\t<ModelName>%s</ModelName>\n",(const char*) m_ModelName);
fprintf(fp,"\t<TextureName>%s</TextureName>\n",(const char*) m_TextureName);
if (m_Animations.size()>0) {
fprintf(fp,"\t<Animations>\n");
for (uint i=0;i<m_Animations.size();i++) {
fprintf(fp,"\t\t<Animation name=\"%s\" file=\"%s\"> </Animation>\n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName);
}
fprintf(fp,"\t</Animations>\n");
}
fprintf(fp,"</Object>\n");
fclose(fp);
return true;
}

View File

@ -1,65 +1,65 @@
#ifndef _OBJECTENTRY_H
#define _OBJECTENTRY_H
class CModel;
class CSkeletonAnim;
#include <vector>
#include "CStr.h"
#include "Bound.h"
#include "ModelDef.h"
class CObjectEntry
{
public:
struct Anim {
// name of the animation - "Idle", "Run", etc
CStr m_AnimName;
// filename of the animation - manidle.psa, manrun.psa, etc
CStr m_FileName;
// animation speed, as specified in XML actor file
float m_Speed;
// the animation data, specific to the this model
CSkeletonAnim* m_AnimData;
};
struct Prop {
// name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc ..
CStr m_PropPointName;
// name of the model file - art/actors/props/sword.xml or whatever
CStr m_ModelName;
};
public:
CObjectEntry(int type);
~CObjectEntry();
bool BuildModel();
bool Load(const char* filename);
bool Save(const char* filename);
// object name
CStr m_Name;
// texture name
CStr m_TextureName;
// model name
CStr m_ModelName;
// list of valid animations for this object
std::vector<Anim> m_Animations;
CSkeletonAnim* m_IdleAnim;
CSkeletonAnim* m_WalkAnim;
CSkeletonAnim* m_DeathAnim;
CSkeletonAnim* m_MeleeAnim;
CSkeletonAnim* m_RangedAnim;
CSkeletonAnim* GetNamedAnimation( CStr animationName );
// list of props attached to object
std::vector<Prop> m_Props;
// corresponding model
CModel* m_Model;
// type of object; index into object managers types array
int m_Type;
};
#endif
#ifndef _OBJECTENTRY_H
#define _OBJECTENTRY_H
class CModel;
class CSkeletonAnim;
#include <vector>
#include "CStr.h"
#include "Bound.h"
#include "ModelDef.h"
class CObjectEntry
{
public:
struct Anim {
// name of the animation - "Idle", "Run", etc
CStr m_AnimName;
// filename of the animation - manidle.psa, manrun.psa, etc
CStr m_FileName;
// animation speed, as specified in XML actor file
float m_Speed;
// the animation data, specific to the this model
CSkeletonAnim* m_AnimData;
};
struct Prop {
// name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc ..
CStr m_PropPointName;
// name of the model file - art/actors/props/sword.xml or whatever
CStr m_ModelName;
};
public:
CObjectEntry(int type);
~CObjectEntry();
bool BuildModel();
bool Load(const char* filename);
bool Save(const char* filename);
// object name
CStr m_Name;
// texture name
CStr m_TextureName;
// model name
CStr m_ModelName;
// list of valid animations for this object
std::vector<Anim> m_Animations;
CSkeletonAnim* m_IdleAnim;
CSkeletonAnim* m_WalkAnim;
CSkeletonAnim* m_DeathAnim;
CSkeletonAnim* m_MeleeAnim;
CSkeletonAnim* m_RangedAnim;
CSkeletonAnim* GetNamedAnimation( CStr animationName );
// list of props attached to object
std::vector<Prop> m_Props;
// corresponding model
CModel* m_Model;
// type of object; index into object managers types array
int m_Type;
};
#endif

View File

@ -8,15 +8,15 @@ CObjectManager::CObjectManager() : m_SelectedObject(0)
m_ObjectTypes.reserve(32);
}
CObjectManager::~CObjectManager()
{
m_SelectedObject=0;
for (size_t i=0;i<m_ObjectTypes.size();i++) {
for (size_t j=0;j<m_ObjectTypes[i].m_Objects.size();j++) {
delete m_ObjectTypes[i].m_Objects[j];
}
}
}
CObjectManager::~CObjectManager()
{
m_SelectedObject=0;
for (size_t i=0;i<m_ObjectTypes.size();i++) {
for (size_t j=0;j<m_ObjectTypes[i].m_Objects.size();j++) {
delete m_ObjectTypes[i].m_Objects[j];
}
}
}
CObjectEntry* CObjectManager::FindObject(const char* objectname)
{
@ -65,25 +65,25 @@ void CObjectManager::LoadObjects()
BuildObjectTypes();
// now iterate through terrain types loading all textures of that type
uint i;
uint i;
for (i=0;i<m_ObjectTypes.size();i++) {
LoadObjects(i);
}
// now build all the models
for (i=0;i<m_ObjectTypes.size();i++) {
std::vector<CObjectEntry*>& objects=m_ObjectTypes[i].m_Objects;
for (uint j=0;j<objects.size();j++) {
// object might have already been built (eg if it's a prop);
// and only build if we haven't a model
if (!objects[j]->m_Model) {
if (!objects[j]->BuildModel()) {
DeleteObject(objects[j]);
}
}
}
}
// now build all the models
for (i=0;i<m_ObjectTypes.size();i++) {
std::vector<CObjectEntry*>& objects=m_ObjectTypes[i].m_Objects;
for (uint j=0;j<objects.size();j++) {
// object might have already been built (eg if it's a prop);
// and only build if we haven't a model
if (!objects[j]->m_Model) {
if (!objects[j]->BuildModel()) {
DeleteObject(objects[j]);
}
}
}
}
}
void CObjectManager::BuildObjectTypes()

View File

@ -1,15 +1,15 @@
#ifndef _OBJECTMANAGER_H
#define _OBJECTMANAGER_H
#include <vector>
#include <vector>
#include "Singleton.h"
#include "ObjectEntry.h"
// access to sole CObjectManager object
#define g_ObjMan CObjectManager::GetSingleton()
///////////////////////////////////////////////////////////////////////////////////////////
// CObjectManager: manager class for all possible actor types
// access to sole CObjectManager object
#define g_ObjMan CObjectManager::GetSingleton()
///////////////////////////////////////////////////////////////////////////////////////////
// CObjectManager: manager class for all possible actor types
class CObjectManager : public Singleton<CObjectManager>
{
public:
@ -23,10 +23,10 @@ public:
std::vector<CObjectEntry*> m_Objects;
};
public:
public:
// constructor, destructor
CObjectManager();
~CObjectManager();
~CObjectManager();
void LoadObjects();

View File

@ -1,104 +1,104 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: RenderableObject.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _RENDERABLEOBJECT_H
#define _RENDERABLEOBJECT_H
#include <assert.h>
#include "res/res.h"
#include "Bound.h"
#include "Matrix3D.h"
// dirty flags - used as notification to the renderer that some bit of data
// need updating
#define RENDERDATA_UPDATE_VERTICES (1<<1)
#define RENDERDATA_UPDATE_INDICES (1<<2)
#define RENDERDATA_UPDATE_TRANSFORM (1<<3)
///////////////////////////////////////////////////////////////////////////////
// CRenderData: base class of all the renderer's renderdata classes - the
// derived class stores necessary information for rendering an object of a
// particular type
class CRenderData
{
public:
CRenderData() : m_UpdateFlags(0) {}
virtual ~CRenderData() {}
u32 m_UpdateFlags;
};
///////////////////////////////////////////////////////////////////////////////
// CRenderableObject: base class of all renderable objects - patches, models,
// sprites, etc; stores position and bound information, and a pointer to
// some renderdata necessary for the renderer to actually render it
class CRenderableObject
{
public:
// constructor
CRenderableObject() : m_RenderData(0) {
m_Transform.SetIdentity();
}
// destructor
virtual ~CRenderableObject() { delete m_RenderData; }
// set object transform
virtual void SetTransform(const CMatrix3D& transform) {
// store transform, calculate inverse
m_Transform=transform;
m_Transform.GetInverse(m_InvTransform);
// normal recalculation likely required on transform change; flag it
SetDirty(RENDERDATA_UPDATE_VERTICES);
// rebuild world space bounds
CalcBounds();
}
// get object to world space transform
const CMatrix3D& GetTransform() const { return m_Transform; }
// get world to object space transform
const CMatrix3D& GetInvTransform() const { return m_InvTransform; }
// mark some part of the renderdata as dirty, and requiring
// an update on next render
void SetDirty(u32 dirtyflags) {
if (m_RenderData) m_RenderData->m_UpdateFlags|=dirtyflags;
}
// calculate (and store in m_Bounds) the world space bounds of this object
// - must be implemented by all concrete subclasses
virtual void CalcBounds() = 0;
// return world space bounds of this object
const CBound& GetBounds() const { return m_Bounds; }
// set the object renderdata
// TODO,RC 10/04/04 - need to delete existing renderdata here, or can we
// assume the renderer won't set renderdata when an object already has it?
// - just assert we've no renderdata at the minute
void SetRenderData(CRenderData* renderdata) {
assert(m_RenderData==0);
m_RenderData=renderdata;
}
// return object renderdata - can be null if renderer hasn't yet
// created the renderdata
CRenderData* GetRenderData() { return m_RenderData; }
protected:
// object bounds
CBound m_Bounds;
// local->world space transform
CMatrix3D m_Transform;
// world->local space transform
CMatrix3D m_InvTransform;
// object renderdata
CRenderData* m_RenderData;
};
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Name: RenderableObject.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _RENDERABLEOBJECT_H
#define _RENDERABLEOBJECT_H
#include <assert.h>
#include "res/res.h"
#include "Bound.h"
#include "Matrix3D.h"
// dirty flags - used as notification to the renderer that some bit of data
// need updating
#define RENDERDATA_UPDATE_VERTICES (1<<1)
#define RENDERDATA_UPDATE_INDICES (1<<2)
#define RENDERDATA_UPDATE_TRANSFORM (1<<3)
///////////////////////////////////////////////////////////////////////////////
// CRenderData: base class of all the renderer's renderdata classes - the
// derived class stores necessary information for rendering an object of a
// particular type
class CRenderData
{
public:
CRenderData() : m_UpdateFlags(0) {}
virtual ~CRenderData() {}
u32 m_UpdateFlags;
};
///////////////////////////////////////////////////////////////////////////////
// CRenderableObject: base class of all renderable objects - patches, models,
// sprites, etc; stores position and bound information, and a pointer to
// some renderdata necessary for the renderer to actually render it
class CRenderableObject
{
public:
// constructor
CRenderableObject() : m_RenderData(0) {
m_Transform.SetIdentity();
}
// destructor
virtual ~CRenderableObject() { delete m_RenderData; }
// set object transform
virtual void SetTransform(const CMatrix3D& transform) {
// store transform, calculate inverse
m_Transform=transform;
m_Transform.GetInverse(m_InvTransform);
// normal recalculation likely required on transform change; flag it
SetDirty(RENDERDATA_UPDATE_VERTICES);
// rebuild world space bounds
CalcBounds();
}
// get object to world space transform
const CMatrix3D& GetTransform() const { return m_Transform; }
// get world to object space transform
const CMatrix3D& GetInvTransform() const { return m_InvTransform; }
// mark some part of the renderdata as dirty, and requiring
// an update on next render
void SetDirty(u32 dirtyflags) {
if (m_RenderData) m_RenderData->m_UpdateFlags|=dirtyflags;
}
// calculate (and store in m_Bounds) the world space bounds of this object
// - must be implemented by all concrete subclasses
virtual void CalcBounds() = 0;
// return world space bounds of this object
const CBound& GetBounds() const { return m_Bounds; }
// set the object renderdata
// TODO,RC 10/04/04 - need to delete existing renderdata here, or can we
// assume the renderer won't set renderdata when an object already has it?
// - just assert we've no renderdata at the minute
void SetRenderData(CRenderData* renderdata) {
assert(m_RenderData==0);
m_RenderData=renderdata;
}
// return object renderdata - can be null if renderer hasn't yet
// created the renderdata
CRenderData* GetRenderData() { return m_RenderData; }
protected:
// object bounds
CBound m_Bounds;
// local->world space transform
CMatrix3D m_Transform;
// world->local space transform
CMatrix3D m_InvTransform;
// object renderdata
CRenderData* m_RenderData;
};
#endif

View File

@ -1,30 +1,30 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnim.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _SKELETONANIM_H
#define _SKELETONANIM_H
#include "Bound.h"
class CSkeletonAnimDef;
////////////////////////////////////////////////////////////////////////////////////////
// CSkeletonAnim: an instance of a CSkeletonAnimDef, for application onto a model
class CSkeletonAnim
{
public:
// the raw animation frame data
CSkeletonAnimDef* m_AnimDef;
// speed at which this animation runs
float m_Speed;
// object space bounds of the model when this animation is applied to it
CBound m_ObjectBounds;
};
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnim.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _SKELETONANIM_H
#define _SKELETONANIM_H
#include "Bound.h"
class CSkeletonAnimDef;
////////////////////////////////////////////////////////////////////////////////////////
// CSkeletonAnim: an instance of a CSkeletonAnimDef, for application onto a model
class CSkeletonAnim
{
public:
// the raw animation frame data
CSkeletonAnimDef* m_AnimDef;
// speed at which this animation runs
float m_Speed;
// object space bounds of the model when this animation is applied to it
CBound m_ObjectBounds;
};
#endif

View File

@ -1,85 +1,85 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnimDef.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _SKELETONANIMDEF_H
#define _SKELETONANIMDEF_H
#include "res/res.h"
#include "CStr.h"
#include "Vector3D.h"
#include "Quaternion.h"
////////////////////////////////////////////////////////////////////////////////////////
// CBoneState: structure describing state of a bone at some point
class CBoneState
{
public:
// translation of bone relative to root
CVector3D m_Translation;
// rotation of bone relative to root
CQuaternion m_Rotation;
};
////////////////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimDef: raw description - eg bonestates - of an animation that plays upon
// a skeleton
class CSkeletonAnimDef
{
public:
// current file version given to saved animations
enum { FILE_VERSION = 1 };
// supported file read version - files with a version less than this will be rejected
enum { FILE_READ_VERSION = 1 };
public:
// Key: description of a single key in a skeleton animation
typedef CBoneState Key;
public:
// CSkeletonAnimDef constructor + destructor
CSkeletonAnimDef();
~CSkeletonAnimDef();
// return the number of keys in this animation
u32 GetNumKeys() const { return m_NumKeys; }
// accessors: get a key for given bone at given time
Key& GetKey(u32 frame,u32 bone) { return m_Keys[frame*m_NumKeys+bone]; }
const Key& GetKey(u32 frame,u32 bone) const { return m_Keys[frame*m_NumKeys+bone]; }
// get duration of this anim, in ms
float GetDuration() const { return m_NumFrames*m_FrameTime; }
// return length of each frame, in ms
float GetFrameTime() const { return m_FrameTime; }
// return number of frames in animation
u32 GetNumFrames() const { return m_NumFrames; }
// build matrices for all bones at the given time (in MS) in this animation
void BuildBoneMatrices(float time,CMatrix3D* matrices) const;
// anim I/O functions
static CSkeletonAnimDef* Load(const char* filename);
static void Save(const char* filename,const CSkeletonAnimDef* anim);
public:
// name of the animation
CStr m_Name;
// frame time - time between successive frames, in ms
float m_FrameTime;
// number of keys in each frame - should match number of bones in the skeleton
u32 m_NumKeys;
// number of frames in the animation
u32 m_NumFrames;
// animation data - m_NumKeys*m_NumFrames total keys
Key* m_Keys;
};
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnimDef.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _SKELETONANIMDEF_H
#define _SKELETONANIMDEF_H
#include "res/res.h"
#include "CStr.h"
#include "Vector3D.h"
#include "Quaternion.h"
////////////////////////////////////////////////////////////////////////////////////////
// CBoneState: structure describing state of a bone at some point
class CBoneState
{
public:
// translation of bone relative to root
CVector3D m_Translation;
// rotation of bone relative to root
CQuaternion m_Rotation;
};
////////////////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimDef: raw description - eg bonestates - of an animation that plays upon
// a skeleton
class CSkeletonAnimDef
{
public:
// current file version given to saved animations
enum { FILE_VERSION = 1 };
// supported file read version - files with a version less than this will be rejected
enum { FILE_READ_VERSION = 1 };
public:
// Key: description of a single key in a skeleton animation
typedef CBoneState Key;
public:
// CSkeletonAnimDef constructor + destructor
CSkeletonAnimDef();
~CSkeletonAnimDef();
// return the number of keys in this animation
u32 GetNumKeys() const { return m_NumKeys; }
// accessors: get a key for given bone at given time
Key& GetKey(u32 frame,u32 bone) { return m_Keys[frame*m_NumKeys+bone]; }
const Key& GetKey(u32 frame,u32 bone) const { return m_Keys[frame*m_NumKeys+bone]; }
// get duration of this anim, in ms
float GetDuration() const { return m_NumFrames*m_FrameTime; }
// return length of each frame, in ms
float GetFrameTime() const { return m_FrameTime; }
// return number of frames in animation
u32 GetNumFrames() const { return m_NumFrames; }
// build matrices for all bones at the given time (in MS) in this animation
void BuildBoneMatrices(float time,CMatrix3D* matrices) const;
// anim I/O functions
static CSkeletonAnimDef* Load(const char* filename);
static void Save(const char* filename,const CSkeletonAnimDef* anim);
public:
// name of the animation
CStr m_Name;
// frame time - time between successive frames, in ms
float m_FrameTime;
// number of keys in each frame - should match number of bones in the skeleton
u32 m_NumKeys;
// number of frames in the animation
u32 m_NumFrames;
// animation data - m_NumKeys*m_NumFrames total keys
Key* m_Keys;
};
#endif

View File

@ -1,67 +1,67 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnimManager.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "res/res.h"
#include "Model.h"
#include "SkeletonAnimManager.h"
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimManager constructor
CSkeletonAnimManager::CSkeletonAnimManager()
{
}
///////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimManager destructor
CSkeletonAnimManager::~CSkeletonAnimManager()
{
typedef std::map<CStr,CSkeletonAnimDef*>::iterator Iter;
for (Iter i=m_Animations.begin();i!=m_Animations.end();++i) {
delete i->second;
}
}
///////////////////////////////////////////////////////////////////////////////
// GetAnimation: return a given animation by filename; return null if filename
// doesn't refer to valid animation file
CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const char* filename)
{
// already loaded?
CStr fname(filename);
std::map<CStr,CSkeletonAnimDef*>::iterator iter=m_Animations.find(fname);
if (iter!=m_Animations.end()) {
// yes - return it
return iter->second;
}
// already failed to load?
std::set<CStr>::iterator setiter=m_BadAnimationFiles.find(fname);
if (setiter!=m_BadAnimationFiles.end()) {
// yes - return null
return 0;
}
// try and load it now
CSkeletonAnimDef* def;
try {
def=CSkeletonAnimDef::Load(filename);
} catch (...) {
def=0;
}
if (!def) {
// add this file as bad
m_BadAnimationFiles.insert(fname);
return 0;
} else {
// add mapping for this file
m_Animations[fname]=def;
return def;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnimManager.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "res/res.h"
#include "Model.h"
#include "SkeletonAnimManager.h"
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimManager constructor
CSkeletonAnimManager::CSkeletonAnimManager()
{
}
///////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimManager destructor
CSkeletonAnimManager::~CSkeletonAnimManager()
{
typedef std::map<CStr,CSkeletonAnimDef*>::iterator Iter;
for (Iter i=m_Animations.begin();i!=m_Animations.end();++i) {
delete i->second;
}
}
///////////////////////////////////////////////////////////////////////////////
// GetAnimation: return a given animation by filename; return null if filename
// doesn't refer to valid animation file
CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const char* filename)
{
// already loaded?
CStr fname(filename);
std::map<CStr,CSkeletonAnimDef*>::iterator iter=m_Animations.find(fname);
if (iter!=m_Animations.end()) {
// yes - return it
return iter->second;
}
// already failed to load?
std::set<CStr>::iterator setiter=m_BadAnimationFiles.find(fname);
if (setiter!=m_BadAnimationFiles.end()) {
// yes - return null
return 0;
}
// try and load it now
CSkeletonAnimDef* def;
try {
def=CSkeletonAnimDef::Load(filename);
} catch (...) {
def=0;
}
if (!def) {
// add this file as bad
m_BadAnimationFiles.insert(fname);
return 0;
} else {
// add mapping for this file
m_Animations[fname]=def;
return def;
}
}

View File

@ -1,44 +1,44 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnimManager.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _SKELETONANIMMANAGER_H
#define _SKELETONANIMMANAGER_H
#include <map>
#include <set>
#include "SkeletonAnimDef.h"
#include "Singleton.h"
// access to sole CSkeletonAnimManager object
#define g_SkelAnimMan CSkeletonAnimManager::GetSingleton()
///////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimManager : owner class of all skeleton anims - manages creation,
// loading and destruction of animation data
class CSkeletonAnimManager : public Singleton<CSkeletonAnimManager>
{
public:
// constructor, destructor
CSkeletonAnimManager();
~CSkeletonAnimManager();
// return a given animation by filename; return null if filename doesn't
// refer to valid animation file
CSkeletonAnimDef* GetAnimation(const char* filename);
private:
CSkeletonAnimDef* LoadAnimation(const char* filename);
// map of all known animations
std::map<CStr,CSkeletonAnimDef*> m_Animations;
// set of bad animation names - prevents multiple reloads of bad files
std::set<CStr> m_BadAnimationFiles;
};
///////////////////////////////////////////////////////////////////////////////
//
// Name: SkeletonAnimManager.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _SKELETONANIMMANAGER_H
#define _SKELETONANIMMANAGER_H
#include <map>
#include <set>
#include "SkeletonAnimDef.h"
#include "Singleton.h"
// access to sole CSkeletonAnimManager object
#define g_SkelAnimMan CSkeletonAnimManager::GetSingleton()
///////////////////////////////////////////////////////////////////////////////
// CSkeletonAnimManager : owner class of all skeleton anims - manages creation,
// loading and destruction of animation data
class CSkeletonAnimManager : public Singleton<CSkeletonAnimManager>
{
public:
// constructor, destructor
CSkeletonAnimManager();
~CSkeletonAnimManager();
// return a given animation by filename; return null if filename doesn't
// refer to valid animation file
CSkeletonAnimDef* GetAnimation(const char* filename);
private:
CSkeletonAnimDef* LoadAnimation(const char* filename);
// map of all known animations
std::map<CStr,CSkeletonAnimDef*> m_Animations;
// set of bad animation names - prevents multiple reloads of bad files
std::set<CStr> m_BadAnimationFiles;
};
#endif

View File

@ -25,7 +25,7 @@
==================================================================*/
#include "Sprite.h"
#include "Renderer.h"
#include "Renderer.h"
#include "ogl.h"
#include "res/tex.h"

View File

@ -16,15 +16,15 @@ CTextureManager::CTextureManager()
{
m_TerrainTextures.reserve(32);
}
CTextureManager::~CTextureManager()
{
for (size_t i=0;i<m_TerrainTextures.size();i++) {
for (size_t j=0;j<m_TerrainTextures[i].m_Textures.size();j++) {
delete m_TerrainTextures[i].m_Textures[j];
}
}
}
CTextureManager::~CTextureManager()
{
for (size_t i=0;i<m_TerrainTextures.size();i++) {
for (size_t j=0;j<m_TerrainTextures[i].m_Textures.size();j++) {
delete m_TerrainTextures[i].m_Textures[j];
}
}
}
void CTextureManager::AddTextureType(const char* name)
{

View File

@ -2,15 +2,15 @@
#define _TEXTUREMANAGER_H
#include <vector>
#include "CStr.h"
#include "Singleton.h"
#include "CStr.h"
#include "Singleton.h"
#include "TextureEntry.h"
// access to sole CTextureManager object
#define g_TexMan CTextureManager ::GetSingleton()
///////////////////////////////////////////////////////////////////////////////////////////
// CTextureManager : manager class for all terrain texture objects
// access to sole CTextureManager object
#define g_TexMan CTextureManager ::GetSingleton()
///////////////////////////////////////////////////////////////////////////////////////////
// CTextureManager : manager class for all terrain texture objects
class CTextureManager : public Singleton<CTextureManager>
{
public:
@ -24,10 +24,10 @@ public:
std::vector<CTextureEntry*> m_Textures;
};
public:
public:
// constructor, destructor
CTextureManager();
~CTextureManager();
~CTextureManager();
void LoadTerrainTextures();

View File

@ -1,31 +1,31 @@
#ifndef _UNIT_H
#define _UNIT_H
#include <assert.h>
#include <assert.h>
#include "Model.h"
class CObjectEntry;
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// CUnit: simple "actor" definition - defines a sole object within the world
class CUnit
{
public:
// sole constructor - unit invalid without a model and object
CUnit(CObjectEntry* object,CModel* model) : m_Object(object), m_Model(model) {
assert(object && model);
}
// destructor
~CUnit() {
delete m_Model;
}
// get unit's template object
CObjectEntry* GetObject() { return m_Object; }
// get unit's model data
CModel* GetModel() { return m_Model; }
public:
// sole constructor - unit invalid without a model and object
CUnit(CObjectEntry* object,CModel* model) : m_Object(object), m_Model(model) {
assert(object && model);
}
// destructor
~CUnit() {
delete m_Model;
}
// get unit's template object
CObjectEntry* GetObject() { return m_Object; }
// get unit's model data
CModel* GetModel() { return m_Model; }
private:
// object from which unit was created
CObjectEntry* m_Object;

View File

@ -1,77 +1,77 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: UnitManager.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "res/res.h"
#include "Model.h"
#include "UnitManager.h"
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
// CUnitManager constructor
CUnitManager::CUnitManager()
{
}
///////////////////////////////////////////////////////////////////////////////
// CUnitManager destructor
CUnitManager::~CUnitManager()
{
DeleteAll();
}
///////////////////////////////////////////////////////////////////////////////
// AddUnit: add given unit to world
void CUnitManager::AddUnit(CUnit* unit)
{
m_Units.push_back(unit);
}
///////////////////////////////////////////////////////////////////////////////
// RemoveUnit: remove given unit from world, but don't delete it
void CUnitManager::RemoveUnit(CUnit* unit)
{
// find entry in list
typedef std::vector<CUnit*>::iterator Iter;
Iter i=std::find(m_Units.begin(),m_Units.end(),unit);
if (i!=m_Units.end()) {
m_Units.erase(i);
}
}
///////////////////////////////////////////////////////////////////////////////
// DeleteAll: remove and delete all units
void CUnitManager::DeleteAll()
{
for (uint i=0;i<m_Units.size();i++) {
delete m_Units[i];
}
m_Units.clear();
}
///////////////////////////////////////////////////////////////////////////////
// PickUnit: iterate through units testing given ray against bounds of each
// unit; return the closest unit, or null if everything missed
CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) const
{
// closest object found so far
CUnit* hit=0;
// distance to closest object found so far
float dist=1.0e30f;
for (uint i=0;i<m_Units.size();i++) {
CUnit* unit=m_Units[i];
float tmin,tmax;
if (unit->GetModel()->GetBounds().RayIntersect(origin,dir,tmin,tmax)) {
if (!hit || tmin<dist) {
hit=unit;
dist=tmin;
}
}
}
return hit;
}
///////////////////////////////////////////////////////////////////////////////
//
// Name: UnitManager.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "res/res.h"
#include "Model.h"
#include "UnitManager.h"
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
// CUnitManager constructor
CUnitManager::CUnitManager()
{
}
///////////////////////////////////////////////////////////////////////////////
// CUnitManager destructor
CUnitManager::~CUnitManager()
{
DeleteAll();
}
///////////////////////////////////////////////////////////////////////////////
// AddUnit: add given unit to world
void CUnitManager::AddUnit(CUnit* unit)
{
m_Units.push_back(unit);
}
///////////////////////////////////////////////////////////////////////////////
// RemoveUnit: remove given unit from world, but don't delete it
void CUnitManager::RemoveUnit(CUnit* unit)
{
// find entry in list
typedef std::vector<CUnit*>::iterator Iter;
Iter i=std::find(m_Units.begin(),m_Units.end(),unit);
if (i!=m_Units.end()) {
m_Units.erase(i);
}
}
///////////////////////////////////////////////////////////////////////////////
// DeleteAll: remove and delete all units
void CUnitManager::DeleteAll()
{
for (uint i=0;i<m_Units.size();i++) {
delete m_Units[i];
}
m_Units.clear();
}
///////////////////////////////////////////////////////////////////////////////
// PickUnit: iterate through units testing given ray against bounds of each
// unit; return the closest unit, or null if everything missed
CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) const
{
// closest object found so far
CUnit* hit=0;
// distance to closest object found so far
float dist=1.0e30f;
for (uint i=0;i<m_Units.size();i++) {
CUnit* unit=m_Units[i];
float tmin,tmax;
if (unit->GetModel()->GetBounds().RayIntersect(origin,dir,tmin,tmax)) {
if (!hit || tmin<dist) {
hit=unit;
dist=tmin;
}
}
}
return hit;
}

View File

@ -1,49 +1,49 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: UnitManager.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _UNITMANAGER_H
#define _UNITMANAGER_H
#include <vector>
#include "Unit.h"
#include "Singleton.h"
class CVector3D;
// access to sole CUnitManager object
#define g_UnitMan CUnitManager::GetSingleton()
///////////////////////////////////////////////////////////////////////////////
// CUnitManager: simple container class holding all units within the world
class CUnitManager : public Singleton<CUnitManager>
{
public:
// constructor, destructor
CUnitManager();
~CUnitManager();
// add given unit to world
void AddUnit(CUnit* unit);
// remove given unit from world, but don't delete it
void RemoveUnit(CUnit* unit);
// remove and delete all units
void DeleteAll();
// return the units
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
// iterate through units testing given ray against bounds of each unit;
// return the closest unit, or null if everything missed
CUnit* PickUnit(const CVector3D& origin,const CVector3D& dir) const;
private:
// list of all known units
std::vector<CUnit*> m_Units;
};
///////////////////////////////////////////////////////////////////////////////
//
// Name: UnitManager.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _UNITMANAGER_H
#define _UNITMANAGER_H
#include <vector>
#include "Unit.h"
#include "Singleton.h"
class CVector3D;
// access to sole CUnitManager object
#define g_UnitMan CUnitManager::GetSingleton()
///////////////////////////////////////////////////////////////////////////////
// CUnitManager: simple container class holding all units within the world
class CUnitManager : public Singleton<CUnitManager>
{
public:
// constructor, destructor
CUnitManager();
~CUnitManager();
// add given unit to world
void AddUnit(CUnit* unit);
// remove given unit from world, but don't delete it
void RemoveUnit(CUnit* unit);
// remove and delete all units
void DeleteAll();
// return the units
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
// iterate through units testing given ray against bounds of each unit;
// return the closest unit, or null if everything missed
CUnit* PickUnit(const CVector3D& origin,const CVector3D& dir) const;
private:
// list of all known units
std::vector<CUnit*> m_Units;
};
#endif

View File

@ -1004,12 +1004,12 @@ int tex_bind(const Handle h)
glBindTexture(GL_TEXTURE_2D, t->id);
return 0;
}
int tex_id(const Handle h)
{
Tex* t = H_USER_DATA(h, Tex);
return t ? t->id : 0;
}
int tex_id(const Handle h)
{
Tex* t = H_USER_DATA(h, Tex);
return t ? t->id : 0;
}
int tex_filter = GL_LINEAR;

View File

@ -28,7 +28,7 @@
extern Handle tex_load(const char* const fn, int scope = 0);
extern int tex_bind(Handle ht);
extern int tex_id(Handle ht);
extern int tex_id(Handle ht);
extern int tex_info(Handle ht, int* w, int* h, int *fmt, int *bpp, void** p);

View File

@ -262,7 +262,7 @@ int poll(struct pollfd /* fds */[], int /* nfds */, int /* timeout */)
__declspec(naked) pthread_t pthread_self(void)
{ __asm jmp dword ptr [GetCurrentThreadId] }
{ __asm jmp dword ptr [GetCurrentThread] }
int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param)

View File

@ -226,19 +226,19 @@ void RenderTerrain()
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// SubmitModelRecursive: recurse down given model, submitting it and all it's descendents to the
// renderer
void SubmitModelRecursive(CModel* model)
{
g_Renderer.Submit(model);
const std::vector<CModel::Prop>& props=model->GetProps();
for (uint i=0;i<props.size();i++) {
SubmitModelRecursive(props[i].m_Model);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// SubmitModelRecursive: recurse down given model, submitting it and all it's descendents to the
// renderer
void SubmitModelRecursive(CModel* model)
{
g_Renderer.Submit(model);
const std::vector<CModel::Prop>& props=model->GetProps();
for (uint i=0;i<props.size();i++) {
SubmitModelRecursive(props[i].m_Model);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// RenderModels: iterate through model list and submit all models in viewing frustum to the
@ -249,7 +249,7 @@ void RenderModels()
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
for (uint i=0;i<units.size();++i) {
if (frustum.IsBoxVisible(CVector3D(0,0,0),units[i]->GetModel()->GetBounds())) {
if (frustum.IsBoxVisible(CVector3D(0,0,0),units[i]->GetModel()->GetBounds())) {
SubmitModelRecursive(units[i]->GetModel());
}
}
@ -420,17 +420,12 @@ void ParseArgs(int argc, char* argv[])
}
}
extern "C" char* _getcwd(char*, int);
int main(int argc, char* argv[])
{
const int ERR_MSG_SIZE = 1000;
wchar_t err_msg[ERR_MSG_SIZE];
lib_init();
// set 24 bit (float) FPU precision for faster divides / sqrts
@ -440,8 +435,6 @@ int main(int argc, char* argv[])
detect();
// init SDL
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0)
{
@ -514,12 +507,16 @@ int main(int argc, char* argv[])
debug_warn("SDL_SetGamma failed");
}
new CConfig;
// vfs_mount("gui", "gui", 0);
vfs_mount("", "mods/official/", 0);
//// dir_add_watch("mods\\official", false);
//Handle xx = tex_load("art/textures/skins/structural/null.png");
#ifndef NO_GUI
// GUI uses VFS, so this must come after VFS init.
g_GUI.Initialize();
@ -560,8 +557,6 @@ int main(int argc, char* argv[])
g_EntityTemplateCollection.loadTemplates();
// if no map name specified, load test01.pmp (for convenience during
// development. that means loading no map at all is currently impossible.
// is that a problem?

View File

@ -1,162 +1,162 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: Bound.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
// necessary includes
#include <assert.h>
#include <float.h>
#include "Bound.h"
///////////////////////////////////////////////////////////////////////////////
// operator+=: extend this bound to include given bound
CBound& CBound::operator+=(const CBound& b)
{
for (int i=0;i<3;++i) {
if (b[0][i]<m_Data[0][i])
m_Data[0][i]=b[0][i];
if (b[1][i]>m_Data[1][i])
m_Data[1][i]=b[1][i];
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// operator+=: extend this bound to include given point
CBound& CBound::operator+=(const CVector3D& pt)
{
for (int i=0;i<3;++i) {
if (pt[i]<m_Data[0][i])
m_Data[0][i]=pt[i];
else if (pt[i]>m_Data[1][i])
m_Data[1][i]=pt[i];
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// RayIntersect: intersect ray with this bound; return true
// if ray hits (and store entry and exit times), or false
// otherwise
// note: incoming ray direction must be normalised
bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir,
float& tmin,float& tmax) const
{
float t1,t2;
float tnear,tfar;
if (dir[0]==0) {
if (origin[0]<m_Data[0][0] || origin[0]>m_Data[1][0])
return false;
else {
tnear=(float) FLT_MIN;
tfar=(float) FLT_MAX;
}
} else {
t1=(m_Data[0][0]-origin[0])/dir[0];
t2=(m_Data[1][0]-origin[0])/dir[0];
if (dir[0]<0) {
tnear = t2;
tfar = t1;
} else {
tnear = t1;
tfar = t2;
}
if (tfar<0)
return false;
}
if (dir[1]==0 && (origin[1]<m_Data[0][1] || origin[1]>m_Data[1][1]))
return false;
else {
t1=(m_Data[0][1]-origin[1])/dir[1];
t2=(m_Data[1][1]-origin[1])/dir[1];
if (dir[1]<0) {
if (t2>tnear)
tnear = t2;
if (t1<tfar)
tfar = t1;
} else {
if (t1>tnear)
tnear = t1;
if (t2<tfar)
tfar = t2;
}
if (tnear>tfar || tfar<0)
return false;
}
if (dir[2]==0 && (origin[2]<m_Data[0][2] || origin[2]>m_Data[1][2]))
return false;
else {
t1=(m_Data[0][2]-origin[2])/dir[2];
t2=(m_Data[1][2]-origin[2])/dir[2];
if (dir[2]<0) {
if (t2>tnear)
tnear = t2;
if (t1<tfar)
tfar = t1;
} else {
if (t1>tnear)
tnear = t1;
if (t2<tfar)
tfar = t2;
}
if (tnear>tfar || tfar<0)
return false;
}
tmin=tnear;
tmax=tfar;
return true;
}
///////////////////////////////////////////////////////////////////////////////
// SetEmpty: initialise this bound as empty
void CBound::SetEmpty()
{
m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX);
m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN);
}
///////////////////////////////////////////////////////////////////////////////
// Transform: transform this bound by given matrix; return transformed bound
// in 'result' parameter - slightly modified version of code in Graphic Gems
// (can't remember which one it was, though)
void CBound::Transform(const CMatrix3D& m,CBound& result) const
{
assert(this!=&result);
for (int i=0;i<3;++i) {
// handle translation
result[0][i]=result[1][i]=m(i,3);
// Now find the extreme points by considering the product of the
// min and max with each component of matrix
for(int j=0;j<3;j++) {
float a=m(j,i)*m_Data[0][j];
float b=m(j,i)*m_Data[1][j];
if (a<b) {
result[0][i]+=a;
result[1][i]+=b;
} else {
result[0][i]+=b;
result[1][i]+=a;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Name: Bound.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
// necessary includes
#include <assert.h>
#include <float.h>
#include "Bound.h"
///////////////////////////////////////////////////////////////////////////////
// operator+=: extend this bound to include given bound
CBound& CBound::operator+=(const CBound& b)
{
for (int i=0;i<3;++i) {
if (b[0][i]<m_Data[0][i])
m_Data[0][i]=b[0][i];
if (b[1][i]>m_Data[1][i])
m_Data[1][i]=b[1][i];
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// operator+=: extend this bound to include given point
CBound& CBound::operator+=(const CVector3D& pt)
{
for (int i=0;i<3;++i) {
if (pt[i]<m_Data[0][i])
m_Data[0][i]=pt[i];
else if (pt[i]>m_Data[1][i])
m_Data[1][i]=pt[i];
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// RayIntersect: intersect ray with this bound; return true
// if ray hits (and store entry and exit times), or false
// otherwise
// note: incoming ray direction must be normalised
bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir,
float& tmin,float& tmax) const
{
float t1,t2;
float tnear,tfar;
if (dir[0]==0) {
if (origin[0]<m_Data[0][0] || origin[0]>m_Data[1][0])
return false;
else {
tnear=(float) FLT_MIN;
tfar=(float) FLT_MAX;
}
} else {
t1=(m_Data[0][0]-origin[0])/dir[0];
t2=(m_Data[1][0]-origin[0])/dir[0];
if (dir[0]<0) {
tnear = t2;
tfar = t1;
} else {
tnear = t1;
tfar = t2;
}
if (tfar<0)
return false;
}
if (dir[1]==0 && (origin[1]<m_Data[0][1] || origin[1]>m_Data[1][1]))
return false;
else {
t1=(m_Data[0][1]-origin[1])/dir[1];
t2=(m_Data[1][1]-origin[1])/dir[1];
if (dir[1]<0) {
if (t2>tnear)
tnear = t2;
if (t1<tfar)
tfar = t1;
} else {
if (t1>tnear)
tnear = t1;
if (t2<tfar)
tfar = t2;
}
if (tnear>tfar || tfar<0)
return false;
}
if (dir[2]==0 && (origin[2]<m_Data[0][2] || origin[2]>m_Data[1][2]))
return false;
else {
t1=(m_Data[0][2]-origin[2])/dir[2];
t2=(m_Data[1][2]-origin[2])/dir[2];
if (dir[2]<0) {
if (t2>tnear)
tnear = t2;
if (t1<tfar)
tfar = t1;
} else {
if (t1>tnear)
tnear = t1;
if (t2<tfar)
tfar = t2;
}
if (tnear>tfar || tfar<0)
return false;
}
tmin=tnear;
tmax=tfar;
return true;
}
///////////////////////////////////////////////////////////////////////////////
// SetEmpty: initialise this bound as empty
void CBound::SetEmpty()
{
m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX);
m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN);
}
///////////////////////////////////////////////////////////////////////////////
// Transform: transform this bound by given matrix; return transformed bound
// in 'result' parameter - slightly modified version of code in Graphic Gems
// (can't remember which one it was, though)
void CBound::Transform(const CMatrix3D& m,CBound& result) const
{
assert(this!=&result);
for (int i=0;i<3;++i) {
// handle translation
result[0][i]=result[1][i]=m(i,3);
// Now find the extreme points by considering the product of the
// min and max with each component of matrix
for(int j=0;j<3;j++) {
float a=m(j,i)*m_Data[0][j];
float b=m(j,i)*m_Data[1][j];
if (a<b) {
result[0][i]+=a;
result[1][i]+=b;
} else {
result[0][i]+=b;
result[1][i]+=a;
}
}
}
}

View File

@ -1,55 +1,55 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: Bound.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _BOUND_H
#define _BOUND_H
// necessary includes
#include "Vector3D.h"
#include "Matrix3D.h"
///////////////////////////////////////////////////////////////////////////////
// CBound: basic axis aligned bounding box class
class CBound
{
public:
CBound() {}
CBound(const CVector3D& min,const CVector3D& max) {
m_Data[0]=min; m_Data[1]=max;
}
void Transform(const CMatrix3D& m,CBound& result) const;
CVector3D& operator[](int index) { return m_Data[index]; }
const CVector3D& operator[](int index) const { return m_Data[index]; }
void SetEmpty();
CBound& operator+=(const CBound& b);
CBound& operator+=(const CVector3D& pt);
bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const;
// return the volume of this bounding box
float GetVolume() const {
CVector3D v=m_Data[1]-m_Data[0];
return v.X*v.Y*v.Z;
}
// return the centre of this bounding box
void GetCentre(CVector3D& centre) const {
centre=(m_Data[0]+m_Data[1])*0.5f;
}
private:
CVector3D m_Data[2];
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Name: Bound.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _BOUND_H
#define _BOUND_H
// necessary includes
#include "Vector3D.h"
#include "Matrix3D.h"
///////////////////////////////////////////////////////////////////////////////
// CBound: basic axis aligned bounding box class
class CBound
{
public:
CBound() {}
CBound(const CVector3D& min,const CVector3D& max) {
m_Data[0]=min; m_Data[1]=max;
}
void Transform(const CMatrix3D& m,CBound& result) const;
CVector3D& operator[](int index) { return m_Data[index]; }
const CVector3D& operator[](int index) const { return m_Data[index]; }
void SetEmpty();
CBound& operator+=(const CBound& b);
CBound& operator+=(const CVector3D& pt);
bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const;
// return the volume of this bounding box
float GetVolume() const {
CVector3D v=m_Data[1]-m_Data[0];
return v.X*v.Y*v.Z;
}
// return the centre of this bounding box
void GetCentre(CVector3D& centre) const {
centre=(m_Data[0]+m_Data[1])*0.5f;
}
private:
CVector3D m_Data[2];
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif

View File

@ -1,4 +1,4 @@
#if 0
#if 0
// last modified Thursday, May 08, 2003
#include <time.h>

View File

@ -1,18 +1,18 @@
#ifndef MATH_UTIL_H
#define MATH_UTIL_H
#ifndef PI
#define PI 3.14159265358979323846f
#endif
#define DEGTORAD(a) ((a) * (PI/180.0f))
#define RADTODEG(a) ((a) * (180.0f/PI))
#define SQR(x) ((x) * (x))
#define MAX3(a,b,c) ( MAX (MAX(a,b), c) )
#define ABS(a) ((a > 0) ? (a) : (-a))
#if 0
#ifndef MATH_UTIL_H
#define MATH_UTIL_H
#ifndef PI
#define PI 3.14159265358979323846f
#endif
#define DEGTORAD(a) ((a) * (PI/180.0f))
#define RADTODEG(a) ((a) * (180.0f/PI))
#define SQR(x) ((x) * (x))
#define MAX3(a,b,c) ( MAX (MAX(a,b), c) )
#define ABS(a) ((a > 0) ? (a) : (-a))
#if 0
/*
Math utility functions
by Michael Reiland
@ -213,8 +213,8 @@ namespace MathUtil
_float SignedModulus(const _float &num, const _float &n);
_double SignedModulus(const _double &num, const _double &n);
}
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,123 +1,123 @@
#ifndef __MATRIX3D_H
#define __MATRIX3D_H
#include <math.h>
#include "Vector3D.h"
#include "Vector4D.h"
class CQuaternion;
/////////////////////////////////////////////////////////////////////////
// CMatrix3D: a 4x4 matrix class for common operations in 3D
class CMatrix3D
{
public:
// the matrix data itself - accessible as either longhand names
// or via a flat array
union {
struct {
float _11, _21, _31, _41;
float _12, _22, _32, _42;
float _13, _23, _33, _43;
float _14, _24, _34, _44;
};
float _data[16];
};
public:
// constructors
CMatrix3D();
CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24,
float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44);
// accessors to individual elements of matrix
float& operator()(int col,int row) {
return _data[row*4+col];
}
const float& operator()(int col,int row) const {
return _data[row*4+col];
}
// matrix multiplication
CMatrix3D operator*(const CMatrix3D &matrix) const;
// matrix multiplication/assignment
CMatrix3D& operator*=(const CMatrix3D &matrix);
// matrix scaling
CMatrix3D operator*(float f) const;
// matrix scaling/assignment
CMatrix3D& operator*=(float f);
// matrix addition
CMatrix3D operator+(const CMatrix3D &matrix) const;
// matrix addition/assignment
CMatrix3D& operator+=(const CMatrix3D &matrix);
// set this matrix to the identity matrix
void SetIdentity();
// set this matrix to the zero matrix
void SetZero();
// concatenate arbitrary matrix onto this matrix
void Concatenate(const CMatrix3D& m);
// set this matrix to a rotation matrix for a rotation about X axis of given angle
void SetXRotation(float angle);
// set this matrix to a rotation matrix for a rotation about Y axis of given angle
void SetYRotation(float angle);
// set this matrix to a rotation matrix for a rotation about Z axis of given angle
void SetZRotation(float angle);
// set this matrix to a rotation described by given quaternion
void SetRotation(const CQuaternion& quat);
// concatentate a rotation about the X axis onto this matrix
void RotateX(float angle);
// concatentate a rotation about the Y axis onto this matrix
void RotateY(float angle);
// concatentate a rotation about the Z axis onto this matrix
void RotateZ(float angle);
// concatentate a rotation described by given quaternion
void Rotate(const CQuaternion& quat);
// set this matrix to given translation
void SetTranslation(float x, float y, float z);
void SetTranslation(const CVector3D& vector);
// concatenate given translation onto this matrix
void Translate(float x, float y, float z);
void Translate(const CVector3D& vector);
// set this matrix to the given scaling matrix
void SetScaling(float x_scale, float y_scale, float z_scale);
// concatentate given scaling matrix onto this matrix
void Scale(float x_scale, float y_scale, float z_scale);
// calculate the inverse of this matrix, store in dst
void GetInverse(CMatrix3D& dst) const;
// calculate the transpose of this matrix, store in dst
void GetTranspose(CMatrix3D& dst) const;
// return the translation component of this matrix
CVector3D GetTranslation() const;
// return left vector, derived from rotation
CVector3D GetLeft() const;
// return up vector, derived from rotation
CVector3D GetUp() const;
// return forward vector, derived from rotation
CVector3D GetIn() const;
// transform a 3D vector by this matrix
void Transform(const CVector3D &vector,CVector3D& result) const;
CVector3D Transform(const CVector3D &vector) const;
// transform a 4D vector by this matrix
void Transform(const CVector4D &vector,CVector4D& result) const;
CVector4D Transform(const CVector4D &vector) const;
// rotate a vector by this matrix
void Rotate(const CVector3D& vector,CVector3D& result) const;
CVector3D Rotate(const CVector3D& vector) const;
// rotate a vector by the transpose of this matrix
void RotateTransposed(const CVector3D& vector,CVector3D& result) const;
CVector3D RotateTransposed(const CVector3D& vector) const;
};
#endif
#ifndef __MATRIX3D_H
#define __MATRIX3D_H
#include <math.h>
#include "Vector3D.h"
#include "Vector4D.h"
class CQuaternion;
/////////////////////////////////////////////////////////////////////////
// CMatrix3D: a 4x4 matrix class for common operations in 3D
class CMatrix3D
{
public:
// the matrix data itself - accessible as either longhand names
// or via a flat array
union {
struct {
float _11, _21, _31, _41;
float _12, _22, _32, _42;
float _13, _23, _33, _43;
float _14, _24, _34, _44;
};
float _data[16];
};
public:
// constructors
CMatrix3D();
CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24,
float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44);
// accessors to individual elements of matrix
float& operator()(int col,int row) {
return _data[row*4+col];
}
const float& operator()(int col,int row) const {
return _data[row*4+col];
}
// matrix multiplication
CMatrix3D operator*(const CMatrix3D &matrix) const;
// matrix multiplication/assignment
CMatrix3D& operator*=(const CMatrix3D &matrix);
// matrix scaling
CMatrix3D operator*(float f) const;
// matrix scaling/assignment
CMatrix3D& operator*=(float f);
// matrix addition
CMatrix3D operator+(const CMatrix3D &matrix) const;
// matrix addition/assignment
CMatrix3D& operator+=(const CMatrix3D &matrix);
// set this matrix to the identity matrix
void SetIdentity();
// set this matrix to the zero matrix
void SetZero();
// concatenate arbitrary matrix onto this matrix
void Concatenate(const CMatrix3D& m);
// set this matrix to a rotation matrix for a rotation about X axis of given angle
void SetXRotation(float angle);
// set this matrix to a rotation matrix for a rotation about Y axis of given angle
void SetYRotation(float angle);
// set this matrix to a rotation matrix for a rotation about Z axis of given angle
void SetZRotation(float angle);
// set this matrix to a rotation described by given quaternion
void SetRotation(const CQuaternion& quat);
// concatentate a rotation about the X axis onto this matrix
void RotateX(float angle);
// concatentate a rotation about the Y axis onto this matrix
void RotateY(float angle);
// concatentate a rotation about the Z axis onto this matrix
void RotateZ(float angle);
// concatentate a rotation described by given quaternion
void Rotate(const CQuaternion& quat);
// set this matrix to given translation
void SetTranslation(float x, float y, float z);
void SetTranslation(const CVector3D& vector);
// concatenate given translation onto this matrix
void Translate(float x, float y, float z);
void Translate(const CVector3D& vector);
// set this matrix to the given scaling matrix
void SetScaling(float x_scale, float y_scale, float z_scale);
// concatentate given scaling matrix onto this matrix
void Scale(float x_scale, float y_scale, float z_scale);
// calculate the inverse of this matrix, store in dst
void GetInverse(CMatrix3D& dst) const;
// calculate the transpose of this matrix, store in dst
void GetTranspose(CMatrix3D& dst) const;
// return the translation component of this matrix
CVector3D GetTranslation() const;
// return left vector, derived from rotation
CVector3D GetLeft() const;
// return up vector, derived from rotation
CVector3D GetUp() const;
// return forward vector, derived from rotation
CVector3D GetIn() const;
// transform a 3D vector by this matrix
void Transform(const CVector3D &vector,CVector3D& result) const;
CVector3D Transform(const CVector3D &vector) const;
// transform a 4D vector by this matrix
void Transform(const CVector4D &vector,CVector4D& result) const;
CVector4D Transform(const CVector4D &vector) const;
// rotate a vector by this matrix
void Rotate(const CVector3D& vector,CVector3D& result) const;
CVector3D Rotate(const CVector3D& vector) const;
// rotate a vector by the transpose of this matrix
void RotateTransposed(const CVector3D& vector,CVector3D& result) const;
CVector3D RotateTransposed(const CVector3D& vector) const;
};
#endif

View File

@ -187,16 +187,16 @@ void CQuaternion::Slerp(const CQuaternion& from,const CQuaternion& to, float rat
m_V.Z = scale0 * from.m_V.Z + scale1 * to1[2];
m_W = scale0 * from.m_W + scale1 * to1[3];
}
///////////////////////////////////////////////////////////////////////////////////////////////
// FromAxisAngle: create a quaternion from axis/angle representation of a rotation
void CQuaternion::FromAxisAngle(const CVector3D& axis,float angle)
{
float sinHalfTheta=(float) sin(angle/2);
float cosHalfTheta=(float) cos(angle/2);
m_V.X=axis.X*sinHalfTheta;
m_V.Y=axis.Y*sinHalfTheta;
m_V.Z=axis.Z*sinHalfTheta;
m_W=cosHalfTheta;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// FromAxisAngle: create a quaternion from axis/angle representation of a rotation
void CQuaternion::FromAxisAngle(const CVector3D& axis,float angle)
{
float sinHalfTheta=(float) sin(angle/2);
float cosHalfTheta=(float) cos(angle/2);
m_V.X=axis.X*sinHalfTheta;
m_V.Y=axis.Y*sinHalfTheta;
m_V.Z=axis.Z*sinHalfTheta;
m_W=cosHalfTheta;
}

View File

@ -37,10 +37,10 @@ public:
void ToMatrix(CMatrix3D& result) const;
//sphere interpolation
void Slerp(const CQuaternion& from,const CQuaternion& to, float ratio);
// create a quaternion from axis/angle representation of a rotation
void FromAxisAngle(const CVector3D& axis,float angle);
void Slerp(const CQuaternion& from,const CQuaternion& to, float ratio);
// create a quaternion from axis/angle representation of a rotation
void FromAxisAngle(const CVector3D& axis,float angle);
};

View File

@ -35,10 +35,10 @@ struct CColor
float r, g, b, a;
};
// yuck - MFC already defines CRect/CSize classes ...
#define CRect PS_CRect
#define CSize PS_CSize
// yuck - MFC already defines CRect/CSize classes ...
#define CRect PS_CRect
#define CSize PS_CSize
class CPos;
class CSize;

View File

@ -1,261 +1,261 @@
#include <assert.h>
#include <algorithm>
#include "res/tex.h"
#include "Renderer.h"
#include "TransparencyRenderer.h"
#include "ModelRData.h"
#include "Model.h"
CModelRData::CModelRData(CModel* model)
: m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0), m_Flags(0)
{
assert(model);
// build all data now
Build();
}
CModelRData::~CModelRData()
{
delete[] m_Indices;
delete[] m_Vertices;
delete[] m_Normals;
if (m_VB) {
glGenBuffersARB(1,(GLuint*) &m_VB);
}
}
void CModelRData::Build()
{
// build data
BuildVertices();
BuildIndices();
// force a texture load on models texture
g_Renderer.LoadTexture(m_Model->GetTexture(),GL_CLAMP_TO_EDGE);
// setup model render flags
if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
}
}
void CModelRData::BuildIndices()
{
CModelDef* mdef=m_Model->GetModelDef();
// allocate indices if we haven't got any already
if (!m_Indices) {
m_Indices=new u16[mdef->GetNumFaces()*3];
}
// build indices
u32 indices=0;
SModelFace* faces=mdef->GetFaces();
for (int j=0; j<mdef->GetNumFaces(); j++) {
SModelFace& face=faces[j];
m_Indices[indices++]=face.m_Verts[0];
m_Indices[indices++]=face.m_Verts[1];
m_Indices[indices++]=face.m_Verts[2];
}
}
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
static SColor4ub ConvertColor(const RGBColor& src)
{
SColor4ub result;
result.R=clamp(int(src.X*255),0,255);
result.G=clamp(int(src.Y*255),0,255);
result.B=clamp(int(src.Z*255),0,255);
result.A=0xff;
return result;
}
static CVector3D SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices)
{
CVector3D result(0,0,0),tmp;
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
const CMatrix3D& m=matrices[vertex.m_Blend.m_Bone[i]];
m.Transform(vertex.m_Coords,tmp);
result+=tmp*vertex.m_Blend.m_Weight[i];
}
return result;
}
static CVector3D SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices)
{
CVector3D result(0,0,0),tmp;
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
const CMatrix3D& m=invmatrices[vertex.m_Blend.m_Bone[i]];
m.RotateTransposed(vertex.m_Norm,tmp);
result+=tmp*vertex.m_Blend.m_Weight[i];
}
return result;
}
void CModelRData::BuildVertices()
{
CModelDef* mdef=m_Model->GetModelDef();
// allocate vertices if we haven't got any already
if (!m_Vertices) {
m_Vertices=new SVertex[mdef->GetNumVertices()];
m_Normals=new CVector3D[mdef->GetNumVertices()];
}
// build vertices
u32 numVertices=mdef->GetNumVertices();
SModelVertex* vertices=mdef->GetVertices();
if (m_Model->GetBoneMatrices()) {
// boned model - calculate skinned vertex positions/normals
for (uint j=0; j<numVertices; j++) {
m_Vertices[j].m_Position=SkinPoint(vertices[j],m_Model->GetBoneMatrices());
m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices());
}
} else {
// just copy regular positions, transform normals to world space
const CMatrix3D& trans=m_Model->GetInvTransform();
for (uint j=0; j<numVertices; j++) {
m_Vertices[j].m_Position=vertices[j].m_Coords;
m_Normals[j]=trans.RotateTransposed(vertices[j].m_Norm);
}
}
// now fill in UV and vertex colour data
for (uint j=0; j<numVertices; j++) {
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],m_Vertices[j].m_Color);
}
if (g_Renderer.m_Caps.m_VBO) {
if (!m_VB) {
glGenBuffersARB(1,(GLuint*) &m_VB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdef->GetNumVertices()*sizeof(SVertex),0,mdef->GetNumBones() ? GL_DYNAMIC_DRAW_ARB : GL_STATIC_DRAW_ARB);
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,mdef->GetNumVertices()*sizeof(SVertex),m_Vertices);
}
}
void CModelRData::RenderStreams(u32 streamflags,bool transparentPass)
{
// ignore transparent passes if this is a transparent object
if (!transparentPass && (m_Flags & MODELRDATA_FLAG_TRANSPARENT)) {
return;
}
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
if (streamflags & STREAM_UV0) g_Renderer.SetTexture(0,m_Model->GetTexture());
u8* base;
if (g_Renderer.m_Caps.m_VBO) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
base=0;
} else {
base=(u8*) &m_Vertices[0];
}
// set vertex pointers
u32 stride=sizeof(SVertex);
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position));
if (streamflags & STREAM_COLOR) glColorPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Color));
if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs));
// render the lot
u32 numFaces=mdldef->GetNumFaces();
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
// bump stats
g_Renderer.m_Stats.m_DrawCalls++;
if (transparentPass) {
g_Renderer.m_Stats.m_TransparentTris+=numFaces;
} else {
g_Renderer.m_Stats.m_ModelTris+=numFaces;
}
}
void CModelRData::Update()
{
if (m_UpdateFlags!=0) {
// renderdata changed : rebuild necessary portions
if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) {
BuildVertices();
}
if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) {
BuildIndices();
}
m_UpdateFlags=0;
}
}
typedef std::pair<int,float> IntFloatPair;
static std::vector<IntFloatPair> IndexSorter;
struct SortFacesByDist {
bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) {
return lhs.second>rhs.second ? true : false;
}
};
float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam)
{
float mindist=1.0e30f;
CVector3D osvtx,csvtx;
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
SModelVertex* vtxs=mdldef->GetVertices();
u32 numFaces=mdldef->GetNumFaces();
SModelFace* faces=mdldef->GetFaces();
IndexSorter.reserve(numFaces);
SModelFace* facePtr=faces;
u32 i;
for (i=0;i<numFaces;i++)
{
osvtx=vtxs[facePtr->m_Verts[0]].m_Coords;
osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords;
osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords;
osvtx*=1.0f/3.0f;
csvtx=objToCam.Transform(osvtx);
float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z);
if (distsqrd<mindist) mindist=distsqrd;
IndexSorter.push_back(IntFloatPair(i,distsqrd));
facePtr++;
}
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
// now build index list
u32 indices=0;
for (i=0;i<numFaces;i++) {
SModelFace& face=faces[IndexSorter[i].first];
m_Indices[indices++]=face.m_Verts[0];
m_Indices[indices++]=face.m_Verts[1];
m_Indices[indices++]=face.m_Verts[2];
}
// clear list for next call
IndexSorter.clear();
return mindist;
}
#include <assert.h>
#include <algorithm>
#include "res/tex.h"
#include "Renderer.h"
#include "TransparencyRenderer.h"
#include "ModelRData.h"
#include "Model.h"
CModelRData::CModelRData(CModel* model)
: m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0), m_Flags(0)
{
assert(model);
// build all data now
Build();
}
CModelRData::~CModelRData()
{
delete[] m_Indices;
delete[] m_Vertices;
delete[] m_Normals;
if (m_VB) {
glGenBuffersARB(1,(GLuint*) &m_VB);
}
}
void CModelRData::Build()
{
// build data
BuildVertices();
BuildIndices();
// force a texture load on models texture
g_Renderer.LoadTexture(m_Model->GetTexture(),GL_CLAMP_TO_EDGE);
// setup model render flags
if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
}
}
void CModelRData::BuildIndices()
{
CModelDef* mdef=m_Model->GetModelDef();
// allocate indices if we haven't got any already
if (!m_Indices) {
m_Indices=new u16[mdef->GetNumFaces()*3];
}
// build indices
u32 indices=0;
SModelFace* faces=mdef->GetFaces();
for (int j=0; j<mdef->GetNumFaces(); j++) {
SModelFace& face=faces[j];
m_Indices[indices++]=face.m_Verts[0];
m_Indices[indices++]=face.m_Verts[1];
m_Indices[indices++]=face.m_Verts[2];
}
}
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
static SColor4ub ConvertColor(const RGBColor& src)
{
SColor4ub result;
result.R=clamp(int(src.X*255),0,255);
result.G=clamp(int(src.Y*255),0,255);
result.B=clamp(int(src.Z*255),0,255);
result.A=0xff;
return result;
}
static CVector3D SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices)
{
CVector3D result(0,0,0),tmp;
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
const CMatrix3D& m=matrices[vertex.m_Blend.m_Bone[i]];
m.Transform(vertex.m_Coords,tmp);
result+=tmp*vertex.m_Blend.m_Weight[i];
}
return result;
}
static CVector3D SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices)
{
CVector3D result(0,0,0),tmp;
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
const CMatrix3D& m=invmatrices[vertex.m_Blend.m_Bone[i]];
m.RotateTransposed(vertex.m_Norm,tmp);
result+=tmp*vertex.m_Blend.m_Weight[i];
}
return result;
}
void CModelRData::BuildVertices()
{
CModelDef* mdef=m_Model->GetModelDef();
// allocate vertices if we haven't got any already
if (!m_Vertices) {
m_Vertices=new SVertex[mdef->GetNumVertices()];
m_Normals=new CVector3D[mdef->GetNumVertices()];
}
// build vertices
u32 numVertices=mdef->GetNumVertices();
SModelVertex* vertices=mdef->GetVertices();
if (m_Model->GetBoneMatrices()) {
// boned model - calculate skinned vertex positions/normals
for (uint j=0; j<numVertices; j++) {
m_Vertices[j].m_Position=SkinPoint(vertices[j],m_Model->GetBoneMatrices());
m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices());
}
} else {
// just copy regular positions, transform normals to world space
const CMatrix3D& trans=m_Model->GetInvTransform();
for (uint j=0; j<numVertices; j++) {
m_Vertices[j].m_Position=vertices[j].m_Coords;
m_Normals[j]=trans.RotateTransposed(vertices[j].m_Norm);
}
}
// now fill in UV and vertex colour data
for (uint j=0; j<numVertices; j++) {
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],m_Vertices[j].m_Color);
}
if (g_Renderer.m_Caps.m_VBO) {
if (!m_VB) {
glGenBuffersARB(1,(GLuint*) &m_VB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdef->GetNumVertices()*sizeof(SVertex),0,mdef->GetNumBones() ? GL_DYNAMIC_DRAW_ARB : GL_STATIC_DRAW_ARB);
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,mdef->GetNumVertices()*sizeof(SVertex),m_Vertices);
}
}
void CModelRData::RenderStreams(u32 streamflags,bool transparentPass)
{
// ignore transparent passes if this is a transparent object
if (!transparentPass && (m_Flags & MODELRDATA_FLAG_TRANSPARENT)) {
return;
}
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
if (streamflags & STREAM_UV0) g_Renderer.SetTexture(0,m_Model->GetTexture());
u8* base;
if (g_Renderer.m_Caps.m_VBO) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
base=0;
} else {
base=(u8*) &m_Vertices[0];
}
// set vertex pointers
u32 stride=sizeof(SVertex);
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position));
if (streamflags & STREAM_COLOR) glColorPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Color));
if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs));
// render the lot
u32 numFaces=mdldef->GetNumFaces();
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
// bump stats
g_Renderer.m_Stats.m_DrawCalls++;
if (transparentPass) {
g_Renderer.m_Stats.m_TransparentTris+=numFaces;
} else {
g_Renderer.m_Stats.m_ModelTris+=numFaces;
}
}
void CModelRData::Update()
{
if (m_UpdateFlags!=0) {
// renderdata changed : rebuild necessary portions
if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) {
BuildVertices();
}
if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) {
BuildIndices();
}
m_UpdateFlags=0;
}
}
typedef std::pair<int,float> IntFloatPair;
static std::vector<IntFloatPair> IndexSorter;
struct SortFacesByDist {
bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) {
return lhs.second>rhs.second ? true : false;
}
};
float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam)
{
float mindist=1.0e30f;
CVector3D osvtx,csvtx;
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
SModelVertex* vtxs=mdldef->GetVertices();
u32 numFaces=mdldef->GetNumFaces();
SModelFace* faces=mdldef->GetFaces();
IndexSorter.reserve(numFaces);
SModelFace* facePtr=faces;
u32 i;
for (i=0;i<numFaces;i++)
{
osvtx=vtxs[facePtr->m_Verts[0]].m_Coords;
osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords;
osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords;
osvtx*=1.0f/3.0f;
csvtx=objToCam.Transform(osvtx);
float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z);
if (distsqrd<mindist) mindist=distsqrd;
IndexSorter.push_back(IntFloatPair(i,distsqrd));
facePtr++;
}
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
// now build index list
u32 indices=0;
for (i=0;i<numFaces;i++) {
SModelFace& face=faces[IndexSorter[i].first];
m_Indices[indices++]=face.m_Verts[0];
m_Indices[indices++]=face.m_Verts[1];
m_Indices[indices++]=face.m_Verts[2];
}
// clear list for next call
IndexSorter.clear();
return mindist;
}

View File

@ -4,10 +4,10 @@
#include <vector>
#include "res/res.h"
#include "Vector3D.h"
#include "Color.h"
#include "Color.h"
#include "RenderableObject.h"
#define MODELRDATA_FLAG_TRANSPARENT (1<<0)
#define MODELRDATA_FLAG_TRANSPARENT (1<<0)
class CModel;
@ -19,9 +19,9 @@ public:
void Update();
void RenderStreams(u32 streamflags,bool transparentPass=false);
// return render flags for this model
u32 GetFlags() const { return m_Flags; }
// return render flags for this model
u32 GetFlags() const { return m_Flags; }
// sort indices of this object from back to front according to given
// object to camera space transform; return sqrd distance to centre of nearest triangle
@ -53,8 +53,8 @@ private:
// transformed vertex normals - required for recalculating lighting on skinned models
CVector3D* m_Normals;
// model render indices
u16* m_Indices;
// model render flags
u16* m_Indices;
// model render flags
u32 m_Flags;
};

View File

@ -1,385 +1,385 @@
#include "pbuffer.h"
#ifdef _WIN32
#include <windows.h>
#include <gl/gl.h>
#include <gl/glext.h>
#include <gl/wglext.h>
static HDC lastDC;
static HGLRC lastGLRC;
static bool GotExts=false;
static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB=0;
static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB=0;
static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB=0;
static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB=0;
static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB=0;
static PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB=0;
static PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB=0;
static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB=0;
class PBuffer
{
public:
enum { MAX_ATTRIBS = 32 };
enum { MAX_PFORMATS = 256 };
PBuffer();
~PBuffer();
void makeCurrent();
bool init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
void close();
// return width,height of this pbuffer
int GetWidth() const { return _width; }
int GetHeight() const { return _height; }
private:
HDC _hDC;
HGLRC _hGLRC;
HPBUFFERARB _hBuffer;
int _width;
int _height;
int _doublebuffer;
int _colorbits;
int _depthbits;
int _stencilbits;
int _rendertextureformat;
int _rendertexturetarget;
int _havemipmaps;
};
static PBuffer g_PBuffer;
PBuffer::PBuffer()
: _width(0), _height(0), _hDC(0), _hGLRC(0), _hBuffer(0)
{
}
PBuffer::~PBuffer()
{
close();
}
void PBuffer::close()
{
if (_hBuffer) {
wglDeleteContext(_hGLRC);
wglReleasePbufferDCARB(_hBuffer,_hDC);
wglDestroyPbufferARB(_hBuffer);
_hBuffer=0;
}
}
static void GetExts()
{
wglCreatePbufferARB=(PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
wglGetPbufferDCARB=(PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
wglReleasePbufferDCARB=(PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
wglDestroyPbufferARB=(PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
wglQueryPbufferARB=(PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
wglGetPixelFormatAttribivARB=(PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB");
wglGetPixelFormatAttribfvARB=(PFNWGLGETPIXELFORMATATTRIBFVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribfvARB");
wglChoosePixelFormatARB=(PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
GotExts=true;
}
// This function actually does the creation of the p-buffer.
// It can only be called once a window has already been created.
bool PBuffer::init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat,int rendertexturetarget,int havemipmaps)
{
if (!GotExts) {
GetExts();
}
// store requested parameters
_width=width;
_height=height;
_doublebuffer=doublebuffer;
_colorbits=colorbits;
_depthbits=depthbits;
_stencilbits=stencilbits;
_rendertextureformat=rendertextureformat;
_rendertexturetarget=rendertexturetarget;
_havemipmaps=havemipmaps;
HDC hdc = wglGetCurrentDC();
HGLRC hglrc = wglGetCurrentContext();
// build attributes
int iattributes[2*PBuffer::MAX_ATTRIBS];
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
float fattributes[2*PBuffer::MAX_ATTRIBS];
memset(fattributes,0,sizeof(float)*2*MAX_ATTRIBS);
int niattribs=0;
// pixel format must be "p-buffer capable" ..
iattributes[2*niattribs] = WGL_DRAW_TO_PBUFFER_ARB;
iattributes[2*niattribs+1] = 1;
niattribs++;
// .. use RGBA rather than index mode ..
iattributes[2*niattribs] = WGL_PIXEL_TYPE_ARB;
iattributes[2*niattribs+1] = WGL_TYPE_RGBA_ARB;
niattribs++;
// .. setup double buffer ..
iattributes[2*niattribs] = WGL_DOUBLE_BUFFER_ARB;
iattributes[2*niattribs+1] = doublebuffer;
niattribs++;
// .. setup color and alpha bits ..
iattributes[2*niattribs] = WGL_COLOR_BITS_ARB;
iattributes[2*niattribs+1] = colorbits;
niattribs++;
iattributes[2*niattribs] = WGL_ALPHA_BITS_ARB;
iattributes[2*niattribs+1] = (colorbits==32) ? 8 : 0;
niattribs++;
// .. setup depth/stencil buffer ..
iattributes[2*niattribs] = WGL_DEPTH_BITS_ARB;
iattributes[2*niattribs+1] = depthbits;
niattribs++;
iattributes[2*niattribs] = WGL_STENCIL_BITS_ARB;
iattributes[2*niattribs+1] = stencilbits;
niattribs++;
// .. must support opengl (doh ..)
iattributes[2*niattribs] = WGL_SUPPORT_OPENGL_ARB;
iattributes[2*niattribs+1] = 1;
niattribs++;
if (rendertextureformat!=0) {
// pbuffer meant to be bound as an RGBA texture, so need a color plane
iattributes[2*niattribs] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
iattributes[2*niattribs+1] = 1;
niattribs++;
}
int pformat[MAX_PFORMATS];
unsigned int nformats;
if (!wglChoosePixelFormatARB(hdc,iattributes,fattributes,MAX_PFORMATS,pformat,&nformats)) {
// LOG << "PBuffer creation failed: wglChoosePixelFormatARB() returned 0\n";
return false;
}
if (nformats<=0) {
// LOG << "PBuffer creation failed: couldn't find a suitable pixel format\n";
return false;
}
// Create the p-buffer.
niattribs=0;
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
if (rendertextureformat!=0) {
// set format
iattributes[2*niattribs]=WGL_TEXTURE_FORMAT_ARB;
iattributes[2*niattribs+1]=rendertextureformat;
niattribs++;
// set target
iattributes[2*niattribs]=WGL_TEXTURE_TARGET_ARB;
iattributes[2*niattribs+1]=rendertexturetarget;
niattribs++;
// mipmaps ..
iattributes[2*niattribs] = WGL_MIPMAP_TEXTURE_ARB;
iattributes[2*niattribs+1] = havemipmaps;
niattribs++;
// ask to allocate the largest pbuffer it can, if it is
// unable to allocate for the width and height
iattributes[2*niattribs]=WGL_PBUFFER_LARGEST_ARB;
iattributes[2*niattribs+1]=0;
niattribs++;
}
_hBuffer=wglCreatePbufferARB(hdc,pformat[0],_width,_height,iattributes );
if (!_hBuffer) {
// LOG << "PBuffer creation failed: wglCreatePbufferARB returned 0\n";
return false;
}
// Get the device context.
_hDC=wglGetPbufferDCARB(_hBuffer);
if (!_hDC) {
// LOG << "PBuffer creation failed: wglGetPbufferDCARB returned 0\n";
return false;
}
// Create a gl context for the p-buffer.
_hGLRC=wglCreateContext(_hDC);
if (!_hGLRC) {
// LOG << "PBuffer creation failed: wglCreateContext returned 0\n";
return false;
}
if(!wglShareLists(hglrc,_hGLRC)) {
// LOG << "PBuffer creation failed: wglShareLists returned 0\n";
return false;
}
// Determine the actual width and height we were able to create.
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_WIDTH_ARB,&_width);
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_HEIGHT_ARB,&_height);
// success ..
// LOG << "PBuffer created: " << _width << " x " << _height << "\n";
// log out attributes of pbuffer's pixel format
int values[MAX_ATTRIBS];
int iatr[MAX_ATTRIBS] = { WGL_PIXEL_TYPE_ARB, WGL_COLOR_BITS_ARB,
WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB,
WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_ACCUM_BITS_ARB,
WGL_DOUBLE_BUFFER_ARB, WGL_SUPPORT_OPENGL_ARB, WGL_ACCELERATION_ARB,
WGL_BIND_TO_TEXTURE_RGBA_ARB, WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB
};
if (wglGetPixelFormatAttribivARB(hdc,pformat[0],0,15,iatr,values)) {
// LOG << "\nPBuffer pixelformat (" << pformat[0] << "):\n";
if (values[0]==WGL_TYPE_COLORINDEX_ARB) {
// LOG << " pixel type = WGL_TYPE_COLORINDEX_ARB\n";
} else if (values[0]==WGL_TYPE_RGBA_ARB) {
// LOG << " pixel type = WGL_TYPE_RGBA_ARB\n";
} else {
// LOG << " pixel type = UNKNOWN\n";
}
// LOG << " color bits = " << values[1] << "\n";
// LOG << " red = " << values[2] << "\n";
// LOG << " green = " << values[3] << "\n";
// LOG << " blue = " << values[4] << "\n";
// LOG << " alpha = " << values[5] << "\n";
// LOG << " depth bits = " << values[6] << "\n";
// LOG << " stencil bits = " << values[7] << "\n";
// LOG << " accum bits = " << values[8] << "\n";
// LOG << " doublebuffer = " << values[9] << "\n";
// LOG << " support opengl = " << values[10] << "\n";
if (values[11]==WGL_FULL_ACCELERATION_ARB) {
// LOG << " acceleration = WGL_FULL_ACCELERATION_ARB\n";
} else if (values[11]== WGL_GENERIC_ACCELERATION_ARB) {
// LOG << " acceleration = WGL_GENERIC_ACCELERATION_ARB\n";
} else {
// LOG << " acceleration = UNKNOWN\n";
}
// LOG << " bind to texture = " << values[12] << "\n\n";
// LOG << " multisample = " << values[13] << "\n";
if (values[13]) {
// LOG << " sample buffers = " << values[14] << "\n\n";
}
}
return true;
}
void PBuffer::makeCurrent()
{
lastGLRC=wglGetCurrentContext();
lastDC=wglGetCurrentDC();
// check first for lost pbuffer
int lost;
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_LOST_ARB,&lost);
if (lost) {
// ack .. have to recreate it ..
close();
if (!init(_width,_height,_doublebuffer,_colorbits,_depthbits,_stencilbits,
_rendertextureformat,_rendertexturetarget,_havemipmaps)) {
// oops .. couldn't rebuild it ..
// LOG << "PBuffer lost; couldn't rebuild";
return;
}
}
if (!wglMakeCurrent(_hDC,_hGLRC)) {
// LOG << "PBuffer::makeCurrent - failed to make pbuffer current";
}
}
void PBufferMakeCurrent()
{
g_PBuffer.makeCurrent();
}
bool isWGLExtensionSupported(const char *extension)
{
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
if (!wglGetExtensionsStringARB) {
// no function to retrieve WGL extension : maybe worth looking in the regular extensions ..
return false;
}
static const char *extensions = NULL;
const char *start;
char *where, *terminator;
where = (char *) strchr(extension, ' ');
if ((where) || (*extension == '\0'))
return false;
if (!extensions)
extensions = (const char *) wglGetExtensionsStringARB(wglGetCurrentDC());
start = extensions;
for (;;) {
where = (char *) strstr((const char *) start, extension);
if (!where)
break;
terminator = where + strlen(extension);
if (where == start || *(where - 1) == ' ') {
if (*terminator == ' ' || *terminator == '\0') {
return true;
}
}
start = terminator;
}
return false;
}
void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat,int rendertexturetarget,int havemipmaps)
{
g_PBuffer.init(width,height,doublebuffer,colorbits,depthbits,stencilbits,
rendertextureformat,rendertexturetarget,havemipmaps);
}
void PBufferClose()
{
g_PBuffer.close();
}
void PBufferMakeUncurrent()
{
wglMakeCurrent(lastDC,lastGLRC);
}
int PBufferWidth()
{
return g_PBuffer.GetWidth();
}
#endif
bool PBufferQuery()
{
if (!isWGLExtensionSupported("WGL_ARB_pbuffer")) return false;
if (!isWGLExtensionSupported("WGL_ARB_pixel_format")) return false;
return true;
}
#include "pbuffer.h"
#ifdef _WIN32
#include <windows.h>
#include <gl/gl.h>
#include <gl/glext.h>
#include <gl/wglext.h>
static HDC lastDC;
static HGLRC lastGLRC;
static bool GotExts=false;
static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB=0;
static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB=0;
static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB=0;
static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB=0;
static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB=0;
static PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB=0;
static PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB=0;
static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB=0;
class PBuffer
{
public:
enum { MAX_ATTRIBS = 32 };
enum { MAX_PFORMATS = 256 };
PBuffer();
~PBuffer();
void makeCurrent();
bool init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
void close();
// return width,height of this pbuffer
int GetWidth() const { return _width; }
int GetHeight() const { return _height; }
private:
HDC _hDC;
HGLRC _hGLRC;
HPBUFFERARB _hBuffer;
int _width;
int _height;
int _doublebuffer;
int _colorbits;
int _depthbits;
int _stencilbits;
int _rendertextureformat;
int _rendertexturetarget;
int _havemipmaps;
};
static PBuffer g_PBuffer;
PBuffer::PBuffer()
: _width(0), _height(0), _hDC(0), _hGLRC(0), _hBuffer(0)
{
}
PBuffer::~PBuffer()
{
close();
}
void PBuffer::close()
{
if (_hBuffer) {
wglDeleteContext(_hGLRC);
wglReleasePbufferDCARB(_hBuffer,_hDC);
wglDestroyPbufferARB(_hBuffer);
_hBuffer=0;
}
}
static void GetExts()
{
wglCreatePbufferARB=(PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
wglGetPbufferDCARB=(PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
wglReleasePbufferDCARB=(PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
wglDestroyPbufferARB=(PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
wglQueryPbufferARB=(PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
wglGetPixelFormatAttribivARB=(PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB");
wglGetPixelFormatAttribfvARB=(PFNWGLGETPIXELFORMATATTRIBFVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribfvARB");
wglChoosePixelFormatARB=(PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
GotExts=true;
}
// This function actually does the creation of the p-buffer.
// It can only be called once a window has already been created.
bool PBuffer::init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat,int rendertexturetarget,int havemipmaps)
{
if (!GotExts) {
GetExts();
}
// store requested parameters
_width=width;
_height=height;
_doublebuffer=doublebuffer;
_colorbits=colorbits;
_depthbits=depthbits;
_stencilbits=stencilbits;
_rendertextureformat=rendertextureformat;
_rendertexturetarget=rendertexturetarget;
_havemipmaps=havemipmaps;
HDC hdc = wglGetCurrentDC();
HGLRC hglrc = wglGetCurrentContext();
// build attributes
int iattributes[2*PBuffer::MAX_ATTRIBS];
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
float fattributes[2*PBuffer::MAX_ATTRIBS];
memset(fattributes,0,sizeof(float)*2*MAX_ATTRIBS);
int niattribs=0;
// pixel format must be "p-buffer capable" ..
iattributes[2*niattribs] = WGL_DRAW_TO_PBUFFER_ARB;
iattributes[2*niattribs+1] = 1;
niattribs++;
// .. use RGBA rather than index mode ..
iattributes[2*niattribs] = WGL_PIXEL_TYPE_ARB;
iattributes[2*niattribs+1] = WGL_TYPE_RGBA_ARB;
niattribs++;
// .. setup double buffer ..
iattributes[2*niattribs] = WGL_DOUBLE_BUFFER_ARB;
iattributes[2*niattribs+1] = doublebuffer;
niattribs++;
// .. setup color and alpha bits ..
iattributes[2*niattribs] = WGL_COLOR_BITS_ARB;
iattributes[2*niattribs+1] = colorbits;
niattribs++;
iattributes[2*niattribs] = WGL_ALPHA_BITS_ARB;
iattributes[2*niattribs+1] = (colorbits==32) ? 8 : 0;
niattribs++;
// .. setup depth/stencil buffer ..
iattributes[2*niattribs] = WGL_DEPTH_BITS_ARB;
iattributes[2*niattribs+1] = depthbits;
niattribs++;
iattributes[2*niattribs] = WGL_STENCIL_BITS_ARB;
iattributes[2*niattribs+1] = stencilbits;
niattribs++;
// .. must support opengl (doh ..)
iattributes[2*niattribs] = WGL_SUPPORT_OPENGL_ARB;
iattributes[2*niattribs+1] = 1;
niattribs++;
if (rendertextureformat!=0) {
// pbuffer meant to be bound as an RGBA texture, so need a color plane
iattributes[2*niattribs] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
iattributes[2*niattribs+1] = 1;
niattribs++;
}
int pformat[MAX_PFORMATS];
unsigned int nformats;
if (!wglChoosePixelFormatARB(hdc,iattributes,fattributes,MAX_PFORMATS,pformat,&nformats)) {
// LOG << "PBuffer creation failed: wglChoosePixelFormatARB() returned 0\n";
return false;
}
if (nformats<=0) {
// LOG << "PBuffer creation failed: couldn't find a suitable pixel format\n";
return false;
}
// Create the p-buffer.
niattribs=0;
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
if (rendertextureformat!=0) {
// set format
iattributes[2*niattribs]=WGL_TEXTURE_FORMAT_ARB;
iattributes[2*niattribs+1]=rendertextureformat;
niattribs++;
// set target
iattributes[2*niattribs]=WGL_TEXTURE_TARGET_ARB;
iattributes[2*niattribs+1]=rendertexturetarget;
niattribs++;
// mipmaps ..
iattributes[2*niattribs] = WGL_MIPMAP_TEXTURE_ARB;
iattributes[2*niattribs+1] = havemipmaps;
niattribs++;
// ask to allocate the largest pbuffer it can, if it is
// unable to allocate for the width and height
iattributes[2*niattribs]=WGL_PBUFFER_LARGEST_ARB;
iattributes[2*niattribs+1]=0;
niattribs++;
}
_hBuffer=wglCreatePbufferARB(hdc,pformat[0],_width,_height,iattributes );
if (!_hBuffer) {
// LOG << "PBuffer creation failed: wglCreatePbufferARB returned 0\n";
return false;
}
// Get the device context.
_hDC=wglGetPbufferDCARB(_hBuffer);
if (!_hDC) {
// LOG << "PBuffer creation failed: wglGetPbufferDCARB returned 0\n";
return false;
}
// Create a gl context for the p-buffer.
_hGLRC=wglCreateContext(_hDC);
if (!_hGLRC) {
// LOG << "PBuffer creation failed: wglCreateContext returned 0\n";
return false;
}
if(!wglShareLists(hglrc,_hGLRC)) {
// LOG << "PBuffer creation failed: wglShareLists returned 0\n";
return false;
}
// Determine the actual width and height we were able to create.
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_WIDTH_ARB,&_width);
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_HEIGHT_ARB,&_height);
// success ..
// LOG << "PBuffer created: " << _width << " x " << _height << "\n";
// log out attributes of pbuffer's pixel format
int values[MAX_ATTRIBS];
int iatr[MAX_ATTRIBS] = { WGL_PIXEL_TYPE_ARB, WGL_COLOR_BITS_ARB,
WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB,
WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_ACCUM_BITS_ARB,
WGL_DOUBLE_BUFFER_ARB, WGL_SUPPORT_OPENGL_ARB, WGL_ACCELERATION_ARB,
WGL_BIND_TO_TEXTURE_RGBA_ARB, WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB
};
if (wglGetPixelFormatAttribivARB(hdc,pformat[0],0,15,iatr,values)) {
// LOG << "\nPBuffer pixelformat (" << pformat[0] << "):\n";
if (values[0]==WGL_TYPE_COLORINDEX_ARB) {
// LOG << " pixel type = WGL_TYPE_COLORINDEX_ARB\n";
} else if (values[0]==WGL_TYPE_RGBA_ARB) {
// LOG << " pixel type = WGL_TYPE_RGBA_ARB\n";
} else {
// LOG << " pixel type = UNKNOWN\n";
}
// LOG << " color bits = " << values[1] << "\n";
// LOG << " red = " << values[2] << "\n";
// LOG << " green = " << values[3] << "\n";
// LOG << " blue = " << values[4] << "\n";
// LOG << " alpha = " << values[5] << "\n";
// LOG << " depth bits = " << values[6] << "\n";
// LOG << " stencil bits = " << values[7] << "\n";
// LOG << " accum bits = " << values[8] << "\n";
// LOG << " doublebuffer = " << values[9] << "\n";
// LOG << " support opengl = " << values[10] << "\n";
if (values[11]==WGL_FULL_ACCELERATION_ARB) {
// LOG << " acceleration = WGL_FULL_ACCELERATION_ARB\n";
} else if (values[11]== WGL_GENERIC_ACCELERATION_ARB) {
// LOG << " acceleration = WGL_GENERIC_ACCELERATION_ARB\n";
} else {
// LOG << " acceleration = UNKNOWN\n";
}
// LOG << " bind to texture = " << values[12] << "\n\n";
// LOG << " multisample = " << values[13] << "\n";
if (values[13]) {
// LOG << " sample buffers = " << values[14] << "\n\n";
}
}
return true;
}
void PBuffer::makeCurrent()
{
lastGLRC=wglGetCurrentContext();
lastDC=wglGetCurrentDC();
// check first for lost pbuffer
int lost;
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_LOST_ARB,&lost);
if (lost) {
// ack .. have to recreate it ..
close();
if (!init(_width,_height,_doublebuffer,_colorbits,_depthbits,_stencilbits,
_rendertextureformat,_rendertexturetarget,_havemipmaps)) {
// oops .. couldn't rebuild it ..
// LOG << "PBuffer lost; couldn't rebuild";
return;
}
}
if (!wglMakeCurrent(_hDC,_hGLRC)) {
// LOG << "PBuffer::makeCurrent - failed to make pbuffer current";
}
}
void PBufferMakeCurrent()
{
g_PBuffer.makeCurrent();
}
bool isWGLExtensionSupported(const char *extension)
{
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
if (!wglGetExtensionsStringARB) {
// no function to retrieve WGL extension : maybe worth looking in the regular extensions ..
return false;
}
static const char *extensions = NULL;
const char *start;
char *where, *terminator;
where = (char *) strchr(extension, ' ');
if ((where) || (*extension == '\0'))
return false;
if (!extensions)
extensions = (const char *) wglGetExtensionsStringARB(wglGetCurrentDC());
start = extensions;
for (;;) {
where = (char *) strstr((const char *) start, extension);
if (!where)
break;
terminator = where + strlen(extension);
if (where == start || *(where - 1) == ' ') {
if (*terminator == ' ' || *terminator == '\0') {
return true;
}
}
start = terminator;
}
return false;
}
void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat,int rendertexturetarget,int havemipmaps)
{
g_PBuffer.init(width,height,doublebuffer,colorbits,depthbits,stencilbits,
rendertextureformat,rendertexturetarget,havemipmaps);
}
void PBufferClose()
{
g_PBuffer.close();
}
void PBufferMakeUncurrent()
{
wglMakeCurrent(lastDC,lastGLRC);
}
int PBufferWidth()
{
return g_PBuffer.GetWidth();
}
#endif
bool PBufferQuery()
{
if (!isWGLExtensionSupported("WGL_ARB_pbuffer")) return false;
if (!isWGLExtensionSupported("WGL_ARB_pixel_format")) return false;
return true;
}

View File

@ -1,12 +1,12 @@
#ifndef _PBUFFER_H
#define _PBUFFER_H
extern void PBufferMakeCurrent();
extern void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
extern void PBufferClose();
extern void PBufferMakeUncurrent();
extern int PBufferWidth();
#endif
#ifndef _PBUFFER_H
#define _PBUFFER_H
extern void PBufferMakeCurrent();
extern void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
extern void PBufferClose();
extern void PBufferMakeUncurrent();
extern int PBufferWidth();
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,312 +1,312 @@
///////////////////////////////////////////////////////////////////////////////
//
// Name: Renderer.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
// Description: OpenGL renderer class; a higher level interface
// on top of OpenGL to handle rendering the basic visual games
// types - terrain, models, sprites, particles etc
//
///////////////////////////////////////////////////////////////////////////////
#ifndef RENDERER_H
#define RENDERER_H
#include <vector>
#include "res/res.h"
#include "ogl.h"
#include "Camera.h"
#include "Frustum.h"
#include "PatchRData.h"
#include "ModelRData.h"
#include "SHCoeffs.h"
#include "Terrain.h"
#include "Singleton.h"
// necessary declarations
class CCamera;
class CPatch;
class CSprite;
class CParticleSys;
class COverlay;
class CMaterial;
class CLightEnv;
class CTexture;
class CTerrain;
// rendering modes
enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES };
// stream flags
#define STREAM_POS 0x01
#define STREAM_NORMAL 0x02
#define STREAM_COLOR 0x04
#define STREAM_UV0 0x08
#define STREAM_UV1 0x10
#define STREAM_UV2 0x20
#define STREAM_UV3 0x40
#define STREAM_POSTOUV0 0x80
//////////////////////////////////////////////////////////////////////////////////////////
// SVertex3D: simple 3D vertex declaration
struct SVertex3D
{
float m_Position[3];
float m_TexCoords[2];
unsigned int m_Color;
};
//////////////////////////////////////////////////////////////////////////////////////////
// SVertex2D: simple 2D vertex declaration
struct SVertex2D
{
float m_Position[2];
float m_TexCoords[2];
unsigned int m_Color;
};
// access to sole renderer object
#define g_Renderer CRenderer::GetSingleton()
///////////////////////////////////////////////////////////////////////////////////////////
// CRenderer: base renderer class - primary interface to the rendering engine
class CRenderer : public Singleton<CRenderer>
{
public:
// various enumerations and renderer related constants
enum { NumAlphaMaps=14 };
enum { MaxTextureUnits=16 };
enum Option {
OPT_NOVBO,
OPT_NOPBUFFER,
OPT_SHADOWS,
OPT_SHADOWCOLOR
};
// stats class - per frame counts of number of draw calls, poly counts etc
struct Stats {
// set all stats to zero
void Reset() { memset(this,0,sizeof(*this)); }
// add given stats to this stats
Stats& operator+=(const Stats& rhs) {
m_Counter++;
m_DrawCalls+=rhs.m_DrawCalls;
m_TerrainTris+=rhs.m_TerrainTris;
m_ModelTris+=rhs.m_ModelTris;
m_TransparentTris+=rhs.m_TransparentTris;
m_BlendSplats+=rhs.m_BlendSplats;
return *this;
}
// count of the number of stats added together
u32 m_Counter;
// number of draw calls per frame - total DrawElements + Begin/End immediate mode loops
u32 m_DrawCalls;
// number of terrain triangles drawn
u32 m_TerrainTris;
// number of (non-transparent) model triangles drawn
u32 m_ModelTris;
// number of transparent model triangles drawn
u32 m_TransparentTris;
// number of splat passes for alphamapping
u32 m_BlendSplats;
};
public:
// constructor, destructor
CRenderer();
~CRenderer();
// open up the renderer: performs any necessary initialisation
bool Open(int width,int height,int depth);
// shutdown the renderer: performs any necessary cleanup
void Close();
// resize renderer view
void Resize(int width,int height);
// set/get boolean renderer option
void SetOptionBool(enum Option opt,bool value);
bool GetOptionBool(enum Option opt) const;
// set/get color renderer option
void SetOptionColor(enum Option opt,const RGBColor& value);
const RGBColor& GetOptionColor(enum Option opt) const;
// return view width
int GetWidth() const { return m_Width; }
// return view height
int GetHeight() const { return m_Height; }
// return view aspect ratio
float GetAspect() const { return float(m_Width)/float(m_Height); }
// signal frame start
void BeginFrame();
// force rendering of any batched objects
void FlushFrame();
// signal frame end : implicitly flushes batched objects
void EndFrame();
// set color used to clear screen in BeginFrame()
void SetClearColor(u32 color);
// return current frame counter
int GetFrameCounter() const { return m_FrameCounter; }
// set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices
void SetCamera(CCamera& camera);
// submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond
// the call to frame end, as must the object itself
void Submit(CPatch* patch);
void Submit(CModel* model);
void Submit(CSprite* sprite);
void Submit(CParticleSys* psys);
void Submit(COverlay* overlay);
// basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in
// editor tools (eg for highlighting specific terrain patches)
// note:
// * all 3D vertices specified in world space
// * primitive operations rendered immediatedly, never batched
// * primitives rendered in current material (set via SetMaterial)
void RenderLine(const SVertex2D* vertices);
void RenderLineLoop(int len,const SVertex2D* vertices);
void RenderTri(const SVertex2D* vertices);
void RenderQuad(const SVertex2D* vertices);
void RenderLine(const SVertex3D* vertices);
void RenderLineLoop(int len,const SVertex3D* vertices);
void RenderTri(const SVertex3D* vertices);
void RenderQuad(const SVertex3D* vertices);
// set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer,
// so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering)
void SetLightEnv(CLightEnv* lightenv) {
m_LightEnv=lightenv;
}
// set the mode to render subsequent terrain patches
void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode=mode; }
// get the mode to render subsequent terrain patches
ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; }
// set the mode to render subsequent models
void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode=mode; }
// get the mode to render subsequent models
ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; }
// try and load the given texture
bool LoadTexture(CTexture* texture,u32 wrapflags);
// set the given unit to reference the given texture; pass a null texture to disable texturing on any unit
void SetTexture(int unit,CTexture* texture);
// BindTexture: bind a GL texture object to given unit
void BindTexture(int unit,GLuint tex);
// query transparency of given texture
bool IsTextureTransparent(CTexture* texture);
// load the default set of alphamaps; return false if any alphamap fails to load, true otherwise
bool LoadAlphaMaps(const char* fnames[]);
// return stats accumulated for current frame
const Stats& GetStats() { return m_Stats; }
protected:
friend class CPatchRData;
friend class CModelRData;
friend class CTransparencyRenderer;
// recurse down given model building renderdata for it and all it's children
void UpdateModelDataRecursive(CModel* model);
// update renderdata of everything submitted
void UpdateSubmittedObjectData();
// patch rendering stuff
void RenderPatchSubmissions();
void RenderPatches();
// model rendering stuff
void BuildTransparentPasses(CModel* model);
void RenderModelSubmissions();
void RenderModelsRecursive(CModel* model,u32 streamflags);
void RenderModelsStreams(u32 streamflags);
void RenderModels();
// shadow rendering stuff
void CreateShadowMap();
void RenderShadowMap();
void ApplyShadowMap();
void CRenderer::BuildTransformation(const CVector3D& pos,const CVector3D& right,const CVector3D& up,
const CVector3D& dir,CMatrix3D& result);
void ConstructLightTransform(const CVector3D& pos,const CVector3D& lightdir,CMatrix3D& result);
void CalcShadowMatrices();
void CalcShadowBounds(CBound& bounds);
// RENDERER DATA:
// view width
int m_Width;
// view height
int m_Height;
// view depth (bpp)
int m_Depth;
// frame counter
int m_FrameCounter;
// current terrain rendering mode
ERenderMode m_TerrainRenderMode;
// current model rendering mode
ERenderMode m_ModelRenderMode;
// current view camera
CCamera m_Camera;
// color used to clear screen in BeginFrame
float m_ClearColor[4];
// submitted object lists for batching
std::vector<CPatch*> m_TerrainPatches;
std::vector<CModel*> m_Models;
std::vector<CSprite*> m_Sprites;
std::vector<CParticleSys*> m_ParticleSyses;
std::vector<COverlay*> m_Overlays;
// current lighting setup
CLightEnv* m_LightEnv;
// current spherical harmonic coefficients (for unit lighting), derived from lightenv
CSHCoeffs m_SHCoeffsUnits;
// current spherical harmonic coefficients (for terrain lighting), derived from lightenv
CSHCoeffs m_SHCoeffsTerrain;
// handle of composite alpha map (all the alpha maps packed into one texture)
u32 m_CompositeAlphaMap;
// handle of shadow map
u32 m_ShadowMap;
// size of each side of shadow map
u32 m_ShadowMapSize;
// per-frame flag: has the shadow map been rendered this frame?
bool m_ShadowRendered;
// projection matrix of shadow casting light
CMatrix3D m_LightProjection;
// transformation matrix of shadow casting light
CMatrix3D m_LightTransform;
// coordinates of each (untransformed) alpha map within the packed texture
struct {
float u0,u1,v0,v1;
} m_AlphaMapCoords[NumAlphaMaps];
// card capabilities
struct Caps {
bool m_VBO;
bool m_TextureBorderClamp;
bool m_PBuffer;
bool m_GenerateMipmaps;
} m_Caps;
// renderer options
struct Options {
bool m_NoVBO;
bool m_NoPBuffer;
bool m_Shadows;
RGBColor m_ShadowColor;
} m_Options;
// build card cap bits
void EnumCaps();
// per-frame renderer stats
Stats m_Stats;
// active textures on each unit
GLuint m_ActiveTextures[MaxTextureUnits];
};
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Name: Renderer.h
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
// Description: OpenGL renderer class; a higher level interface
// on top of OpenGL to handle rendering the basic visual games
// types - terrain, models, sprites, particles etc
//
///////////////////////////////////////////////////////////////////////////////
#ifndef RENDERER_H
#define RENDERER_H
#include <vector>
#include "res/res.h"
#include "ogl.h"
#include "Camera.h"
#include "Frustum.h"
#include "PatchRData.h"
#include "ModelRData.h"
#include "SHCoeffs.h"
#include "Terrain.h"
#include "Singleton.h"
// necessary declarations
class CCamera;
class CPatch;
class CSprite;
class CParticleSys;
class COverlay;
class CMaterial;
class CLightEnv;
class CTexture;
class CTerrain;
// rendering modes
enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES };
// stream flags
#define STREAM_POS 0x01
#define STREAM_NORMAL 0x02
#define STREAM_COLOR 0x04
#define STREAM_UV0 0x08
#define STREAM_UV1 0x10
#define STREAM_UV2 0x20
#define STREAM_UV3 0x40
#define STREAM_POSTOUV0 0x80
//////////////////////////////////////////////////////////////////////////////////////////
// SVertex3D: simple 3D vertex declaration
struct SVertex3D
{
float m_Position[3];
float m_TexCoords[2];
unsigned int m_Color;
};
//////////////////////////////////////////////////////////////////////////////////////////
// SVertex2D: simple 2D vertex declaration
struct SVertex2D
{
float m_Position[2];
float m_TexCoords[2];
unsigned int m_Color;
};
// access to sole renderer object
#define g_Renderer CRenderer::GetSingleton()
///////////////////////////////////////////////////////////////////////////////////////////
// CRenderer: base renderer class - primary interface to the rendering engine
class CRenderer : public Singleton<CRenderer>
{
public:
// various enumerations and renderer related constants
enum { NumAlphaMaps=14 };
enum { MaxTextureUnits=16 };
enum Option {
OPT_NOVBO,
OPT_NOPBUFFER,
OPT_SHADOWS,
OPT_SHADOWCOLOR
};
// stats class - per frame counts of number of draw calls, poly counts etc
struct Stats {
// set all stats to zero
void Reset() { memset(this,0,sizeof(*this)); }
// add given stats to this stats
Stats& operator+=(const Stats& rhs) {
m_Counter++;
m_DrawCalls+=rhs.m_DrawCalls;
m_TerrainTris+=rhs.m_TerrainTris;
m_ModelTris+=rhs.m_ModelTris;
m_TransparentTris+=rhs.m_TransparentTris;
m_BlendSplats+=rhs.m_BlendSplats;
return *this;
}
// count of the number of stats added together
u32 m_Counter;
// number of draw calls per frame - total DrawElements + Begin/End immediate mode loops
u32 m_DrawCalls;
// number of terrain triangles drawn
u32 m_TerrainTris;
// number of (non-transparent) model triangles drawn
u32 m_ModelTris;
// number of transparent model triangles drawn
u32 m_TransparentTris;
// number of splat passes for alphamapping
u32 m_BlendSplats;
};
public:
// constructor, destructor
CRenderer();
~CRenderer();
// open up the renderer: performs any necessary initialisation
bool Open(int width,int height,int depth);
// shutdown the renderer: performs any necessary cleanup
void Close();
// resize renderer view
void Resize(int width,int height);
// set/get boolean renderer option
void SetOptionBool(enum Option opt,bool value);
bool GetOptionBool(enum Option opt) const;
// set/get color renderer option
void SetOptionColor(enum Option opt,const RGBColor& value);
const RGBColor& GetOptionColor(enum Option opt) const;
// return view width
int GetWidth() const { return m_Width; }
// return view height
int GetHeight() const { return m_Height; }
// return view aspect ratio
float GetAspect() const { return float(m_Width)/float(m_Height); }
// signal frame start
void BeginFrame();
// force rendering of any batched objects
void FlushFrame();
// signal frame end : implicitly flushes batched objects
void EndFrame();
// set color used to clear screen in BeginFrame()
void SetClearColor(u32 color);
// return current frame counter
int GetFrameCounter() const { return m_FrameCounter; }
// set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices
void SetCamera(CCamera& camera);
// submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond
// the call to frame end, as must the object itself
void Submit(CPatch* patch);
void Submit(CModel* model);
void Submit(CSprite* sprite);
void Submit(CParticleSys* psys);
void Submit(COverlay* overlay);
// basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in
// editor tools (eg for highlighting specific terrain patches)
// note:
// * all 3D vertices specified in world space
// * primitive operations rendered immediatedly, never batched
// * primitives rendered in current material (set via SetMaterial)
void RenderLine(const SVertex2D* vertices);
void RenderLineLoop(int len,const SVertex2D* vertices);
void RenderTri(const SVertex2D* vertices);
void RenderQuad(const SVertex2D* vertices);
void RenderLine(const SVertex3D* vertices);
void RenderLineLoop(int len,const SVertex3D* vertices);
void RenderTri(const SVertex3D* vertices);
void RenderQuad(const SVertex3D* vertices);
// set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer,
// so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering)
void SetLightEnv(CLightEnv* lightenv) {
m_LightEnv=lightenv;
}
// set the mode to render subsequent terrain patches
void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode=mode; }
// get the mode to render subsequent terrain patches
ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; }
// set the mode to render subsequent models
void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode=mode; }
// get the mode to render subsequent models
ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; }
// try and load the given texture
bool LoadTexture(CTexture* texture,u32 wrapflags);
// set the given unit to reference the given texture; pass a null texture to disable texturing on any unit
void SetTexture(int unit,CTexture* texture);
// BindTexture: bind a GL texture object to given unit
void BindTexture(int unit,GLuint tex);
// query transparency of given texture
bool IsTextureTransparent(CTexture* texture);
// load the default set of alphamaps; return false if any alphamap fails to load, true otherwise
bool LoadAlphaMaps(const char* fnames[]);
// return stats accumulated for current frame
const Stats& GetStats() { return m_Stats; }
protected:
friend class CPatchRData;
friend class CModelRData;
friend class CTransparencyRenderer;
// recurse down given model building renderdata for it and all it's children
void UpdateModelDataRecursive(CModel* model);
// update renderdata of everything submitted
void UpdateSubmittedObjectData();
// patch rendering stuff
void RenderPatchSubmissions();
void RenderPatches();
// model rendering stuff
void BuildTransparentPasses(CModel* model);
void RenderModelSubmissions();
void RenderModelsRecursive(CModel* model,u32 streamflags);
void RenderModelsStreams(u32 streamflags);
void RenderModels();
// shadow rendering stuff
void CreateShadowMap();
void RenderShadowMap();
void ApplyShadowMap();
void CRenderer::BuildTransformation(const CVector3D& pos,const CVector3D& right,const CVector3D& up,
const CVector3D& dir,CMatrix3D& result);
void ConstructLightTransform(const CVector3D& pos,const CVector3D& lightdir,CMatrix3D& result);
void CalcShadowMatrices();
void CalcShadowBounds(CBound& bounds);
// RENDERER DATA:
// view width
int m_Width;
// view height
int m_Height;
// view depth (bpp)
int m_Depth;
// frame counter
int m_FrameCounter;
// current terrain rendering mode
ERenderMode m_TerrainRenderMode;
// current model rendering mode
ERenderMode m_ModelRenderMode;
// current view camera
CCamera m_Camera;
// color used to clear screen in BeginFrame
float m_ClearColor[4];
// submitted object lists for batching
std::vector<CPatch*> m_TerrainPatches;
std::vector<CModel*> m_Models;
std::vector<CSprite*> m_Sprites;
std::vector<CParticleSys*> m_ParticleSyses;
std::vector<COverlay*> m_Overlays;
// current lighting setup
CLightEnv* m_LightEnv;
// current spherical harmonic coefficients (for unit lighting), derived from lightenv
CSHCoeffs m_SHCoeffsUnits;
// current spherical harmonic coefficients (for terrain lighting), derived from lightenv
CSHCoeffs m_SHCoeffsTerrain;
// handle of composite alpha map (all the alpha maps packed into one texture)
u32 m_CompositeAlphaMap;
// handle of shadow map
u32 m_ShadowMap;
// size of each side of shadow map
u32 m_ShadowMapSize;
// per-frame flag: has the shadow map been rendered this frame?
bool m_ShadowRendered;
// projection matrix of shadow casting light
CMatrix3D m_LightProjection;
// transformation matrix of shadow casting light
CMatrix3D m_LightTransform;
// coordinates of each (untransformed) alpha map within the packed texture
struct {
float u0,u1,v0,v1;
} m_AlphaMapCoords[NumAlphaMaps];
// card capabilities
struct Caps {
bool m_VBO;
bool m_TextureBorderClamp;
bool m_PBuffer;
bool m_GenerateMipmaps;
} m_Caps;
// renderer options
struct Options {
bool m_NoVBO;
bool m_NoPBuffer;
bool m_Shadows;
RGBColor m_ShadowColor;
} m_Options;
// build card cap bits
void EnumCaps();
// per-frame renderer stats
Stats m_Stats;
// active textures on each unit
GLuint m_ActiveTextures[MaxTextureUnits];
};
#endif

View File

@ -1,185 +1,185 @@
#include <algorithm>
#include "Renderer.h"
#include "TransparencyRenderer.h"
#include "Model.h"
CTransparencyRenderer g_TransparencyRenderer;
///////////////////////////////////////////////////////////////////////////////////////////////////
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
struct SortObjectsByDist {
typedef CTransparencyRenderer::SObject SortObj;
bool operator()(const SortObj& lhs,const SortObj& rhs) {
return lhs.m_Dist>rhs.m_Dist? true : false;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Sort: coarsely sort submitted objects in back to front manner
void CTransparencyRenderer::Sort()
{
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Render: render all deferred passes; call Sort before using to ensure passes
// are drawn in correct order
void CTransparencyRenderer::Render()
{
// switch on wireframe if we need it
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
// switch on client states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// setup texture environment to modulate diffuse color with texture color
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
// just pass through texture's alpha
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER,0.975f);
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
glDepthMask(0);
glAlphaFunc(GL_LEQUAL,0.975f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDepthMask(1);
// switch off client states
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
// switch wireframe off again
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
} else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) {
// edged faces: need to make a second pass over the data:
// first switch on wireframe
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
// setup some renderstate ..
glDepthMask(0);
g_Renderer.SetTexture(0,0);
glColor4f(1,1,1,0.75f);
glLineWidth(1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// .. and some client states
glEnableClientState(GL_VERTEX_ARRAY);
// render each model
RenderObjectsStreams(STREAM_POS);
// .. and switch off the client states
glDisableClientState(GL_VERTEX_ARRAY);
// .. and restore the renderstates
glDisable(GL_BLEND);
glDepthMask(1);
// restore fill mode, and we're done
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
}
void CTransparencyRenderer::Clear()
{
// all transparent objects rendered; release them
m_Objects.clear();
}
void CTransparencyRenderer::Add(CModel* model)
{
// resize array, get last object in list
m_Objects.resize(m_Objects.size()+1);
SObject& obj=m_Objects.back();
obj.m_Model=model;
// build transform from object to camera space
CMatrix3D objToCam,invcam;
g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam);
objToCam*=model->GetTransform();
// resort model indices from back to front, according to camera position - and store
// the returned sqrd distance to the centre of the nearest triangle
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam);
}
void CTransparencyRenderer::RenderShadows()
{
// coarsely sort submitted objects in back to front manner
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
// switch on client states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDepthMask(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
RenderObjectsStreams(STREAM_POS|STREAM_UV0);
glDisable(GL_ALPHA_TEST);
glDepthMask(1);
glDisable(GL_BLEND);
// switch off client states
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// RenderObjectsStreams: render given streams on all objects
void CTransparencyRenderer::RenderObjectsStreams(u32 streamflags)
{
for (uint i=0;i<m_Objects.size();++i) {
CModel* model=m_Objects[i].m_Model;
glPushMatrix();
glMultMatrixf(&model->GetTransform()._11);
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
modeldata->RenderStreams(streamflags,true);
glPopMatrix();
}
#include <algorithm>
#include "Renderer.h"
#include "TransparencyRenderer.h"
#include "Model.h"
CTransparencyRenderer g_TransparencyRenderer;
///////////////////////////////////////////////////////////////////////////////////////////////////
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
struct SortObjectsByDist {
typedef CTransparencyRenderer::SObject SortObj;
bool operator()(const SortObj& lhs,const SortObj& rhs) {
return lhs.m_Dist>rhs.m_Dist? true : false;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Sort: coarsely sort submitted objects in back to front manner
void CTransparencyRenderer::Sort()
{
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Render: render all deferred passes; call Sort before using to ensure passes
// are drawn in correct order
void CTransparencyRenderer::Render()
{
// switch on wireframe if we need it
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
// switch on client states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// setup texture environment to modulate diffuse color with texture color
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
// just pass through texture's alpha
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER,0.975f);
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
glDepthMask(0);
glAlphaFunc(GL_LEQUAL,0.975f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDepthMask(1);
// switch off client states
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
// switch wireframe off again
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
} else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) {
// edged faces: need to make a second pass over the data:
// first switch on wireframe
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
// setup some renderstate ..
glDepthMask(0);
g_Renderer.SetTexture(0,0);
glColor4f(1,1,1,0.75f);
glLineWidth(1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// .. and some client states
glEnableClientState(GL_VERTEX_ARRAY);
// render each model
RenderObjectsStreams(STREAM_POS);
// .. and switch off the client states
glDisableClientState(GL_VERTEX_ARRAY);
// .. and restore the renderstates
glDisable(GL_BLEND);
glDepthMask(1);
// restore fill mode, and we're done
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
}
void CTransparencyRenderer::Clear()
{
// all transparent objects rendered; release them
m_Objects.clear();
}
void CTransparencyRenderer::Add(CModel* model)
{
// resize array, get last object in list
m_Objects.resize(m_Objects.size()+1);
SObject& obj=m_Objects.back();
obj.m_Model=model;
// build transform from object to camera space
CMatrix3D objToCam,invcam;
g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam);
objToCam*=model->GetTransform();
// resort model indices from back to front, according to camera position - and store
// the returned sqrd distance to the centre of the nearest triangle
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam);
}
void CTransparencyRenderer::RenderShadows()
{
// coarsely sort submitted objects in back to front manner
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
// switch on client states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDepthMask(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
RenderObjectsStreams(STREAM_POS|STREAM_UV0);
glDisable(GL_ALPHA_TEST);
glDepthMask(1);
glDisable(GL_BLEND);
// switch off client states
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// RenderObjectsStreams: render given streams on all objects
void CTransparencyRenderer::RenderObjectsStreams(u32 streamflags)
{
for (uint i=0;i<m_Objects.size();++i) {
CModel* model=m_Objects[i].m_Model;
glPushMatrix();
glMultMatrixf(&model->GetTransform()._11);
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
modeldata->RenderStreams(streamflags,true);
glPopMatrix();
}
}

View File

@ -1,39 +1,39 @@
#ifndef __TRANSPARENCYRENDERER_H
#define __TRANSPARENCYRENDERER_H
#include <vector>
class CModel;
class CTransparencyRenderer
{
public:
struct SObject {
// the transparent model
CModel* m_Model;
// sqrd distance from camera to centre of nearest triangle
float m_Dist;
};
public:
// add object to render in deferred transparency pass
void Add(CModel* model);
// render all deferred objects
void Render();
// render shadows from all deferred objects
void RenderShadows();
// coarsely sort submitted objects in back to front manner
void Sort();
// empty object list
void Clear();
private:
// render given streams on all objects
void RenderObjectsStreams(u32 streamflags);
// list of transparent objects to render
std::vector<SObject> m_Objects;
};
extern CTransparencyRenderer g_TransparencyRenderer;
#endif
#ifndef __TRANSPARENCYRENDERER_H
#define __TRANSPARENCYRENDERER_H
#include <vector>
class CModel;
class CTransparencyRenderer
{
public:
struct SObject {
// the transparent model
CModel* m_Model;
// sqrd distance from camera to centre of nearest triangle
float m_Dist;
};
public:
// add object to render in deferred transparency pass
void Add(CModel* model);
// render all deferred objects
void Render();
// render shadows from all deferred objects
void RenderShadows();
// coarsely sort submitted objects in back to front manner
void Sort();
// empty object list
void Clear();
private:
// render given streams on all objects
void RenderObjectsStreams(u32 streamflags);
// list of transparent objects to render
std::vector<SObject> m_Objects;
};
extern CTransparencyRenderer g_TransparencyRenderer;
#endif

View File

@ -1,121 +1,121 @@
#include "AlterElevationCommand.h"
#include "UIGlobals.h"
#include "MiniMap.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
CAlterElevationCommand::CAlterElevationCommand(int brushSize,int selectionCentre[2])
{
m_BrushSize=brushSize;
m_SelectionCentre[0]=selectionCentre[0];
m_SelectionCentre[1]=selectionCentre[1];
}
CAlterElevationCommand::~CAlterElevationCommand()
{
}
void CAlterElevationCommand::Execute()
{
int r=m_BrushSize;
u32 mapSize=g_Terrain.GetVerticesPerSide();
// get range of vertices affected by brush
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
// resize input/output arrays
m_DataIn.resize(x1-x0+1,z1-z0+1);
m_DataOut.resize(x1-x0+1,z1-z0+1);
// fill input data
int i,j;
for (j=z0;j<=z1;j++) {
for (i=x0;i<=x1;i++) {
u16 input=g_Terrain.GetHeightMap()[j*mapSize+i];
m_DataIn(i-x0,j-z0)=input;
}
}
// call on base classes to fill the output data
CalcDataOut(x0,x1,z0,z1);
// now actually apply data to terrain
ApplyDataToSelection(m_DataOut);
}
void CAlterElevationCommand::ApplyDataToSelection(const CArray2D<u16>& data)
{
u32 mapSize=g_Terrain.GetVerticesPerSide();
int r=m_BrushSize;
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
// copy given data to heightmap
int i,j;
for (j=z0;j<=z1;j++) {
for (i=x0;i<=x1;i++) {
int idx=j*mapSize+i;
u16 height=data(i-x0,j-z0);
// update heightmap
g_Terrain.GetHeightMap()[idx]=height;
}
}
// flag vertex data as dirty for affected patches, and rebuild bounds of these patches
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
int px0=clamp(-1+(x0/16),0,patchesPerSide);
int px1=clamp(1+(x1/16),0,patchesPerSide);
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
int pz1=clamp(1+(z1/16),0,patchesPerSide);
for (j=pz0;j<pz1;j++) {
for (int i=px0;i<px1;i++) {
CPatch* patch=g_Terrain.GetPatch(i,j);
patch->CalcBounds();
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}
// rebuild this bit of the minimap
int w=1+2*m_BrushSize;
int x=m_SelectionCentre[1]-m_BrushSize;
if (x<0) {
w+=x;
x=0;
}
int h=1+2*m_BrushSize;
int y=m_SelectionCentre[0]-m_BrushSize;
if (y<0) {
h+=y;
y=0;
}
g_MiniMap.Rebuild(x,y,w,h);
}
void CAlterElevationCommand::Undo()
{
ApplyDataToSelection(m_DataIn);
}
void CAlterElevationCommand::Redo()
{
ApplyDataToSelection(m_DataOut);
}
#include "AlterElevationCommand.h"
#include "UIGlobals.h"
#include "MiniMap.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
CAlterElevationCommand::CAlterElevationCommand(int brushSize,int selectionCentre[2])
{
m_BrushSize=brushSize;
m_SelectionCentre[0]=selectionCentre[0];
m_SelectionCentre[1]=selectionCentre[1];
}
CAlterElevationCommand::~CAlterElevationCommand()
{
}
void CAlterElevationCommand::Execute()
{
int r=m_BrushSize;
u32 mapSize=g_Terrain.GetVerticesPerSide();
// get range of vertices affected by brush
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
// resize input/output arrays
m_DataIn.resize(x1-x0+1,z1-z0+1);
m_DataOut.resize(x1-x0+1,z1-z0+1);
// fill input data
int i,j;
for (j=z0;j<=z1;j++) {
for (i=x0;i<=x1;i++) {
u16 input=g_Terrain.GetHeightMap()[j*mapSize+i];
m_DataIn(i-x0,j-z0)=input;
}
}
// call on base classes to fill the output data
CalcDataOut(x0,x1,z0,z1);
// now actually apply data to terrain
ApplyDataToSelection(m_DataOut);
}
void CAlterElevationCommand::ApplyDataToSelection(const CArray2D<u16>& data)
{
u32 mapSize=g_Terrain.GetVerticesPerSide();
int r=m_BrushSize;
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
// copy given data to heightmap
int i,j;
for (j=z0;j<=z1;j++) {
for (i=x0;i<=x1;i++) {
int idx=j*mapSize+i;
u16 height=data(i-x0,j-z0);
// update heightmap
g_Terrain.GetHeightMap()[idx]=height;
}
}
// flag vertex data as dirty for affected patches, and rebuild bounds of these patches
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
int px0=clamp(-1+(x0/16),0,patchesPerSide);
int px1=clamp(1+(x1/16),0,patchesPerSide);
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
int pz1=clamp(1+(z1/16),0,patchesPerSide);
for (j=pz0;j<pz1;j++) {
for (int i=px0;i<px1;i++) {
CPatch* patch=g_Terrain.GetPatch(i,j);
patch->CalcBounds();
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}
// rebuild this bit of the minimap
int w=1+2*m_BrushSize;
int x=m_SelectionCentre[1]-m_BrushSize;
if (x<0) {
w+=x;
x=0;
}
int h=1+2*m_BrushSize;
int y=m_SelectionCentre[0]-m_BrushSize;
if (y<0) {
h+=y;
y=0;
}
g_MiniMap.Rebuild(x,y,w,h);
}
void CAlterElevationCommand::Undo()
{
ApplyDataToSelection(m_DataIn);
}
void CAlterElevationCommand::Redo()
{
ApplyDataToSelection(m_DataOut);
}

View File

@ -1,45 +1,45 @@
#ifndef _ALTERELEVATIONCOMMAND_H
#define _ALTERELEVATIONCOMMAND_H
#include <set>
#include "res/res.h"
#include "Command.h"
#include "Array2D.h"
class CAlterElevationCommand : public CCommand
{
public:
// constructor, destructor
CAlterElevationCommand(int brushSize,int selectionCentre[2]);
~CAlterElevationCommand();
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return true; }
// undo
void Undo();
// redo
void Redo();
// abstract function implemented by subclasses to fill in outgoing data member
virtual void CalcDataOut(int x0,int x1,int z0,int z1) = 0;
protected:
void ApplyDataToSelection(const CArray2D<u16>& data);
// size of brush
int m_BrushSize;
// centre of brush
int m_SelectionCentre[2];
// origin of data set
int m_SelectionOrigin[2];
// input data (original terrain heights)
CArray2D<u16> m_DataIn;
// output data (final terrain heights)
CArray2D<u16> m_DataOut;
};
#endif
#ifndef _ALTERELEVATIONCOMMAND_H
#define _ALTERELEVATIONCOMMAND_H
#include <set>
#include "res/res.h"
#include "Command.h"
#include "Array2D.h"
class CAlterElevationCommand : public CCommand
{
public:
// constructor, destructor
CAlterElevationCommand(int brushSize,int selectionCentre[2]);
~CAlterElevationCommand();
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return true; }
// undo
void Undo();
// redo
void Redo();
// abstract function implemented by subclasses to fill in outgoing data member
virtual void CalcDataOut(int x0,int x1,int z0,int z1) = 0;
protected:
void ApplyDataToSelection(const CArray2D<u16>& data);
// size of brush
int m_BrushSize;
// centre of brush
int m_SelectionCentre[2];
// origin of data set
int m_SelectionOrigin[2];
// input data (original terrain heights)
CArray2D<u16> m_DataIn;
// output data (final terrain heights)
CArray2D<u16> m_DataOut;
};
#endif

View File

@ -1,66 +1,66 @@
#include "AlterLightEnvCommand.h"
#include "UnitManager.h"
#include "ObjectManager.h"
#include "Model.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
extern CLightEnv g_LightEnv;
CAlterLightEnvCommand::CAlterLightEnvCommand(const CLightEnv& env) : m_LightEnv(env)
{
}
CAlterLightEnvCommand::~CAlterLightEnvCommand()
{
}
void CAlterLightEnvCommand::Execute()
{
// save current lighting environment
m_SavedLightEnv=g_LightEnv;
// apply this commands lighting environment onto the global lighting environment
ApplyData(m_LightEnv);
}
void CAlterLightEnvCommand::ApplyData(const CLightEnv& env)
{
// copy given lighting environment to global environment
g_LightEnv=env;
// dirty the vertices on all patches
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
u32 i,j;
for (j=0;j<patchesPerSide;j++) {
for (i=0;i<patchesPerSide;i++) {
CPatch* patch=g_Terrain.GetPatch(i,j);
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}
// dirty all models
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
for (i=0;i<units.size();++i) {
CUnit* unit=units[i];
unit->GetModel()->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
CObjectEntry* selobject=g_ObjMan.GetSelectedObject();
if (selobject && selobject->m_Model) {
selobject->m_Model->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}
void CAlterLightEnvCommand::Undo()
{
ApplyData(m_SavedLightEnv);
}
void CAlterLightEnvCommand::Redo()
{
ApplyData(m_LightEnv);
}
#include "AlterLightEnvCommand.h"
#include "UnitManager.h"
#include "ObjectManager.h"
#include "Model.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
extern CLightEnv g_LightEnv;
CAlterLightEnvCommand::CAlterLightEnvCommand(const CLightEnv& env) : m_LightEnv(env)
{
}
CAlterLightEnvCommand::~CAlterLightEnvCommand()
{
}
void CAlterLightEnvCommand::Execute()
{
// save current lighting environment
m_SavedLightEnv=g_LightEnv;
// apply this commands lighting environment onto the global lighting environment
ApplyData(m_LightEnv);
}
void CAlterLightEnvCommand::ApplyData(const CLightEnv& env)
{
// copy given lighting environment to global environment
g_LightEnv=env;
// dirty the vertices on all patches
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
u32 i,j;
for (j=0;j<patchesPerSide;j++) {
for (i=0;i<patchesPerSide;i++) {
CPatch* patch=g_Terrain.GetPatch(i,j);
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}
// dirty all models
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
for (i=0;i<units.size();++i) {
CUnit* unit=units[i];
unit->GetModel()->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
CObjectEntry* selobject=g_ObjMan.GetSelectedObject();
if (selobject && selobject->m_Model) {
selobject->m_Model->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}
void CAlterLightEnvCommand::Undo()
{
ApplyData(m_SavedLightEnv);
}
void CAlterLightEnvCommand::Redo()
{
ApplyData(m_LightEnv);
}

View File

@ -1,40 +1,40 @@
#ifndef _ALTERLIGHTENVCOMMAND_H
#define _ALTERLIGHTENVCOMMAND_H
#include <set>
#include "res/res.h"
#include "Command.h"
#include "LightEnv.h"
class CAlterLightEnvCommand : public CCommand
{
public:
// constructor, destructor
CAlterLightEnvCommand(const CLightEnv& env);
~CAlterLightEnvCommand();
// return the texture name of this command
const char* GetName() const { return "Alter Lighting Parameters"; }
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return true; }
// undo
void Undo();
// redo
void Redo();
private:
// apply given lighting parameters to global environment
void ApplyData(const CLightEnv& env);
// lighting parameters to apply to the environment
CLightEnv m_LightEnv;
// old lighting parameters - saved for undo/redo
CLightEnv m_SavedLightEnv;
};
#endif
#ifndef _ALTERLIGHTENVCOMMAND_H
#define _ALTERLIGHTENVCOMMAND_H
#include <set>
#include "res/res.h"
#include "Command.h"
#include "LightEnv.h"
class CAlterLightEnvCommand : public CCommand
{
public:
// constructor, destructor
CAlterLightEnvCommand(const CLightEnv& env);
~CAlterLightEnvCommand();
// return the texture name of this command
const char* GetName() const { return "Alter Lighting Parameters"; }
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return true; }
// undo
void Undo();
// redo
void Redo();
private:
// apply given lighting parameters to global environment
void ApplyData(const CLightEnv& env);
// lighting parameters to apply to the environment
CLightEnv m_LightEnv;
// old lighting parameters - saved for undo/redo
CLightEnv m_SavedLightEnv;
};
#endif

View File

@ -1,202 +1,202 @@
#ifndef _ARRAY2D_H
#define _ARRAY2D_H
template <class T>
class CArray2D
{
public:
CArray2D();
CArray2D(int usize,int vsize);
CArray2D(int usize,int vsize,const T* data);
CArray2D(const CArray2D& rhs);
virtual ~CArray2D();
CArray2D& operator=(const CArray2D& rhs);
operator T*();
operator const T*() const;
int usize() const;
int vsize() const;
void size(int& usize,int& vsize) const;
void resize(int usize,int vsize);
void fill(const T* elements);
T& operator()(int a,int b);
const T& operator()(int a,int b) const;
T& at(int a,int b);
const T& at(int a,int b) const;
protected:
// allocate and deallocate are overrideable by subclasses, allowing alternative
// (more efficient) allocation in certain circumstances
// * if allocation/deallocation is not done using new[]/delete[], it is necessary
// to override both functions
virtual void allocate();
virtual void deallocate();
int _usize; // no of columns;
int _vsize; // no of rows
T* _elements;
};
///////////////////////////////////////////////////////////////////////////
#include <assert.h>
#include <string.h>
template <class T>
CArray2D<T>::CArray2D() : _usize(0), _vsize(0), _elements(0)
{
}
template <class T>
CArray2D<T>::CArray2D(int usize,int vsize)
: _usize(usize), _vsize(vsize), _elements(0)
{
allocate();
}
template <class T>
CArray2D<T>::CArray2D(int usize,int vsize,const T* elements)
: _usize(usize), _vsize(vsize), _elements(0)
{
assert(elements!=0);
allocate();
fill(elements);
}
template <class T>
CArray2D<T>::CArray2D(const CArray2D<T>& rhs)
: _usize(rhs._usize), _vsize(rhs._vsize), _elements(0)
{
allocate();
fill(rhs._elements);
}
template <class T>
CArray2D<T>::~CArray2D()
{
deallocate();
}
template <class T>
CArray2D<T>& CArray2D<T>::operator=(const CArray2D<T>& rhs)
{
if (this==&rhs)
return *this;
deallocate();
_usize=rhs._usize;
_vsize=rhs._vsize;
allocate();
fill(rhs._elements);
return *this;
}
template <class T>
void CArray2D<T>::allocate()
{
assert(_elements==0);
_elements=new T[_usize*_vsize];
}
template <class T>
void CArray2D<T>::deallocate()
{
delete[] _elements;
_elements=0;
}
template <class T>
int CArray2D<T>::usize() const
{
return _usize;
}
template <class T>
int CArray2D<T>::vsize() const
{
return _vsize;
}
template <class T>
void CArray2D<T>::size(int& usize,int& vsize) const
{
usize=_usize;
vsize=_vsize;
}
template <class T>
void CArray2D<T>::resize(int usize,int vsize)
{
deallocate();
_usize=usize;
_vsize=vsize;
allocate();
}
template <class T>
void CArray2D<T>::fill(const T* elements)
{
memcpy(_elements,elements,sizeof(T)*_usize*_vsize);
}
// operator()(int r,int c)
// return the element at (r,c) (ie c'th element in r'th row)
template <class T>
T& CArray2D<T>::operator()(int u,int v)
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
const T& CArray2D<T>::operator()(int u,int v) const
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
T& CArray2D<T>::at(int u,int v)
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
const T& CArray2D<T>::at(int u,int v) const
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
CArray2D<T>::operator T*()
{
return _elements;
}
template <class T>
CArray2D<T>::operator const T*() const
{
return _elements;
}
///////////////////////////////////////////////////////////////////////////
#endif
#ifndef _ARRAY2D_H
#define _ARRAY2D_H
template <class T>
class CArray2D
{
public:
CArray2D();
CArray2D(int usize,int vsize);
CArray2D(int usize,int vsize,const T* data);
CArray2D(const CArray2D& rhs);
virtual ~CArray2D();
CArray2D& operator=(const CArray2D& rhs);
operator T*();
operator const T*() const;
int usize() const;
int vsize() const;
void size(int& usize,int& vsize) const;
void resize(int usize,int vsize);
void fill(const T* elements);
T& operator()(int a,int b);
const T& operator()(int a,int b) const;
T& at(int a,int b);
const T& at(int a,int b) const;
protected:
// allocate and deallocate are overrideable by subclasses, allowing alternative
// (more efficient) allocation in certain circumstances
// * if allocation/deallocation is not done using new[]/delete[], it is necessary
// to override both functions
virtual void allocate();
virtual void deallocate();
int _usize; // no of columns;
int _vsize; // no of rows
T* _elements;
};
///////////////////////////////////////////////////////////////////////////
#include <assert.h>
#include <string.h>
template <class T>
CArray2D<T>::CArray2D() : _usize(0), _vsize(0), _elements(0)
{
}
template <class T>
CArray2D<T>::CArray2D(int usize,int vsize)
: _usize(usize), _vsize(vsize), _elements(0)
{
allocate();
}
template <class T>
CArray2D<T>::CArray2D(int usize,int vsize,const T* elements)
: _usize(usize), _vsize(vsize), _elements(0)
{
assert(elements!=0);
allocate();
fill(elements);
}
template <class T>
CArray2D<T>::CArray2D(const CArray2D<T>& rhs)
: _usize(rhs._usize), _vsize(rhs._vsize), _elements(0)
{
allocate();
fill(rhs._elements);
}
template <class T>
CArray2D<T>::~CArray2D()
{
deallocate();
}
template <class T>
CArray2D<T>& CArray2D<T>::operator=(const CArray2D<T>& rhs)
{
if (this==&rhs)
return *this;
deallocate();
_usize=rhs._usize;
_vsize=rhs._vsize;
allocate();
fill(rhs._elements);
return *this;
}
template <class T>
void CArray2D<T>::allocate()
{
assert(_elements==0);
_elements=new T[_usize*_vsize];
}
template <class T>
void CArray2D<T>::deallocate()
{
delete[] _elements;
_elements=0;
}
template <class T>
int CArray2D<T>::usize() const
{
return _usize;
}
template <class T>
int CArray2D<T>::vsize() const
{
return _vsize;
}
template <class T>
void CArray2D<T>::size(int& usize,int& vsize) const
{
usize=_usize;
vsize=_vsize;
}
template <class T>
void CArray2D<T>::resize(int usize,int vsize)
{
deallocate();
_usize=usize;
_vsize=vsize;
allocate();
}
template <class T>
void CArray2D<T>::fill(const T* elements)
{
memcpy(_elements,elements,sizeof(T)*_usize*_vsize);
}
// operator()(int r,int c)
// return the element at (r,c) (ie c'th element in r'th row)
template <class T>
T& CArray2D<T>::operator()(int u,int v)
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
const T& CArray2D<T>::operator()(int u,int v) const
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
T& CArray2D<T>::at(int u,int v)
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
const T& CArray2D<T>::at(int u,int v) const
{
assert(u>=0 && u<_usize);
assert(v>=0 && v<_vsize);
return _elements[(u*_vsize)+v];
}
template <class T>
CArray2D<T>::operator T*()
{
return _elements;
}
template <class T>
CArray2D<T>::operator const T*() const
{
return _elements;
}
///////////////////////////////////////////////////////////////////////////
#endif

View File

@ -1,92 +1,92 @@
#include "stdafx.h"
#include "MainFrm.h"
#include "EditorData.h"
#include "BrushShapeEditorTool.h"
#include "BrushShapeEditorDlgBar.h"
BEGIN_MESSAGE_MAP(CBrushShapeEditorDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CBrushShapeEditorDlgBar)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
ON_CBN_SELCHANGE(IDC_COMBO_TERRAINTYPES, OnSelChangeBrush)
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
END_MESSAGE_MAP()
CBrushShapeEditorDlgBar::CBrushShapeEditorDlgBar()
{
}
CBrushShapeEditorDlgBar::~CBrushShapeEditorDlgBar()
{
}
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
{
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
return FALSE;
}
if (!OnInitDialog()) {
return FALSE;
}
return TRUE;
}
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
{
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
return FALSE;
}
return TRUE;
}
void CBrushShapeEditorDlgBar::OnButtonAdd()
{
}
BOOL CBrushShapeEditorDlgBar::OnInitDialog()
{
// get the current window size and position
CRect rect;
GetWindowRect(rect);
// now change the size, position, and Z order of the window.
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
// set up brush size slider
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sliderctrl->SetRange(0,CBrushShapeEditorTool::MAX_BRUSH_SIZE);
sliderctrl->SetPos(CBrushShapeEditorTool::GetTool()->GetBrushSize());
return TRUE;
}
void CBrushShapeEditorDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
bDisableIfNoHndler = FALSE;
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
}
void CBrushShapeEditorDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
{
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
CBrushShapeEditorTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
*pResult = 0;
}
void CBrushShapeEditorDlgBar::OnSelChangeBrush()
{
}
void CBrushShapeEditorDlgBar::OnButtonBack()
{
CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd();
mainfrm->DeselectTools();
}
#include "stdafx.h"
#include "MainFrm.h"
#include "EditorData.h"
#include "BrushShapeEditorTool.h"
#include "BrushShapeEditorDlgBar.h"
BEGIN_MESSAGE_MAP(CBrushShapeEditorDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CBrushShapeEditorDlgBar)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
ON_CBN_SELCHANGE(IDC_COMBO_TERRAINTYPES, OnSelChangeBrush)
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
END_MESSAGE_MAP()
CBrushShapeEditorDlgBar::CBrushShapeEditorDlgBar()
{
}
CBrushShapeEditorDlgBar::~CBrushShapeEditorDlgBar()
{
}
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
{
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
return FALSE;
}
if (!OnInitDialog()) {
return FALSE;
}
return TRUE;
}
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
{
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
return FALSE;
}
return TRUE;
}
void CBrushShapeEditorDlgBar::OnButtonAdd()
{
}
BOOL CBrushShapeEditorDlgBar::OnInitDialog()
{
// get the current window size and position
CRect rect;
GetWindowRect(rect);
// now change the size, position, and Z order of the window.
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
// set up brush size slider
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sliderctrl->SetRange(0,CBrushShapeEditorTool::MAX_BRUSH_SIZE);
sliderctrl->SetPos(CBrushShapeEditorTool::GetTool()->GetBrushSize());
return TRUE;
}
void CBrushShapeEditorDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
bDisableIfNoHndler = FALSE;
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
}
void CBrushShapeEditorDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
{
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
CBrushShapeEditorTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
*pResult = 0;
}
void CBrushShapeEditorDlgBar::OnSelChangeBrush()
{
}
void CBrushShapeEditorDlgBar::OnButtonBack()
{
CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd();
mainfrm->DeselectTools();
}

View File

@ -1,31 +1,31 @@
#ifndef _BRUSHSHAPEEDITORDLGBAR_H
#define _BRUSHSHAPEEDITORDLGBAR_H
class CBrushShapeEditorDlgBar : public CDialogBar
{
// DECLARE_DYNAMIC(CInitDialogBar)
public:
CBrushShapeEditorDlgBar();
~CBrushShapeEditorDlgBar();
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
protected:
BOOL OnInitDialog();
// Generated message map functions
//{{AFX_MSG(CBrushShapeEditorDlgBar)
afx_msg void OnButtonAdd();
afx_msg void OnButtonBack();
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelChangeBrush();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
#ifndef _BRUSHSHAPEEDITORDLGBAR_H
#define _BRUSHSHAPEEDITORDLGBAR_H
class CBrushShapeEditorDlgBar : public CDialogBar
{
// DECLARE_DYNAMIC(CInitDialogBar)
public:
CBrushShapeEditorDlgBar();
~CBrushShapeEditorDlgBar();
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
protected:
BOOL OnInitDialog();
// Generated message map functions
//{{AFX_MSG(CBrushShapeEditorDlgBar)
afx_msg void OnButtonAdd();
afx_msg void OnButtonBack();
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelChangeBrush();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif

View File

@ -1,86 +1,86 @@
#include "BrushShapeEditorTool.h"
#include <stdlib.h>
#include <string.h>
#include "ogl.h"
// default tool instance
CBrushShapeEditorTool CBrushShapeEditorTool::m_BrushShapeEditorTool;
CBrushShapeEditorTool::CBrushShapeEditorTool() : m_BrushSize(5), m_BrushData(0)
{
m_BrushData=new bool[m_BrushSize*m_BrushSize];
memset(m_BrushData,0,sizeof(bool)*m_BrushSize*m_BrushSize);
}
void CBrushShapeEditorTool::OnDraw()
{
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glDepthMask(0);
// draw grid
// draw state of each bit in the brush
int r=m_BrushSize;
// iterate through selected patches
for (int j=0;j<r;j++) {
for (int i=0;i<r;i++) {
if (m_BrushData[j*m_BrushSize+i]) {
// draw filled quad here
}
}
}
glDepthMask(1);
}
void CBrushShapeEditorTool::OnLButtonDown(unsigned int flags,int px,int py)
{
// check for bit under cursor
if (0) {
// switch if on
}
}
void CBrushShapeEditorTool::OnRButtonDown(unsigned int flags,int px,int py)
{
// check for bit under cursor
if (0) {
// switch it off
}
}
void CBrushShapeEditorTool::OnMouseMove(unsigned int flags,int px,int py)
{
/*
if (flags & TOOL_MOUSEFLAG_LBUTTONDOWN) {
OnLButtonDown(flags,px,py);
} else if (flags & TOOL_MOUSEFLAG_RBUTTONDOWN) {
OnRButtonDown(flags,px,py);
}
*/
}
void CBrushShapeEditorTool::SetBrushSize(int size)
{
// allocate new data
bool* newdata=new bool[size*size];
memset(newdata,0,sizeof(bool)*size*size);
// copy data from old to new
bool* src=m_BrushData;
bool* dst=newdata;
u32 copysize=size>m_BrushSize ? m_BrushSize : size;
for (u32 j=0;j<copysize;j++) {
memcpy(dst,src,copysize*sizeof(bool));
dst+=copysize;
src+=m_BrushSize;
}
// clean up and assign new data as current
delete[] m_BrushData;
m_BrushData=newdata;
#include "BrushShapeEditorTool.h"
#include <stdlib.h>
#include <string.h>
#include "ogl.h"
// default tool instance
CBrushShapeEditorTool CBrushShapeEditorTool::m_BrushShapeEditorTool;
CBrushShapeEditorTool::CBrushShapeEditorTool() : m_BrushSize(5), m_BrushData(0)
{
m_BrushData=new bool[m_BrushSize*m_BrushSize];
memset(m_BrushData,0,sizeof(bool)*m_BrushSize*m_BrushSize);
}
void CBrushShapeEditorTool::OnDraw()
{
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glDepthMask(0);
// draw grid
// draw state of each bit in the brush
int r=m_BrushSize;
// iterate through selected patches
for (int j=0;j<r;j++) {
for (int i=0;i<r;i++) {
if (m_BrushData[j*m_BrushSize+i]) {
// draw filled quad here
}
}
}
glDepthMask(1);
}
void CBrushShapeEditorTool::OnLButtonDown(unsigned int flags,int px,int py)
{
// check for bit under cursor
if (0) {
// switch if on
}
}
void CBrushShapeEditorTool::OnRButtonDown(unsigned int flags,int px,int py)
{
// check for bit under cursor
if (0) {
// switch it off
}
}
void CBrushShapeEditorTool::OnMouseMove(unsigned int flags,int px,int py)
{
/*
if (flags & TOOL_MOUSEFLAG_LBUTTONDOWN) {
OnLButtonDown(flags,px,py);
} else if (flags & TOOL_MOUSEFLAG_RBUTTONDOWN) {
OnRButtonDown(flags,px,py);
}
*/
}
void CBrushShapeEditorTool::SetBrushSize(int size)
{
// allocate new data
bool* newdata=new bool[size*size];
memset(newdata,0,sizeof(bool)*size*size);
// copy data from old to new
bool* src=m_BrushData;
bool* dst=newdata;
u32 copysize=size>m_BrushSize ? m_BrushSize : size;
for (u32 j=0;j<copysize;j++) {
memcpy(dst,src,copysize*sizeof(bool));
dst+=copysize;
src+=m_BrushSize;
}
// clean up and assign new data as current
delete[] m_BrushData;
m_BrushData=newdata;
}

View File

@ -1,44 +1,44 @@
#ifndef _BRUSHSHAPEEDITORTOOL_H
#define _BRUSHSHAPEEDITORTOOL_H
#include "res/res.h"
#include "Tool.h"
class CPatch;
class CMiniPatch;
class CBrushShapeEditorTool : public CTool
{
public:
enum { MAX_BRUSH_SIZE=8 };
public:
CBrushShapeEditorTool();
// draw the visual representation of this tool
void OnDraw();
// callback for left button down event
void OnLButtonDown(unsigned int flags,int px,int py);
// callback for right button down event
void OnRButtonDown(unsigned int flags,int px,int py);
// callback for mouse move event
void OnMouseMove(unsigned int flags,int px,int py);
// set current brush size
void SetBrushSize(int size);
// get current brush size
int GetBrushSize() { return m_BrushSize; }
// get the default brush shape editor instance
static CBrushShapeEditorTool* GetTool() { return &m_BrushShapeEditorTool; }
protected:
// current tool brush size
int m_BrushSize;
// on/off state of each bit in the brush
bool* m_BrushData;
// default tool instance
static CBrushShapeEditorTool m_BrushShapeEditorTool;
};
#endif
#ifndef _BRUSHSHAPEEDITORTOOL_H
#define _BRUSHSHAPEEDITORTOOL_H
#include "res/res.h"
#include "Tool.h"
class CPatch;
class CMiniPatch;
class CBrushShapeEditorTool : public CTool
{
public:
enum { MAX_BRUSH_SIZE=8 };
public:
CBrushShapeEditorTool();
// draw the visual representation of this tool
void OnDraw();
// callback for left button down event
void OnLButtonDown(unsigned int flags,int px,int py);
// callback for right button down event
void OnRButtonDown(unsigned int flags,int px,int py);
// callback for mouse move event
void OnMouseMove(unsigned int flags,int px,int py);
// set current brush size
void SetBrushSize(int size);
// get current brush size
int GetBrushSize() { return m_BrushSize; }
// get the default brush shape editor instance
static CBrushShapeEditorTool* GetTool() { return &m_BrushShapeEditorTool; }
protected:
// current tool brush size
int m_BrushSize;
// on/off state of each bit in the brush
bool* m_BrushData;
// default tool instance
static CBrushShapeEditorTool m_BrushShapeEditorTool;
};
#endif

View File

@ -1,150 +1,150 @@
#include "BrushTool.h"
#include "UIGlobals.h"
#include "HFTracer.h"
#include "NaviCam.h"
#include "TextureManager.h"
#include "Camera.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ogl.h"
#include <list>
extern CCamera g_Camera;
extern CTerrain g_Terrain;
CBrushTool::CBrushTool() : m_BrushSize(1), m_LButtonDown(false), m_RButtonDown(false)
{
}
static void RenderTileOutline(int gx,int gz)
{
CMiniPatch* mpatch=g_Terrain.GetTile(gx,gz);
if (!mpatch) return;
u32 mapSize=g_Terrain.GetVerticesPerSide();
CVector3D V[4];
g_Terrain.CalcPosition(gx,gz,V[0]);
g_Terrain.CalcPosition(gx+1,gz,V[1]);
g_Terrain.CalcPosition(gx+1,gz+1,V[2]);
g_Terrain.CalcPosition(gx,gz+1,V[3]);
glLineWidth(2);
glColor4f(0.05f,0.95f,0.1f,0.75f);
glBegin (GL_LINE_LOOP);
for(int i = 0; i < 4; i++)
glVertex3fv(&V[i].X);
glEnd ();
glColor4f (0.1f,0.9f,0.15f,0.35f);
glBegin (GL_QUADS);
for(i = 0; i < 4; i++)
glVertex3fv(&V[i].X);
glEnd ();
}
void CBrushTool::OnDraw()
{
glActiveTexture (GL_TEXTURE0);
glDisable (GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(0);
int r=m_BrushSize;
// iterate through selected patches
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
RenderTileOutline(i,j);
}
}
glDepthMask(1);
glDisable(GL_BLEND);
}
void CBrushTool::OnLButtonDown(unsigned int flags,int px,int py)
{
m_LButtonDown=true;
OnTriggerLeft();
}
void CBrushTool::OnLButtonUp(unsigned int flags,int px,int py)
{
m_LButtonDown=false;
}
void CBrushTool::OnRButtonDown(unsigned int flags,int px,int py)
{
m_RButtonDown=true;
OnTriggerRight();
}
void CBrushTool::OnRButtonUp(unsigned int flags,int px,int py)
{
m_RButtonDown=false;
}
/////////////////////////////////////////////////////////////////////////////////////////
// BuildCameraRay: calculate origin and ray direction of a ray through
// the pixel (px,py) on the screen
void CBrushTool::BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir)
{
// get points on far plane of frustum in camera space
CCamera& camera=g_NaviCam.GetCamera();
CVector3D cPts[4];
camera.GetCameraPlanePoints(camera.GetFarPlane(),cPts);
// transform to world space
CVector3D wPts[4];
for (int i=0;i<4;i++) {
wPts[i]=camera.m_Orientation.Transform(cPts[i]);
}
// get world space position of mouse point
float dx=float(px)/float(g_Renderer.GetWidth());
float dz=1-float(py)/float(g_Renderer.GetHeight());
CVector3D vdx=wPts[1]-wPts[0];
CVector3D vdz=wPts[3]-wPts[0];
CVector3D pt=wPts[0]+(vdx*dx)+(vdz*dz);
// copy origin
origin=camera.m_Orientation.GetTranslation();
// build direction
dir=pt-origin;
dir.Normalize();
}
void CBrushTool::OnMouseMove(unsigned int flags,int px,int py)
{
// build camera ray
CVector3D rayorigin,raydir;
BuildCameraRay(px,py,rayorigin,raydir);
// intersect with terrain
CVector3D ipt;
CHFTracer hftracer(g_Terrain.GetHeightMap(),g_Terrain.GetVerticesPerSide(),float(CELL_SIZE),HEIGHT_SCALE);
if (hftracer.RayIntersect(rayorigin,raydir,m_SelectionCentre[0],m_SelectionCentre[1],m_SelectionPoint)) {
// drag trigger supported?
if (SupportDragTrigger()) {
// yes - handle mouse button down state
if (m_LButtonDown) {
OnTriggerLeft();
} else if (m_RButtonDown) {
OnTriggerRight();
}
}
}
}
#include "BrushTool.h"
#include "UIGlobals.h"
#include "HFTracer.h"
#include "NaviCam.h"
#include "TextureManager.h"
#include "Camera.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ogl.h"
#include <list>
extern CCamera g_Camera;
extern CTerrain g_Terrain;
CBrushTool::CBrushTool() : m_BrushSize(1), m_LButtonDown(false), m_RButtonDown(false)
{
}
static void RenderTileOutline(int gx,int gz)
{
CMiniPatch* mpatch=g_Terrain.GetTile(gx,gz);
if (!mpatch) return;
u32 mapSize=g_Terrain.GetVerticesPerSide();
CVector3D V[4];
g_Terrain.CalcPosition(gx,gz,V[0]);
g_Terrain.CalcPosition(gx+1,gz,V[1]);
g_Terrain.CalcPosition(gx+1,gz+1,V[2]);
g_Terrain.CalcPosition(gx,gz+1,V[3]);
glLineWidth(2);
glColor4f(0.05f,0.95f,0.1f,0.75f);
glBegin (GL_LINE_LOOP);
for(int i = 0; i < 4; i++)
glVertex3fv(&V[i].X);
glEnd ();
glColor4f (0.1f,0.9f,0.15f,0.35f);
glBegin (GL_QUADS);
for(i = 0; i < 4; i++)
glVertex3fv(&V[i].X);
glEnd ();
}
void CBrushTool::OnDraw()
{
glActiveTexture (GL_TEXTURE0);
glDisable (GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(0);
int r=m_BrushSize;
// iterate through selected patches
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
RenderTileOutline(i,j);
}
}
glDepthMask(1);
glDisable(GL_BLEND);
}
void CBrushTool::OnLButtonDown(unsigned int flags,int px,int py)
{
m_LButtonDown=true;
OnTriggerLeft();
}
void CBrushTool::OnLButtonUp(unsigned int flags,int px,int py)
{
m_LButtonDown=false;
}
void CBrushTool::OnRButtonDown(unsigned int flags,int px,int py)
{
m_RButtonDown=true;
OnTriggerRight();
}
void CBrushTool::OnRButtonUp(unsigned int flags,int px,int py)
{
m_RButtonDown=false;
}
/////////////////////////////////////////////////////////////////////////////////////////
// BuildCameraRay: calculate origin and ray direction of a ray through
// the pixel (px,py) on the screen
void CBrushTool::BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir)
{
// get points on far plane of frustum in camera space
CCamera& camera=g_NaviCam.GetCamera();
CVector3D cPts[4];
camera.GetCameraPlanePoints(camera.GetFarPlane(),cPts);
// transform to world space
CVector3D wPts[4];
for (int i=0;i<4;i++) {
wPts[i]=camera.m_Orientation.Transform(cPts[i]);
}
// get world space position of mouse point
float dx=float(px)/float(g_Renderer.GetWidth());
float dz=1-float(py)/float(g_Renderer.GetHeight());
CVector3D vdx=wPts[1]-wPts[0];
CVector3D vdz=wPts[3]-wPts[0];
CVector3D pt=wPts[0]+(vdx*dx)+(vdz*dz);
// copy origin
origin=camera.m_Orientation.GetTranslation();
// build direction
dir=pt-origin;
dir.Normalize();
}
void CBrushTool::OnMouseMove(unsigned int flags,int px,int py)
{
// build camera ray
CVector3D rayorigin,raydir;
BuildCameraRay(px,py,rayorigin,raydir);
// intersect with terrain
CVector3D ipt;
CHFTracer hftracer(g_Terrain.GetHeightMap(),g_Terrain.GetVerticesPerSide(),float(CELL_SIZE),HEIGHT_SCALE);
if (hftracer.RayIntersect(rayorigin,raydir,m_SelectionCentre[0],m_SelectionCentre[1],m_SelectionPoint)) {
// drag trigger supported?
if (SupportDragTrigger()) {
// yes - handle mouse button down state
if (m_LButtonDown) {
OnTriggerLeft();
} else if (m_RButtonDown) {
OnTriggerRight();
}
}
}
}

View File

@ -1,64 +1,64 @@
#ifndef _BRUSHTOOL_H
#define _BRUSHTOOL_H
#include "res/res.h"
#include "Tool.h"
#include "Vector3D.h"
class CPatch;
class CMiniPatch;
class CBrushTool : public CTool
{
public:
CBrushTool();
// draw the visual representation of this tool
virtual void OnDraw();
// callback for left button down event
virtual void OnLButtonDown(unsigned int flags,int px,int py);
// callback for left button up event
virtual void OnLButtonUp(unsigned int flags,int px,int py);
// callback for right button down event
virtual void OnRButtonDown(unsigned int flags,int px,int py);
// callback for right button up event
virtual void OnRButtonUp(unsigned int flags,int px,int py);
// callback for mouse move event
virtual void OnMouseMove(unsigned int flags,int px,int py);
// action to take when tool is triggered via left mouse, or left mouse + drag
virtual void OnTriggerLeft() {};
// action to take when tool is triggered via right mouse, or right mouse + drag
virtual void OnTriggerRight() {};
// set current brush size
void SetBrushSize(int size) { m_BrushSize=size; }
// get current brush size
int GetBrushSize() { return m_BrushSize; }
// virtual function: allow multiple triggers by click and drag? - else requires individual clicks
// to invoke trigger .. default to off
virtual bool SupportDragTrigger() { return false; }
protected:
// build camera ray through screen point (px,py)
void BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir);
// return true if given tile is on border of selection, false otherwise
bool IsBorderSelection(int gx,int gz);
// return true if given tile is a neighbour of the a border of selection, false otherwise
bool IsNeighbourSelection(int gx,int gz);
// build a selection of the given radius around the given minipatch
void BuildSelection(int radius,CPatch* patch,CMiniPatch* minipatch);
// left mouse button currently down?
bool m_LButtonDown;
// right mouse button currently down?
bool m_RButtonDown;
// current tool brush size
int m_BrushSize;
// centre of current selection
int m_SelectionCentre[2];
// world space "projection" of mouse point - somewhere in the m_SelectionCentre tile
CVector3D m_SelectionPoint;
};
#endif
#ifndef _BRUSHTOOL_H
#define _BRUSHTOOL_H
#include "res/res.h"
#include "Tool.h"
#include "Vector3D.h"
class CPatch;
class CMiniPatch;
class CBrushTool : public CTool
{
public:
CBrushTool();
// draw the visual representation of this tool
virtual void OnDraw();
// callback for left button down event
virtual void OnLButtonDown(unsigned int flags,int px,int py);
// callback for left button up event
virtual void OnLButtonUp(unsigned int flags,int px,int py);
// callback for right button down event
virtual void OnRButtonDown(unsigned int flags,int px,int py);
// callback for right button up event
virtual void OnRButtonUp(unsigned int flags,int px,int py);
// callback for mouse move event
virtual void OnMouseMove(unsigned int flags,int px,int py);
// action to take when tool is triggered via left mouse, or left mouse + drag
virtual void OnTriggerLeft() {};
// action to take when tool is triggered via right mouse, or right mouse + drag
virtual void OnTriggerRight() {};
// set current brush size
void SetBrushSize(int size) { m_BrushSize=size; }
// get current brush size
int GetBrushSize() { return m_BrushSize; }
// virtual function: allow multiple triggers by click and drag? - else requires individual clicks
// to invoke trigger .. default to off
virtual bool SupportDragTrigger() { return false; }
protected:
// build camera ray through screen point (px,py)
void BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir);
// return true if given tile is on border of selection, false otherwise
bool IsBorderSelection(int gx,int gz);
// return true if given tile is a neighbour of the a border of selection, false otherwise
bool IsNeighbourSelection(int gx,int gz);
// build a selection of the given radius around the given minipatch
void BuildSelection(int radius,CPatch* patch,CMiniPatch* minipatch);
// left mouse button currently down?
bool m_LButtonDown;
// right mouse button currently down?
bool m_RButtonDown;
// current tool brush size
int m_BrushSize;
// centre of current selection
int m_SelectionCentre[2];
// world space "projection" of mouse point - somewhere in the m_SelectionCentre tile
CVector3D m_SelectionPoint;
};
#endif

View File

@ -1,56 +1,56 @@
// ColorButton.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "ColorButton.h"
/////////////////////////////////////////////////////////////////////////////
// CColorButton
CColorButton::CColorButton() : m_Color(0)
{
}
CColorButton::~CColorButton()
{
}
BEGIN_MESSAGE_MAP(CColorButton, CButton)
//{{AFX_MSG_MAP(CColorButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CColorButton message handlers
void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// draw button edges
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
// deflate the drawing rect by the size of the button's edges
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
// fill the interior color
pDC->FillSolidRect(rect,m_Color);
}
void CColorButton::OnClicked()
{
CColorDialog dlg;
if (dlg.DoModal()==IDOK) {
// store color in button
m_Color=dlg.m_cc.rgbResult;
// force redraw
Invalidate();
UpdateWindow();
}
}
// ColorButton.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "ColorButton.h"
/////////////////////////////////////////////////////////////////////////////
// CColorButton
CColorButton::CColorButton() : m_Color(0)
{
}
CColorButton::~CColorButton()
{
}
BEGIN_MESSAGE_MAP(CColorButton, CButton)
//{{AFX_MSG_MAP(CColorButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CColorButton message handlers
void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// draw button edges
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
// deflate the drawing rect by the size of the button's edges
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
// fill the interior color
pDC->FillSolidRect(rect,m_Color);
}
void CColorButton::OnClicked()
{
CColorDialog dlg;
if (dlg.DoModal()==IDOK) {
// store color in button
m_Color=dlg.m_cc.rgbResult;
// force redraw
Invalidate();
UpdateWindow();
}
}

View File

@ -1,77 +1,77 @@
#if !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
#define AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ColorButton.h : header file
//
#include "Color.h"
inline void ColorRefToRGBColor(COLORREF c,RGBColor& result)
{
result.X=(c & 0xff)/255.0f;
result.Y=((c>>8) & 0xff)/255.0f;
result.Z=((c>>16) & 0xff)/255.0f;
}
inline void RGBColorToColorRef(const RGBColor& c,COLORREF& result)
{
int r=int(c.X*255);
if (r<0) r=0;
if (r>255) r=255;
int g=int(c.Y*255);
if (g<0) g=0;
if (g>255) g=255;
int b=int(c.Z*255);
if (b<0) b=0;
if (b>255) b=255;
result=r | (g<<8) | (b<<16);
}
/////////////////////////////////////////////////////////////////////////////
// CColorButton window
class CColorButton : public CButton
{
// Construction
public:
CColorButton();
// Attributes
public:
COLORREF m_Color;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CColorButton();
// Generated message map functions
protected:
//{{AFX_MSG(CColorButton)
afx_msg void OnClicked();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
#if !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
#define AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ColorButton.h : header file
//
#include "Color.h"
inline void ColorRefToRGBColor(COLORREF c,RGBColor& result)
{
result.X=(c & 0xff)/255.0f;
result.Y=((c>>8) & 0xff)/255.0f;
result.Z=((c>>16) & 0xff)/255.0f;
}
inline void RGBColorToColorRef(const RGBColor& c,COLORREF& result)
{
int r=int(c.X*255);
if (r<0) r=0;
if (r>255) r=255;
int g=int(c.Y*255);
if (g<0) g=0;
if (g>255) g=255;
int b=int(c.Z*255);
if (b<0) b=0;
if (b>255) b=255;
result=r | (g<<8) | (b<<16);
}
/////////////////////////////////////////////////////////////////////////////
// CColorButton window
class CColorButton : public CButton
{
// Construction
public:
CColorButton();
// Attributes
public:
COLORREF m_Color;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CColorButton();
// Generated message map functions
protected:
//{{AFX_MSG(CColorButton)
afx_msg void OnClicked();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)

View File

@ -1,24 +1,24 @@
#ifndef _COMMAND_H
#define _COMMAND_H
class CCommand
{
public:
// virtual destructor
virtual ~CCommand() {}
// return the texture name of this command
virtual const char* GetName() const { return 0; }
// execute this command
virtual void Execute() = 0;
// can undo command?
virtual bool IsUndoable() const = 0;
// undo
virtual void Undo() {}
// redo
virtual void Redo() {}
};
#endif
#ifndef _COMMAND_H
#define _COMMAND_H
class CCommand
{
public:
// virtual destructor
virtual ~CCommand() {}
// return the texture name of this command
virtual const char* GetName() const { return 0; }
// execute this command
virtual void Execute() = 0;
// can undo command?
virtual bool IsUndoable() const = 0;
// undo
virtual void Undo() {}
// redo
virtual void Redo() {}
};
#endif

View File

@ -1,127 +1,127 @@
#include "Command.h"
#include "CommandManager.h"
CCommandManager g_CmdMan;
CCommandManager::CCommandManager() : m_CommandHistoryLength(128), m_HistoryPos(-1)
{
}
CCommandManager::~CCommandManager()
{
ClearHistory();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Append: add given command to the end of the history list, without
// executing it
void CCommandManager::Append(CCommand* cmd)
{
if (cmd->IsUndoable()) {
// remove all existing commands from current position to end
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
for (CommandList::iterator i=iter;i!=m_CommandHistory.end();++i) {
delete *i;
}
m_CommandHistory.erase(iter,m_CommandHistory.end());
// add new command to end
m_CommandHistory.push_back(cmd);
// check for history that's too big
if (m_CommandHistory.size()>m_CommandHistoryLength) {
CCommand* cmd=m_CommandHistory.front();
m_CommandHistory.pop_front();
delete cmd;
}
// update history position to point at last command executed
m_HistoryPos=m_CommandHistory.size()-1;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Execute: execute the given command, then add it to the end of the history list
void CCommandManager::Execute(CCommand* cmd)
{
cmd->Execute();
Append(cmd);
}
CCommandManager::CommandList::iterator CCommandManager::GetIterator(int pos)
{
if (pos<0 || uint(pos)>=m_CommandHistory.size()) return m_CommandHistory.end();
typedef CommandList::iterator Iter;
int count=0;
for (Iter iter=m_CommandHistory.begin();iter!=m_CommandHistory.end();++iter) {
if (count==pos) {
return iter;
}
count++;
}
// hmm .. shouldn't get here
return m_CommandHistory.end();
}
CCommand* CCommandManager::GetUndoCommand()
{
CommandList::iterator iter=GetIterator(m_HistoryPos);
if (iter!=m_CommandHistory.end()) {
return *iter;
} else {
return 0;
}
}
void CCommandManager::Undo()
{
CCommand* cmd=GetUndoCommand();
if (cmd) {
cmd->Undo();
m_HistoryPos--;
}
}
const char* CCommandManager::GetUndoName()
{
CCommand* cmd=GetUndoCommand();
return cmd ? cmd->GetName() : 0;
}
CCommand* CCommandManager::GetRedoCommand()
{
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
if (iter!=m_CommandHistory.end()) {
return *iter;
} else {
return 0;
}
}
void CCommandManager::Redo()
{
CCommand* cmd=GetRedoCommand();
if (cmd) {
cmd->Redo();
m_HistoryPos++;
}
}
const char* CCommandManager::GetRedoName()
{
CCommand* cmd=GetRedoCommand();
return cmd ? cmd->GetName() : 0;
}
void CCommandManager::ClearHistory()
{
// empty out command history
while (m_CommandHistory.size()>0) {
CCommand* cmd=m_CommandHistory.front();
m_CommandHistory.pop_front();
delete cmd;
}
}
#include "Command.h"
#include "CommandManager.h"
CCommandManager g_CmdMan;
CCommandManager::CCommandManager() : m_CommandHistoryLength(128), m_HistoryPos(-1)
{
}
CCommandManager::~CCommandManager()
{
ClearHistory();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Append: add given command to the end of the history list, without
// executing it
void CCommandManager::Append(CCommand* cmd)
{
if (cmd->IsUndoable()) {
// remove all existing commands from current position to end
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
for (CommandList::iterator i=iter;i!=m_CommandHistory.end();++i) {
delete *i;
}
m_CommandHistory.erase(iter,m_CommandHistory.end());
// add new command to end
m_CommandHistory.push_back(cmd);
// check for history that's too big
if (m_CommandHistory.size()>m_CommandHistoryLength) {
CCommand* cmd=m_CommandHistory.front();
m_CommandHistory.pop_front();
delete cmd;
}
// update history position to point at last command executed
m_HistoryPos=m_CommandHistory.size()-1;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Execute: execute the given command, then add it to the end of the history list
void CCommandManager::Execute(CCommand* cmd)
{
cmd->Execute();
Append(cmd);
}
CCommandManager::CommandList::iterator CCommandManager::GetIterator(int pos)
{
if (pos<0 || uint(pos)>=m_CommandHistory.size()) return m_CommandHistory.end();
typedef CommandList::iterator Iter;
int count=0;
for (Iter iter=m_CommandHistory.begin();iter!=m_CommandHistory.end();++iter) {
if (count==pos) {
return iter;
}
count++;
}
// hmm .. shouldn't get here
return m_CommandHistory.end();
}
CCommand* CCommandManager::GetUndoCommand()
{
CommandList::iterator iter=GetIterator(m_HistoryPos);
if (iter!=m_CommandHistory.end()) {
return *iter;
} else {
return 0;
}
}
void CCommandManager::Undo()
{
CCommand* cmd=GetUndoCommand();
if (cmd) {
cmd->Undo();
m_HistoryPos--;
}
}
const char* CCommandManager::GetUndoName()
{
CCommand* cmd=GetUndoCommand();
return cmd ? cmd->GetName() : 0;
}
CCommand* CCommandManager::GetRedoCommand()
{
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
if (iter!=m_CommandHistory.end()) {
return *iter;
} else {
return 0;
}
}
void CCommandManager::Redo()
{
CCommand* cmd=GetRedoCommand();
if (cmd) {
cmd->Redo();
m_HistoryPos++;
}
}
const char* CCommandManager::GetRedoName()
{
CCommand* cmd=GetRedoCommand();
return cmd ? cmd->GetName() : 0;
}
void CCommandManager::ClearHistory()
{
// empty out command history
while (m_CommandHistory.size()>0) {
CCommand* cmd=m_CommandHistory.front();
m_CommandHistory.pop_front();
delete cmd;
}
}

View File

@ -1,39 +1,39 @@
#ifndef _COMMANDMANAGER_H
#define _COMMANDMANAGER_H
class CCommand;
#include <list>
#include "res/res.h"
class CCommandManager
{
public:
CCommandManager();
~CCommandManager();
void Append(CCommand* cmd);
void Execute(CCommand* cmd);
void Undo();
const char* GetUndoName();
void Redo();
const char* GetRedoName();
void ClearHistory();
private:
typedef std::list<CCommand*> CommandList;
CommandList::iterator GetIterator(int pos);
CCommand* GetUndoCommand();
CCommand* GetRedoCommand();
i32 m_HistoryPos;
u32 m_CommandHistoryLength;
CommandList m_CommandHistory;
};
extern CCommandManager g_CmdMan;
#endif
#ifndef _COMMANDMANAGER_H
#define _COMMANDMANAGER_H
class CCommand;
#include <list>
#include "res/res.h"
class CCommandManager
{
public:
CCommandManager();
~CCommandManager();
void Append(CCommand* cmd);
void Execute(CCommand* cmd);
void Undo();
const char* GetUndoName();
void Redo();
const char* GetRedoName();
void ClearHistory();
private:
typedef std::list<CCommand*> CommandList;
CommandList::iterator GetIterator(int pos);
CCommand* GetUndoCommand();
CCommand* GetRedoCommand();
i32 m_HistoryPos;
u32 m_CommandHistoryLength;
CommandList m_CommandHistory;
};
extern CCommandManager g_CmdMan;
#endif

View File

@ -1,96 +1,96 @@
// DirectionButton.cpp : implementation file
//
#include <math.h>
#include "stdafx.h"
#include "ScEd.h"
#include "DirectionButton.h"
#include "MathUtil.h"
/////////////////////////////////////////////////////////////////////////////
// CDirectionButton
CDirectionButton::CDirectionButton() : m_Direction(0)
{
}
CDirectionButton::~CDirectionButton()
{
}
BEGIN_MESSAGE_MAP(CDirectionButton, CButton)
//{{AFX_MSG_MAP(CDirectionButton)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDirectionButton message handlers
void CDirectionButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// draw button edges
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
// deflate the drawing rect by the size of the button's edges
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
// fill the interior color
pDC->FillSolidRect(rect,RGB(0,0,0));
// shrink rect before drawing anything else
rect.DeflateRect(15,15);
// create a hollow brush
CBrush brush;
brush.CreateStockObject(HOLLOW_BRUSH);
CBrush* oldbrush=pDC->SelectObject(&brush);
// draw circle
pDC->SetROP2(R2_WHITE);
pDC->Ellipse(&rect);
// draw direction arrow
pDC->SetROP2(R2_COPYPEN);
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* oldpen=pDC->SelectObject(&pen);
float cx=float(rect.bottom+rect.top)/2.0f;
float cy=float(rect.bottom+rect.top)/2.0f;
float dy=float(rect.bottom-rect.top)/2.0f;
float dx=float(rect.right-rect.left)/2.0f;
float r=(float) sqrt(dx*dx+dy*dy);
float dirx=sin(DEGTORAD(m_Direction));
float diry=cos(DEGTORAD(m_Direction));
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
double slopy , cosy , siny;
double Par = 6.5; //length of Arrow (>)
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
cosy = cos( slopy );
siny = sin( slopy ); //need math.h for these functions
//draw a line between the 2 endpoint
pDC->MoveTo( m_One );
pDC->LineTo( m_Two );
pDC->MoveTo( m_Two );
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
pDC->LineTo( m_Two );
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
}
// DirectionButton.cpp : implementation file
//
#include <math.h>
#include "stdafx.h"
#include "ScEd.h"
#include "DirectionButton.h"
#include "MathUtil.h"
/////////////////////////////////////////////////////////////////////////////
// CDirectionButton
CDirectionButton::CDirectionButton() : m_Direction(0)
{
}
CDirectionButton::~CDirectionButton()
{
}
BEGIN_MESSAGE_MAP(CDirectionButton, CButton)
//{{AFX_MSG_MAP(CDirectionButton)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDirectionButton message handlers
void CDirectionButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// draw button edges
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
// deflate the drawing rect by the size of the button's edges
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
// fill the interior color
pDC->FillSolidRect(rect,RGB(0,0,0));
// shrink rect before drawing anything else
rect.DeflateRect(15,15);
// create a hollow brush
CBrush brush;
brush.CreateStockObject(HOLLOW_BRUSH);
CBrush* oldbrush=pDC->SelectObject(&brush);
// draw circle
pDC->SetROP2(R2_WHITE);
pDC->Ellipse(&rect);
// draw direction arrow
pDC->SetROP2(R2_COPYPEN);
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* oldpen=pDC->SelectObject(&pen);
float cx=float(rect.bottom+rect.top)/2.0f;
float cy=float(rect.bottom+rect.top)/2.0f;
float dy=float(rect.bottom-rect.top)/2.0f;
float dx=float(rect.right-rect.left)/2.0f;
float r=(float) sqrt(dx*dx+dy*dy);
float dirx=sin(DEGTORAD(m_Direction));
float diry=cos(DEGTORAD(m_Direction));
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
double slopy , cosy , siny;
double Par = 6.5; //length of Arrow (>)
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
cosy = cos( slopy );
siny = sin( slopy ); //need math.h for these functions
//draw a line between the 2 endpoint
pDC->MoveTo( m_One );
pDC->LineTo( m_Two );
pDC->MoveTo( m_Two );
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
pDC->LineTo( m_Two );
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
}

View File

@ -1,51 +1,51 @@
#if !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
#define AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DirectionButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CDirectionButton window
class CDirectionButton : public CButton
{
// Construction
public:
CDirectionButton();
// Attributes
public:
float m_Direction;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDirectionButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDirectionButton();
// Generated message map functions
protected:
//{{AFX_MSG(CDirectionButton)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
#if !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
#define AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DirectionButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CDirectionButton window
class CDirectionButton : public CButton
{
// Construction
public:
CDirectionButton();
// Attributes
public:
float m_Direction;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDirectionButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDirectionButton();
// Generated message map functions
protected:
//{{AFX_MSG(CDirectionButton)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +1,82 @@
#ifndef _EDITORDATA_H
#define _EDITORDATA_H
#include "MiniMap.h"
#include "InfoBox.h"
#include "PaintTextureTool.h"
#include "NaviCam.h"
#include "CStr.h"
#include "Terrain.h"
#include "Renderer.h"
#include "Camera.h"
#include "LightEnv.h"
class CEditorData
{
public:
enum EditMode { SCENARIO_EDIT, UNIT_EDIT, BRUSH_EDIT, TEST_MODE };
public:
CEditorData();
void SetMode(EditMode mode);
EditMode GetMode() const { return m_Mode; }
// initialise editor at given width, height and bpp
bool Init();
void Terminate();
void OnCameraChanged();
void OnDraw();
void OnScreenShot(const char* filename);
CInfoBox& GetInfoBox() { return m_InfoBox; }
// terrain plane
CPlane m_TerrainPlane;
// set the scenario name
void SetScenarioName(const char* name) { m_ScenarioName=name; }
// get the scenario name
const char* GetScenarioName() const { return (const char*) m_ScenarioName; }
bool LoadTerrain(const char* filename);
// update time dependent data in the world to account for changes over
// the given time (in ms)
void UpdateWorld(float time);
void RenderNoCull();
private:
bool InitScene();
void LoadAlphaMaps();
void InitResources();
void InitCamera();
void RenderTerrain();
void RenderModels();
void RenderWorld();
void RenderObEdGrid();
void InitSingletons();
void StartTestMode();
void StopTestMode();
// current editing mode
EditMode m_Mode;
// camera to use in object viewing mode
CCamera m_ObjectCamera;
// transform of model in object viewing mode
CMatrix3D m_ModelMatrix;
// information panel
CInfoBox m_InfoBox;
// the (short) name of this scenario used in title bar and as default save name
CStr m_ScenarioName;
};
extern CEditorData g_EditorData;
extern CTerrain g_Terrain;
extern CLightEnv g_LightEnv;
#endif
#ifndef _EDITORDATA_H
#define _EDITORDATA_H
#include "MiniMap.h"
#include "InfoBox.h"
#include "PaintTextureTool.h"
#include "NaviCam.h"
#include "CStr.h"
#include "Terrain.h"
#include "Renderer.h"
#include "Camera.h"
#include "LightEnv.h"
class CEditorData
{
public:
enum EditMode { SCENARIO_EDIT, UNIT_EDIT, BRUSH_EDIT, TEST_MODE };
public:
CEditorData();
void SetMode(EditMode mode);
EditMode GetMode() const { return m_Mode; }
// initialise editor at given width, height and bpp
bool Init();
void Terminate();
void OnCameraChanged();
void OnDraw();
void OnScreenShot(const char* filename);
CInfoBox& GetInfoBox() { return m_InfoBox; }
// terrain plane
CPlane m_TerrainPlane;
// set the scenario name
void SetScenarioName(const char* name) { m_ScenarioName=name; }
// get the scenario name
const char* GetScenarioName() const { return (const char*) m_ScenarioName; }
bool LoadTerrain(const char* filename);
// update time dependent data in the world to account for changes over
// the given time (in ms)
void UpdateWorld(float time);
void RenderNoCull();
private:
bool InitScene();
void LoadAlphaMaps();
void InitResources();
void InitCamera();
void RenderTerrain();
void RenderModels();
void RenderWorld();
void RenderObEdGrid();
void InitSingletons();
void StartTestMode();
void StopTestMode();
// current editing mode
EditMode m_Mode;
// camera to use in object viewing mode
CCamera m_ObjectCamera;
// transform of model in object viewing mode
CMatrix3D m_ModelMatrix;
// information panel
CInfoBox m_InfoBox;
// the (short) name of this scenario used in title bar and as default save name
CStr m_ScenarioName;
};
extern CEditorData g_EditorData;
extern CTerrain g_Terrain;
extern CLightEnv g_LightEnv;
#endif

View File

@ -1,187 +1,187 @@
#include "stdafx.h"
#include "ToolManager.h"
#include "ElevToolsDlgBar.h"
#include "RaiseElevationTool.h"
#include "SmoothElevationTool.h"
#include "UIGlobals.h"
BEGIN_MESSAGE_MAP(CElevToolsDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CElevToolsDlgBar)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_RADIO_RAISE, OnRadioRaise)
ON_BN_CLICKED(IDC_RADIO_SMOOTH, OnRadioSmooth)
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHEFFECT, OnReleasedCaptureSliderBrushEffect)
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
END_MESSAGE_MAP()
CElevToolsDlgBar::CElevToolsDlgBar() : m_Mode(RAISELOWER_MODE)
{
}
CElevToolsDlgBar::~CElevToolsDlgBar()
{
}
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
{
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
return FALSE;
}
if (!OnInitDialog()) {
return FALSE;
}
return TRUE;
}
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
{
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
return FALSE;
}
return TRUE;
}
void CElevToolsDlgBar::SetRaiseControls()
{
// set up brush size slider
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizectrl->SetRange(0,CRaiseElevationTool::MAX_BRUSH_SIZE,TRUE);
sizectrl->SetPos(CRaiseElevationTool::GetTool()->GetBrushSize());
// set up brush effect slider
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectctrl->SetRange(1,CRaiseElevationTool::MAX_SPEED/16,TRUE);
effectctrl->SetPos(CRaiseElevationTool::GetTool()->GetSpeed()/16);
// setup radio buttons
CheckDlgButton(IDC_RADIO_RAISE,TRUE);
CheckDlgButton(IDC_RADIO_SMOOTH,FALSE);
}
void CElevToolsDlgBar::SetSmoothControls()
{
// set up brush size slider
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizectrl->SetRange(0,CSmoothElevationTool::MAX_BRUSH_SIZE,TRUE);
sizectrl->SetPos(CSmoothElevationTool::GetTool()->GetBrushSize());
// set up brush effect slider
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectctrl->SetRange(1,int(CSmoothElevationTool::MAX_SMOOTH_POWER),TRUE);
effectctrl->SetPos(int(CSmoothElevationTool::GetTool()->GetSmoothPower()));
// setup radio buttons
CheckDlgButton(IDC_RADIO_RAISE,FALSE);
CheckDlgButton(IDC_RADIO_SMOOTH,TRUE);
}
BOOL CElevToolsDlgBar::OnInitDialog()
{
// get the current window size and position
CRect rect;
GetWindowRect(rect);
// now change the size, position, and Z order of the window.
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
// initially show raise controls
SetRaiseControls();
return TRUE;
}
void CElevToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
bDisableIfNoHndler = FALSE;
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
}
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
{
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
CRaiseElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
} else {
CSmoothElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
}
*pResult = 0;
}
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult)
{
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
CRaiseElevationTool::GetTool()->SetSpeed(sliderctrl->GetPos()*16);
} else {
CSmoothElevationTool::GetTool()->SetSmoothPower(float(sliderctrl->GetPos()));
}
*pResult = 0;
}
void CElevToolsDlgBar::OnShow()
{
switch (m_Mode) {
case RAISELOWER_MODE:
SetRaiseControls();
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
break;
case SMOOTH_MODE:
SetSmoothControls();
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
break;
default:
assert(0);
}
}
void CElevToolsDlgBar::OnRadioRaise()
{
// set UI elements for raise/lower
SetRaiseControls();
// set current tool
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
// redraw sliders
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizeslider->Invalidate();
sizeslider->UpdateWindow();
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectslider->Invalidate();
effectslider->UpdateWindow();
// store mode
m_Mode=RAISELOWER_MODE;
}
void CElevToolsDlgBar::OnRadioSmooth()
{
// set UI elements for smooth
SetSmoothControls();
// set current tool
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
// redraw sliders
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizeslider->Invalidate();
sizeslider->UpdateWindow();
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectslider->Invalidate();
effectslider->UpdateWindow();
// store mode
m_Mode=SMOOTH_MODE;
}
#include "stdafx.h"
#include "ToolManager.h"
#include "ElevToolsDlgBar.h"
#include "RaiseElevationTool.h"
#include "SmoothElevationTool.h"
#include "UIGlobals.h"
BEGIN_MESSAGE_MAP(CElevToolsDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CElevToolsDlgBar)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_RADIO_RAISE, OnRadioRaise)
ON_BN_CLICKED(IDC_RADIO_SMOOTH, OnRadioSmooth)
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHEFFECT, OnReleasedCaptureSliderBrushEffect)
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
END_MESSAGE_MAP()
CElevToolsDlgBar::CElevToolsDlgBar() : m_Mode(RAISELOWER_MODE)
{
}
CElevToolsDlgBar::~CElevToolsDlgBar()
{
}
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
{
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
return FALSE;
}
if (!OnInitDialog()) {
return FALSE;
}
return TRUE;
}
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
{
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
return FALSE;
}
return TRUE;
}
void CElevToolsDlgBar::SetRaiseControls()
{
// set up brush size slider
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizectrl->SetRange(0,CRaiseElevationTool::MAX_BRUSH_SIZE,TRUE);
sizectrl->SetPos(CRaiseElevationTool::GetTool()->GetBrushSize());
// set up brush effect slider
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectctrl->SetRange(1,CRaiseElevationTool::MAX_SPEED/16,TRUE);
effectctrl->SetPos(CRaiseElevationTool::GetTool()->GetSpeed()/16);
// setup radio buttons
CheckDlgButton(IDC_RADIO_RAISE,TRUE);
CheckDlgButton(IDC_RADIO_SMOOTH,FALSE);
}
void CElevToolsDlgBar::SetSmoothControls()
{
// set up brush size slider
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizectrl->SetRange(0,CSmoothElevationTool::MAX_BRUSH_SIZE,TRUE);
sizectrl->SetPos(CSmoothElevationTool::GetTool()->GetBrushSize());
// set up brush effect slider
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectctrl->SetRange(1,int(CSmoothElevationTool::MAX_SMOOTH_POWER),TRUE);
effectctrl->SetPos(int(CSmoothElevationTool::GetTool()->GetSmoothPower()));
// setup radio buttons
CheckDlgButton(IDC_RADIO_RAISE,FALSE);
CheckDlgButton(IDC_RADIO_SMOOTH,TRUE);
}
BOOL CElevToolsDlgBar::OnInitDialog()
{
// get the current window size and position
CRect rect;
GetWindowRect(rect);
// now change the size, position, and Z order of the window.
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
// initially show raise controls
SetRaiseControls();
return TRUE;
}
void CElevToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
bDisableIfNoHndler = FALSE;
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
}
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
{
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
CRaiseElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
} else {
CSmoothElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
}
*pResult = 0;
}
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult)
{
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
CRaiseElevationTool::GetTool()->SetSpeed(sliderctrl->GetPos()*16);
} else {
CSmoothElevationTool::GetTool()->SetSmoothPower(float(sliderctrl->GetPos()));
}
*pResult = 0;
}
void CElevToolsDlgBar::OnShow()
{
switch (m_Mode) {
case RAISELOWER_MODE:
SetRaiseControls();
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
break;
case SMOOTH_MODE:
SetSmoothControls();
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
break;
default:
assert(0);
}
}
void CElevToolsDlgBar::OnRadioRaise()
{
// set UI elements for raise/lower
SetRaiseControls();
// set current tool
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
// redraw sliders
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizeslider->Invalidate();
sizeslider->UpdateWindow();
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectslider->Invalidate();
effectslider->UpdateWindow();
// store mode
m_Mode=RAISELOWER_MODE;
}
void CElevToolsDlgBar::OnRadioSmooth()
{
// set UI elements for smooth
SetSmoothControls();
// set current tool
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
// redraw sliders
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
sizeslider->Invalidate();
sizeslider->UpdateWindow();
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
effectslider->Invalidate();
effectslider->UpdateWindow();
// store mode
m_Mode=SMOOTH_MODE;
}

View File

@ -1,38 +1,38 @@
#ifndef _ELEVTOOLSDLGBAR_H
#define _ELEVTOOLSDLGBAR_H
class CElevToolsDlgBar : public CDialogBar
{
public:
enum Mode { RAISELOWER_MODE, SMOOTH_MODE };
CElevToolsDlgBar();
~CElevToolsDlgBar();
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
void OnShow();
protected:
BOOL OnInitDialog();
void SetRaiseControls();
void SetSmoothControls();
// current operating mode
Mode m_Mode;
// Generated message map functions
//{{AFX_MSG(CElevToolsDlgBar)
afx_msg void OnRadioRaise();
afx_msg void OnRadioSmooth();
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
#ifndef _ELEVTOOLSDLGBAR_H
#define _ELEVTOOLSDLGBAR_H
class CElevToolsDlgBar : public CDialogBar
{
public:
enum Mode { RAISELOWER_MODE, SMOOTH_MODE };
CElevToolsDlgBar();
~CElevToolsDlgBar();
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
void OnShow();
protected:
BOOL OnInitDialog();
void SetRaiseControls();
void SetSmoothControls();
// current operating mode
Mode m_Mode;
// Generated message map functions
//{{AFX_MSG(CElevToolsDlgBar)
afx_msg void OnRadioRaise();
afx_msg void OnRadioSmooth();
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif

View File

@ -1,98 +1,98 @@
// ElevationButton.cpp : implementation file
//
#include <math.h>
#include "stdafx.h"
#include "ScEd.h"
#include "ElevationButton.h"
#include "MathUtil.h"
/////////////////////////////////////////////////////////////////////////////
// CElevationButton
CElevationButton::CElevationButton() : m_Elevation(45)
{
}
CElevationButton::~CElevationButton()
{
}
BEGIN_MESSAGE_MAP(CElevationButton, CButton)
//{{AFX_MSG_MAP(CElevationButton)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CElevationButton message handlers
void CElevationButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// draw button edges
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
// deflate the drawing rect by the size of the button's edges
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
// fill the interior color
pDC->FillSolidRect(rect,RGB(0,0,0));
// shrink rect before drawing anything else
rect.DeflateRect(15,5);
// create a hollow brush
CBrush brush;
brush.CreateStockObject(HOLLOW_BRUSH);
CBrush* oldbrush=pDC->SelectObject(&brush);
// draw horizon
pDC->SetROP2(R2_WHITE);
pDC->MoveTo(rect.left,rect.bottom);
pDC->LineTo(rect.right,rect.bottom);
// draw direction arrow
pDC->SetROP2(R2_COPYPEN);
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* oldpen=pDC->SelectObject(&pen);
float dy=float(rect.bottom-rect.top)/2.0f;
float dx=float(rect.right-rect.left)/2.0f;
float r=(float) sqrt(2*dx*dx);
float cx=float(rect.left+rect.right)/2.0f;
float cy=float(rect.bottom);
float dirx=cos(DEGTORAD(m_Elevation));
float diry=-sin(DEGTORAD(m_Elevation));
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
double slopy , cosy , siny;
double Par = 6.5; //length of Arrow (>)
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
cosy = cos( slopy );
siny = sin( slopy ); //need math.h for these functions
//draw a line between the 2 endpoint
pDC->MoveTo( m_One );
pDC->LineTo( m_Two );
pDC->MoveTo( m_Two );
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
pDC->LineTo( m_Two );
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
}
// ElevationButton.cpp : implementation file
//
#include <math.h>
#include "stdafx.h"
#include "ScEd.h"
#include "ElevationButton.h"
#include "MathUtil.h"
/////////////////////////////////////////////////////////////////////////////
// CElevationButton
CElevationButton::CElevationButton() : m_Elevation(45)
{
}
CElevationButton::~CElevationButton()
{
}
BEGIN_MESSAGE_MAP(CElevationButton, CButton)
//{{AFX_MSG_MAP(CElevationButton)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CElevationButton message handlers
void CElevationButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// draw button edges
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
// deflate the drawing rect by the size of the button's edges
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
// fill the interior color
pDC->FillSolidRect(rect,RGB(0,0,0));
// shrink rect before drawing anything else
rect.DeflateRect(15,5);
// create a hollow brush
CBrush brush;
brush.CreateStockObject(HOLLOW_BRUSH);
CBrush* oldbrush=pDC->SelectObject(&brush);
// draw horizon
pDC->SetROP2(R2_WHITE);
pDC->MoveTo(rect.left,rect.bottom);
pDC->LineTo(rect.right,rect.bottom);
// draw direction arrow
pDC->SetROP2(R2_COPYPEN);
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* oldpen=pDC->SelectObject(&pen);
float dy=float(rect.bottom-rect.top)/2.0f;
float dx=float(rect.right-rect.left)/2.0f;
float r=(float) sqrt(2*dx*dx);
float cx=float(rect.left+rect.right)/2.0f;
float cy=float(rect.bottom);
float dirx=cos(DEGTORAD(m_Elevation));
float diry=-sin(DEGTORAD(m_Elevation));
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
double slopy , cosy , siny;
double Par = 6.5; //length of Arrow (>)
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
cosy = cos( slopy );
siny = sin( slopy ); //need math.h for these functions
//draw a line between the 2 endpoint
pDC->MoveTo( m_One );
pDC->LineTo( m_Two );
pDC->MoveTo( m_Two );
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
pDC->LineTo( m_Two );
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
}

View File

@ -1,51 +1,51 @@
#if !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
#define AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ElevationButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CElevationButton window
class CElevationButton : public CButton
{
// Construction
public:
CElevationButton();
// Attributes
public:
float m_Elevation;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CElevationButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CElevationButton();
// Generated message map functions
protected:
//{{AFX_MSG(CElevationButton)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
#if !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
#define AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ElevationButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CElevationButton window
class CElevationButton : public CButton
{
// Construction
public:
CElevationButton();
// Attributes
public:
float m_Elevation;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CElevationButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CElevationButton();
// Generated message map functions
protected:
//{{AFX_MSG(CElevationButton)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)

View File

@ -1,31 +1,31 @@
// ImageListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "ImageListCtrl.h"
/////////////////////////////////////////////////////////////////////////////
// CImageListCtrl
CImageListCtrl::CImageListCtrl()
{
}
CImageListCtrl::~CImageListCtrl()
{
}
BEGIN_MESSAGE_MAP(CImageListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CImageListCtrl)
ON_WM_DRAWITEM()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CImageListCtrl message handlers
void CImageListCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
}
// ImageListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "ImageListCtrl.h"
/////////////////////////////////////////////////////////////////////////////
// CImageListCtrl
CImageListCtrl::CImageListCtrl()
{
}
CImageListCtrl::~CImageListCtrl()
{
}
BEGIN_MESSAGE_MAP(CImageListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CImageListCtrl)
ON_WM_DRAWITEM()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CImageListCtrl message handlers
void CImageListCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
}

View File

@ -1,48 +1,48 @@
#if !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
#define AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ImageListCtrl.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CImageListCtrl window
class CImageListCtrl : public CListCtrl
{
// Construction
public:
CImageListCtrl();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CImageListCtrl)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CImageListCtrl();
// Generated message map functions
protected:
//{{AFX_MSG(CImageListCtrl)
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
#if !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
#define AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ImageListCtrl.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CImageListCtrl window
class CImageListCtrl : public CListCtrl
{
// Construction
public:
CImageListCtrl();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CImageListCtrl)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CImageListCtrl();
// Generated message map functions
protected:
//{{AFX_MSG(CImageListCtrl)
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)

View File

@ -1,241 +1,241 @@
#include "InfoBox.h"
#include "UIGlobals.h"
#include "types.h"
#include "ogl.h"
#include "timer.h"
#include "NPFont.h"
#include "NPFontManager.h"
#include "OverlayText.h"
#include "Renderer.h"
static const char* DefaultFontName="mods/official/fonts/verdana18.fnt";
CInfoBox::CInfoBox() : m_Font(0), m_Visible(false)
{
m_LastFPSTime=get_time();
m_Stats.Reset();
}
void CInfoBox::Initialise()
{
m_Font=NPFontManager::instance().add(DefaultFontName);
}
void CInfoBox::Render()
{
if (!m_Visible) return;
const u32 panelColor=0x80f9527d;
const u32 borderColor=0xfffa0043;
// setup renderstate
glDisable(GL_DEPTH_TEST);
glDepthMask(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// load identity modelview
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// setup ortho view
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
int w=g_Renderer.GetWidth();
int h=g_Renderer.GetHeight();
glOrtho(0,w,0,h,-1,1);
glColor4ubv((const GLubyte*) &panelColor);
// render infobox as quad
glBegin(GL_QUADS);
glVertex2i(3,h-180);
glVertex2i(150,h-180);
glVertex2i(150,h-2);
glVertex2i(3,h-2);
glEnd();
// render border
glColor4ubv((const GLubyte*) &borderColor);
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glVertex2i(1,h-182);
glVertex2i(152,h-182);
glVertex2i(152,h-1);
glVertex2i(1,h-1);
glEnd();
// render any info now, assuming we've got a font
if (m_Font) {
RenderInfo();
}
// restore matrices
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// restore renderstate
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthMask(1);
}
void render(COverlayText* overlaytext)
{
// get font on overlay
NPFont* font=overlaytext->GetFont();
if (!font) return;
const CStr& str=overlaytext->GetString();
int len=str.Length();
if (len==0) return;
// bind to font texture
g_Renderer.SetTexture(0,&font->texture());
// setup texenv
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
// get overlay's position
float x,y;
overlaytext->GetPosition(x,y);
// setup color
const CColor& color=overlaytext->GetColor();
glColor4fv((float*) &color);
float x0=x;
float ftw=float(font->textureWidth());
float fth=float(font->textureHeight());
float fdy=float(font->height())/fth;
// submit quad verts for each character
glBegin(GL_QUADS);
for (int i=0;i<len;i++) {
// get pointer to char widths
const NPFont::CharData& cdata=font->chardata(str[i]);
const int* cw=&cdata._widthA;
if (cw[0]>0) x0+=cw[0];
// find the tile for this character
unsigned char c0=unsigned char(str[i]-32);
int ix=c0%font->numCols();
int iy=c0/font->numCols();
// calc UV coords of character in texture
float u0=float(ix*font->maxcharwidth()+cw[0]-1)/ftw;
float v0=float(iy*(font->height()+1))/fth;
float u1=u0+float(cw[1]+1)/ftw;
float v1=v0+fdy;
glTexCoord2f(u0,v0);
glVertex2f(x0,y);
glTexCoord2f(u1,v0);
glVertex2f(x0+float(cw[1]+1),y);
glTexCoord2f(u1,v1);
glVertex2f(x0+float(cw[1]+1),y+font->height());
glTexCoord2f(u0,v1);
glVertex2f(x0,y+font->height());
// translate such that next character is rendered in correct position
x0+=float(cw[1]+1);
if (cw[2]>0) x0+=cw[2];
}
glEnd();
// unbind texture ..
g_Renderer.SetTexture(0,0);
}
void CInfoBox::RenderInfo()
{
int w=g_Renderer.GetWidth();
int h=g_Renderer.GetHeight();
char buf[32];
if (m_LastStats.m_Counter) {
u32 dy=m_Font->height()+2;
float y=float(h-dy);
sprintf(buf,"FPS: %d",int(m_LastStats.m_Counter/m_LastTickTime));
COverlayText fpstext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&fpstext);
y-=dy;
sprintf(buf,"FT: %.2f",1000*m_LastTickTime/float(m_LastStats.m_Counter));
COverlayText fttext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&fttext);
y-=dy;
u32 totalTris=m_LastStats.m_TerrainTris+m_LastStats.m_ModelTris+m_LastStats.m_TransparentTris;
sprintf(buf,"TPF: %d",int(totalTris/m_LastStats.m_Counter));
COverlayText tpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&tpftext);
y-=dy;
sprintf(buf,"TeTPF: %d",int(m_LastStats.m_TerrainTris/m_LastStats.m_Counter));
COverlayText tetpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&tetpftext);
y-=dy;
sprintf(buf,"MTPF: %d",int(m_LastStats.m_ModelTris/m_LastStats.m_Counter));
COverlayText mtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&mtpftext);
y-=dy;
sprintf(buf,"TrTPF: %d",int(m_LastStats.m_TransparentTris/m_LastStats.m_Counter));
COverlayText trtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&trtpftext);
y-=dy;
sprintf(buf,"DCPF: %d",int(m_LastStats.m_DrawCalls/m_LastStats.m_Counter));
COverlayText dcpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&dcpftext);
y-=dy;
sprintf(buf,"SPPF: %d",int(m_LastStats.m_BlendSplats/m_LastStats.m_Counter));
COverlayText sppftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&sppftext);
y-=dy;
}
}
void CInfoBox::OnFrameComplete()
{
// accumulate stats
m_Stats+=g_Renderer.GetStats();
// fps check
double cur_time=get_time();
if (cur_time-m_LastFPSTime>1) {
// save tick time
m_LastTickTime=cur_time-m_LastFPSTime;
// save stats
m_LastStats=m_Stats;
// save time
m_LastFPSTime=cur_time;
// reset stats
m_Stats.Reset();
}
#include "InfoBox.h"
#include "UIGlobals.h"
#include "types.h"
#include "ogl.h"
#include "timer.h"
#include "NPFont.h"
#include "NPFontManager.h"
#include "OverlayText.h"
#include "Renderer.h"
static const char* DefaultFontName="mods/official/fonts/verdana18.fnt";
CInfoBox::CInfoBox() : m_Font(0), m_Visible(false)
{
m_LastFPSTime=get_time();
m_Stats.Reset();
}
void CInfoBox::Initialise()
{
m_Font=NPFontManager::instance().add(DefaultFontName);
}
void CInfoBox::Render()
{
if (!m_Visible) return;
const u32 panelColor=0x80f9527d;
const u32 borderColor=0xfffa0043;
// setup renderstate
glDisable(GL_DEPTH_TEST);
glDepthMask(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// load identity modelview
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// setup ortho view
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
int w=g_Renderer.GetWidth();
int h=g_Renderer.GetHeight();
glOrtho(0,w,0,h,-1,1);
glColor4ubv((const GLubyte*) &panelColor);
// render infobox as quad
glBegin(GL_QUADS);
glVertex2i(3,h-180);
glVertex2i(150,h-180);
glVertex2i(150,h-2);
glVertex2i(3,h-2);
glEnd();
// render border
glColor4ubv((const GLubyte*) &borderColor);
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glVertex2i(1,h-182);
glVertex2i(152,h-182);
glVertex2i(152,h-1);
glVertex2i(1,h-1);
glEnd();
// render any info now, assuming we've got a font
if (m_Font) {
RenderInfo();
}
// restore matrices
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// restore renderstate
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthMask(1);
}
void render(COverlayText* overlaytext)
{
// get font on overlay
NPFont* font=overlaytext->GetFont();
if (!font) return;
const CStr& str=overlaytext->GetString();
int len=str.Length();
if (len==0) return;
// bind to font texture
g_Renderer.SetTexture(0,&font->texture());
// setup texenv
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
// get overlay's position
float x,y;
overlaytext->GetPosition(x,y);
// setup color
const CColor& color=overlaytext->GetColor();
glColor4fv((float*) &color);
float x0=x;
float ftw=float(font->textureWidth());
float fth=float(font->textureHeight());
float fdy=float(font->height())/fth;
// submit quad verts for each character
glBegin(GL_QUADS);
for (int i=0;i<len;i++) {
// get pointer to char widths
const NPFont::CharData& cdata=font->chardata(str[i]);
const int* cw=&cdata._widthA;
if (cw[0]>0) x0+=cw[0];
// find the tile for this character
unsigned char c0=unsigned char(str[i]-32);
int ix=c0%font->numCols();
int iy=c0/font->numCols();
// calc UV coords of character in texture
float u0=float(ix*font->maxcharwidth()+cw[0]-1)/ftw;
float v0=float(iy*(font->height()+1))/fth;
float u1=u0+float(cw[1]+1)/ftw;
float v1=v0+fdy;
glTexCoord2f(u0,v0);
glVertex2f(x0,y);
glTexCoord2f(u1,v0);
glVertex2f(x0+float(cw[1]+1),y);
glTexCoord2f(u1,v1);
glVertex2f(x0+float(cw[1]+1),y+font->height());
glTexCoord2f(u0,v1);
glVertex2f(x0,y+font->height());
// translate such that next character is rendered in correct position
x0+=float(cw[1]+1);
if (cw[2]>0) x0+=cw[2];
}
glEnd();
// unbind texture ..
g_Renderer.SetTexture(0,0);
}
void CInfoBox::RenderInfo()
{
int w=g_Renderer.GetWidth();
int h=g_Renderer.GetHeight();
char buf[32];
if (m_LastStats.m_Counter) {
u32 dy=m_Font->height()+2;
float y=float(h-dy);
sprintf(buf,"FPS: %d",int(m_LastStats.m_Counter/m_LastTickTime));
COverlayText fpstext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&fpstext);
y-=dy;
sprintf(buf,"FT: %.2f",1000*m_LastTickTime/float(m_LastStats.m_Counter));
COverlayText fttext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&fttext);
y-=dy;
u32 totalTris=m_LastStats.m_TerrainTris+m_LastStats.m_ModelTris+m_LastStats.m_TransparentTris;
sprintf(buf,"TPF: %d",int(totalTris/m_LastStats.m_Counter));
COverlayText tpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&tpftext);
y-=dy;
sprintf(buf,"TeTPF: %d",int(m_LastStats.m_TerrainTris/m_LastStats.m_Counter));
COverlayText tetpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&tetpftext);
y-=dy;
sprintf(buf,"MTPF: %d",int(m_LastStats.m_ModelTris/m_LastStats.m_Counter));
COverlayText mtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&mtpftext);
y-=dy;
sprintf(buf,"TrTPF: %d",int(m_LastStats.m_TransparentTris/m_LastStats.m_Counter));
COverlayText trtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&trtpftext);
y-=dy;
sprintf(buf,"DCPF: %d",int(m_LastStats.m_DrawCalls/m_LastStats.m_Counter));
COverlayText dcpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&dcpftext);
y-=dy;
sprintf(buf,"SPPF: %d",int(m_LastStats.m_BlendSplats/m_LastStats.m_Counter));
COverlayText sppftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
render(&sppftext);
y-=dy;
}
}
void CInfoBox::OnFrameComplete()
{
// accumulate stats
m_Stats+=g_Renderer.GetStats();
// fps check
double cur_time=get_time();
if (cur_time-m_LastFPSTime>1) {
// save tick time
m_LastTickTime=cur_time-m_LastFPSTime;
// save stats
m_LastStats=m_Stats;
// save time
m_LastFPSTime=cur_time;
// reset stats
m_Stats.Reset();
}
}

View File

@ -1,45 +1,45 @@
#ifndef _INFOBOX_H
#define _INFOBOX_H
class NPFont;
#include "Renderer.h"
class CInfoBox
{
public:
CInfoBox();
// setup the infobox
void Initialise();
// render out the info box
void Render();
// frame has been rendered out, update stats
void OnFrameComplete();
// set visibility
void SetVisible(bool flag) { m_Visible=flag; }
// get visibility
bool GetVisible() const { return m_Visible; }
private:
// text output: render any relevant current information
void RenderInfo();
// currently visible?
bool m_Visible;
// font to use rendering out text to the info box
NPFont* m_Font;
// current frame rate
double m_FPS;
// last known frame time
double m_LastFPSTime;
// accumulated stats
CRenderer::Stats m_Stats;
// time of the last 1 second "tick"
double m_LastTickTime;
// stats from last 1 second "tick"
CRenderer::Stats m_LastStats;
};
#endif
#ifndef _INFOBOX_H
#define _INFOBOX_H
class NPFont;
#include "Renderer.h"
class CInfoBox
{
public:
CInfoBox();
// setup the infobox
void Initialise();
// render out the info box
void Render();
// frame has been rendered out, update stats
void OnFrameComplete();
// set visibility
void SetVisible(bool flag) { m_Visible=flag; }
// get visibility
bool GetVisible() const { return m_Visible; }
private:
// text output: render any relevant current information
void RenderInfo();
// currently visible?
bool m_Visible;
// font to use rendering out text to the info box
NPFont* m_Font;
// current frame rate
double m_FPS;
// last known frame time
double m_LastFPSTime;
// accumulated stats
CRenderer::Stats m_Stats;
// time of the last 1 second "tick"
double m_LastTickTime;
// stats from last 1 second "tick"
CRenderer::Stats m_LastStats;
};
#endif

View File

@ -1,170 +1,170 @@
// LightSettingsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "LightSettingsDlg.h"
#include <assert.h>
#include "Terrain.h"
#include "LightEnv.h"
#include "CommandManager.h"
#include "AlterLightEnvCommand.h"
extern CTerrain g_Terrain;
/////////////////////////////////////////////////////////////////////////////
// CLightSettingsDlg dialog
CLightSettingsDlg::CLightSettingsDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLightSettingsDlg::IDD, pParent), m_PreviousPreview(false)
{
//{{AFX_DATA_INIT(CLightSettingsDlg)
m_Direction = 270;
m_Elevation = 45;
//}}AFX_DATA_INIT
}
void CLightSettingsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLightSettingsDlg)
DDX_Control(pDX, IDC_BUTTON_UNITSAMBIENTCOLOR, m_UnitsAmbientColor);
DDX_Control(pDX, IDC_BUTTON_DIRECTION, m_DirectionButton);
DDX_Control(pDX, IDC_BUTTON_ELEVATION, m_ElevationButton);
DDX_Control(pDX, IDC_BUTTON_TERRAINAMBIENTCOLOR, m_TerrainAmbientColor);
DDX_Control(pDX, IDC_BUTTON_SUNCOLOR, m_SunColor);
DDX_Text(pDX, IDC_EDIT_DIRECTION, m_Direction);
DDX_Text(pDX, IDC_EDIT_ELEVATION, m_Elevation);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLightSettingsDlg, CDialog)
//{{AFX_MSG_MAP(CLightSettingsDlg)
ON_BN_CLICKED(IDC_BUTTON_APPLY, OnButtonApply)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DIRECTION, OnDeltaposSpinDirection)
ON_EN_CHANGE(IDC_EDIT_DIRECTION, OnChangeEditDirection)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ELEVATION, OnDeltaposSpinElevation)
ON_EN_CHANGE(IDC_EDIT_ELEVATION, OnChangeEditElevation)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLightSettingsDlg message handlers
void CLightSettingsDlg::OnButtonApply()
{
UpdateData(TRUE);
// have we previously applied a lightenv?
if (m_PreviousPreview) {
// yes - undo it
g_CmdMan.Undo();
}
// build a lighting environment from the parameters
CLightEnv env;
env.m_Elevation=DEGTORAD(m_ElevationButton.m_Elevation);
env.m_Rotation=DEGTORAD(m_DirectionButton.m_Direction);
ColorRefToRGBColor(m_SunColor.m_Color,env.m_SunColor);
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_TerrainAmbientColor);
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_UnitsAmbientColor);
// create and execute an AlterLightEnv command
CAlterLightEnvCommand* cmd=new CAlterLightEnvCommand(env);
g_CmdMan.Execute(cmd);
AfxGetMainWnd()->Invalidate();
AfxGetMainWnd()->UpdateWindow();
m_PreviousPreview=true;
}
BOOL CLightSettingsDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
assert(dirspin);
dirspin->SetRange32(0,359);
dirspin->SetPos(m_Direction);
m_DirectionButton.m_Direction=float(m_Direction);
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
assert(espin);
espin->SetRange32(0,90);
espin->SetPos(m_Elevation);
m_ElevationButton.m_Elevation=float(m_Elevation);
return TRUE;
}
void CLightSettingsDlg::OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// update direction button
if (!UpdateData(TRUE)) return;
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
m_Direction=dirspin->GetPos()+pNMUpDown->iDelta;
m_DirectionButton.m_Direction=float(m_Direction);
m_DirectionButton.Invalidate();
m_DirectionButton.UpdateWindow();
UpdateData(FALSE);
*pResult = 0;
}
void CLightSettingsDlg::OnChangeEditDirection()
{
if (IsWindow(m_DirectionButton.m_hWnd)) {
if (!UpdateData(TRUE)) return;
m_DirectionButton.m_Direction=float(m_Direction);
m_DirectionButton.Invalidate();
m_DirectionButton.UpdateWindow();
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
if (dirspin) dirspin->SetPos(m_Direction);
}
}
void CLightSettingsDlg::OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// update elevation button
if (!UpdateData(TRUE)) return;
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
m_Elevation=espin->GetPos()+pNMUpDown->iDelta;
m_ElevationButton.m_Elevation=float(m_Elevation);
m_ElevationButton.Invalidate();
m_ElevationButton.UpdateWindow();
UpdateData(FALSE);
*pResult = 0;
}
void CLightSettingsDlg::OnChangeEditElevation()
{
if (IsWindow(m_ElevationButton.m_hWnd)) {
if (!UpdateData(TRUE)) return;
m_ElevationButton.m_Elevation=float(m_Elevation);
m_ElevationButton.Invalidate();
m_ElevationButton.UpdateWindow();
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
if (espin) espin->SetPos(m_Elevation);
}
}
// LightSettingsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "LightSettingsDlg.h"
#include <assert.h>
#include "Terrain.h"
#include "LightEnv.h"
#include "CommandManager.h"
#include "AlterLightEnvCommand.h"
extern CTerrain g_Terrain;
/////////////////////////////////////////////////////////////////////////////
// CLightSettingsDlg dialog
CLightSettingsDlg::CLightSettingsDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLightSettingsDlg::IDD, pParent), m_PreviousPreview(false)
{
//{{AFX_DATA_INIT(CLightSettingsDlg)
m_Direction = 270;
m_Elevation = 45;
//}}AFX_DATA_INIT
}
void CLightSettingsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLightSettingsDlg)
DDX_Control(pDX, IDC_BUTTON_UNITSAMBIENTCOLOR, m_UnitsAmbientColor);
DDX_Control(pDX, IDC_BUTTON_DIRECTION, m_DirectionButton);
DDX_Control(pDX, IDC_BUTTON_ELEVATION, m_ElevationButton);
DDX_Control(pDX, IDC_BUTTON_TERRAINAMBIENTCOLOR, m_TerrainAmbientColor);
DDX_Control(pDX, IDC_BUTTON_SUNCOLOR, m_SunColor);
DDX_Text(pDX, IDC_EDIT_DIRECTION, m_Direction);
DDX_Text(pDX, IDC_EDIT_ELEVATION, m_Elevation);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLightSettingsDlg, CDialog)
//{{AFX_MSG_MAP(CLightSettingsDlg)
ON_BN_CLICKED(IDC_BUTTON_APPLY, OnButtonApply)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DIRECTION, OnDeltaposSpinDirection)
ON_EN_CHANGE(IDC_EDIT_DIRECTION, OnChangeEditDirection)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ELEVATION, OnDeltaposSpinElevation)
ON_EN_CHANGE(IDC_EDIT_ELEVATION, OnChangeEditElevation)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLightSettingsDlg message handlers
void CLightSettingsDlg::OnButtonApply()
{
UpdateData(TRUE);
// have we previously applied a lightenv?
if (m_PreviousPreview) {
// yes - undo it
g_CmdMan.Undo();
}
// build a lighting environment from the parameters
CLightEnv env;
env.m_Elevation=DEGTORAD(m_ElevationButton.m_Elevation);
env.m_Rotation=DEGTORAD(m_DirectionButton.m_Direction);
ColorRefToRGBColor(m_SunColor.m_Color,env.m_SunColor);
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_TerrainAmbientColor);
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_UnitsAmbientColor);
// create and execute an AlterLightEnv command
CAlterLightEnvCommand* cmd=new CAlterLightEnvCommand(env);
g_CmdMan.Execute(cmd);
AfxGetMainWnd()->Invalidate();
AfxGetMainWnd()->UpdateWindow();
m_PreviousPreview=true;
}
BOOL CLightSettingsDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
assert(dirspin);
dirspin->SetRange32(0,359);
dirspin->SetPos(m_Direction);
m_DirectionButton.m_Direction=float(m_Direction);
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
assert(espin);
espin->SetRange32(0,90);
espin->SetPos(m_Elevation);
m_ElevationButton.m_Elevation=float(m_Elevation);
return TRUE;
}
void CLightSettingsDlg::OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// update direction button
if (!UpdateData(TRUE)) return;
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
m_Direction=dirspin->GetPos()+pNMUpDown->iDelta;
m_DirectionButton.m_Direction=float(m_Direction);
m_DirectionButton.Invalidate();
m_DirectionButton.UpdateWindow();
UpdateData(FALSE);
*pResult = 0;
}
void CLightSettingsDlg::OnChangeEditDirection()
{
if (IsWindow(m_DirectionButton.m_hWnd)) {
if (!UpdateData(TRUE)) return;
m_DirectionButton.m_Direction=float(m_Direction);
m_DirectionButton.Invalidate();
m_DirectionButton.UpdateWindow();
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
if (dirspin) dirspin->SetPos(m_Direction);
}
}
void CLightSettingsDlg::OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// update elevation button
if (!UpdateData(TRUE)) return;
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
m_Elevation=espin->GetPos()+pNMUpDown->iDelta;
m_ElevationButton.m_Elevation=float(m_Elevation);
m_ElevationButton.Invalidate();
m_ElevationButton.UpdateWindow();
UpdateData(FALSE);
*pResult = 0;
}
void CLightSettingsDlg::OnChangeEditElevation()
{
if (IsWindow(m_ElevationButton.m_hWnd)) {
if (!UpdateData(TRUE)) return;
m_ElevationButton.m_Elevation=float(m_Elevation);
m_ElevationButton.Invalidate();
m_ElevationButton.UpdateWindow();
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
if (espin) espin->SetPos(m_Elevation);
}
}

View File

@ -1,64 +1,64 @@
#if !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
#define AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// LightSettingsDlg.h : header file
//
#include "ColorButton.h"
#include "DirectionButton.h"
#include "ElevationButton.h"
/////////////////////////////////////////////////////////////////////////////
// CLightSettingsDlg dialog
class CLightSettingsDlg : public CDialog
{
// Construction
public:
CLightSettingsDlg(CWnd* pParent = NULL); // standard constructor
bool m_PreviousPreview;
// Dialog Data
//{{AFX_DATA(CLightSettingsDlg)
enum { IDD = IDD_DIALOG_LIGHTSETTINGS };
CColorButton m_UnitsAmbientColor;
CDirectionButton m_DirectionButton;
CElevationButton m_ElevationButton;
CColorButton m_TerrainAmbientColor;
CColorButton m_SunColor;
int m_Direction;
int m_Elevation;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CLightSettingsDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CLightSettingsDlg)
afx_msg void OnButtonApply();
virtual BOOL OnInitDialog();
afx_msg void OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnChangeEditDirection();
afx_msg void OnButtonTerrainambientcolor();
afx_msg void OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnChangeEditElevation();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
#if !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
#define AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// LightSettingsDlg.h : header file
//
#include "ColorButton.h"
#include "DirectionButton.h"
#include "ElevationButton.h"
/////////////////////////////////////////////////////////////////////////////
// CLightSettingsDlg dialog
class CLightSettingsDlg : public CDialog
{
// Construction
public:
CLightSettingsDlg(CWnd* pParent = NULL); // standard constructor
bool m_PreviousPreview;
// Dialog Data
//{{AFX_DATA(CLightSettingsDlg)
enum { IDD = IDD_DIALOG_LIGHTSETTINGS };
CColorButton m_UnitsAmbientColor;
CDirectionButton m_DirectionButton;
CElevationButton m_ElevationButton;
CColorButton m_TerrainAmbientColor;
CColorButton m_SunColor;
int m_Direction;
int m_Elevation;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CLightSettingsDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CLightSettingsDlg)
afx_msg void OnButtonApply();
virtual BOOL OnInitDialog();
afx_msg void OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnChangeEditDirection();
afx_msg void OnButtonTerrainambientcolor();
afx_msg void OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnChangeEditElevation();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)

View File

@ -1,107 +1,107 @@
// MainFrameDlgBar.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "MainFrm.h"
#include "MainFrameDlgBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CMainFrameDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CMainFrameDlgBar)
ON_BN_CLICKED(IDC_BUTTON_SELECT, OnButtonSelect)
ON_BN_CLICKED(IDC_BUTTON_TEXTURETOOLS, OnButtonTextureTools)
ON_BN_CLICKED(IDC_BUTTON_ELEVATIONTOOLS, OnButtonElevationTools)
ON_BN_CLICKED(IDC_BUTTON_MODELTOOLS, OnButtonModelTools)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMainFrameDlgBar dialog
CMainFrameDlgBar::CMainFrameDlgBar()
{
//{{AFX_DATA_INIT(CMainFrameDlgBar)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
{
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
return FALSE;
}
if (!OnInitDialog()) {
return FALSE;
}
return TRUE;
}
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
{
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
return FALSE;
}
return TRUE;
}
void CMainFrameDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
bDisableIfNoHndler = FALSE;
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrameDlgBar message handlers
void CMainFrameDlgBar::OnButtonSelect()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->DeselectTools();
}
void CMainFrameDlgBar::OnButtonTextureTools()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->OnTextureTools();
}
void CMainFrameDlgBar::OnButtonElevationTools()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->OnElevationTools();
}
void CMainFrameDlgBar::OnButtonModelTools()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->OnUnitTools();
}
BOOL CMainFrameDlgBar::OnInitDialog()
{
CButton* btnSelect=(CButton*) GetDlgItem(IDC_BUTTON_SELECT);
btnSelect->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_SELECT)));
CButton* btnTexTools=(CButton*) GetDlgItem(IDC_BUTTON_TEXTURETOOLS);
btnTexTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_TEXTURETOOLS)));
CButton* btnElevTools=(CButton*) GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS);
btnElevTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_ELEVATIONTOOLS)));
CButton* btnMdlTools=(CButton*) GetDlgItem(IDC_BUTTON_MODELTOOLS);
btnMdlTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_MODELTOOLS)));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// MainFrameDlgBar.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "MainFrm.h"
#include "MainFrameDlgBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CMainFrameDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CMainFrameDlgBar)
ON_BN_CLICKED(IDC_BUTTON_SELECT, OnButtonSelect)
ON_BN_CLICKED(IDC_BUTTON_TEXTURETOOLS, OnButtonTextureTools)
ON_BN_CLICKED(IDC_BUTTON_ELEVATIONTOOLS, OnButtonElevationTools)
ON_BN_CLICKED(IDC_BUTTON_MODELTOOLS, OnButtonModelTools)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMainFrameDlgBar dialog
CMainFrameDlgBar::CMainFrameDlgBar()
{
//{{AFX_DATA_INIT(CMainFrameDlgBar)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
{
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
return FALSE;
}
if (!OnInitDialog()) {
return FALSE;
}
return TRUE;
}
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
{
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
return FALSE;
}
return TRUE;
}
void CMainFrameDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
bDisableIfNoHndler = FALSE;
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrameDlgBar message handlers
void CMainFrameDlgBar::OnButtonSelect()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->DeselectTools();
}
void CMainFrameDlgBar::OnButtonTextureTools()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->OnTextureTools();
}
void CMainFrameDlgBar::OnButtonElevationTools()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->OnElevationTools();
}
void CMainFrameDlgBar::OnButtonModelTools()
{
CMainFrame* parent=(CMainFrame*) GetParent();
parent->OnUnitTools();
}
BOOL CMainFrameDlgBar::OnInitDialog()
{
CButton* btnSelect=(CButton*) GetDlgItem(IDC_BUTTON_SELECT);
btnSelect->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_SELECT)));
CButton* btnTexTools=(CButton*) GetDlgItem(IDC_BUTTON_TEXTURETOOLS);
btnTexTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_TEXTURETOOLS)));
CButton* btnElevTools=(CButton*) GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS);
btnElevTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_ELEVATIONTOOLS)));
CButton* btnMdlTools=(CButton*) GetDlgItem(IDC_BUTTON_MODELTOOLS);
btnMdlTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_MODELTOOLS)));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

View File

@ -1,53 +1,53 @@
#if !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
#define AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MainFrameDlgBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CMainFrameDlgBar dialog
class CMainFrameDlgBar : public CDialogBar
{
// Construction
public:
CMainFrameDlgBar(); // standard constructor
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
// Dialog Data
//{{AFX_DATA(CMainFrameDlgBar)
enum { IDD = IDR_MAINFRAME };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrameDlgBar)
protected:
//}}AFX_VIRTUAL
// Implementation
protected:
BOOL OnInitDialog();
// Generated message map functions
//{{AFX_MSG(CMainFrameDlgBar)
afx_msg void OnButtonSelect();
afx_msg void OnButtonTextureTools();
afx_msg void OnButtonElevationTools();
afx_msg void OnButtonModelTools();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
#if !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
#define AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MainFrameDlgBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CMainFrameDlgBar dialog
class CMainFrameDlgBar : public CDialogBar
{
// Construction
public:
CMainFrameDlgBar(); // standard constructor
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
// Dialog Data
//{{AFX_DATA(CMainFrameDlgBar)
enum { IDD = IDR_MAINFRAME };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrameDlgBar)
protected:
//}}AFX_VIRTUAL
// Implementation
protected:
BOOL OnInitDialog();
// Generated message map functions
//{{AFX_MSG(CMainFrameDlgBar)
afx_msg void OnButtonSelect();
afx_msg void OnButtonTextureTools();
afx_msg void OnButtonElevationTools();
afx_msg void OnButtonModelTools();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,117 @@
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
#define AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MainFrameDlgBar.h"
#include "TexToolsDlgBar.h"
#include "ElevToolsDlgBar.h"
#include "UnitToolsDlgBar.h"
#include "UnitPropertiesDlgBar.h"
#include "BrushShapeEditorDlgBar.h"
class CObjectEntry;
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
public:
// Operations
public:
void OnUnitTools();
void OnObjectProperties(CObjectEntry* obj);
void DeselectTools();
void SetTitle();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CMainFrameDlgBar m_wndDlgBar;
CTexToolsDlgBar m_wndTexToolsBar;
CElevToolsDlgBar m_wndElevToolsBar;
CUnitToolsDlgBar m_wndUnitToolsBar;
CUnitPropertiesDlgBar m_wndUnitPropsBar;
CBrushShapeEditorDlgBar m_wndBrushShapeEditorBar;
// Generated message map functions
protected:
friend class CMainFrameDlgBar;
friend class CScEdView;
void DisableCtrlBars();
void DisableToolbarButtons();
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTerrainLoad();
afx_msg void OnLightingSettings();
afx_msg void OnViewScreenshot();
afx_msg void OnTextureTools();
afx_msg void OnToolsOptions();
afx_msg void OnToolsBrushShapeEditor();
afx_msg void OnEditUndo();
afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
afx_msg void OnEditRedo();
afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
afx_msg void OnElevationTools();
afx_msg void OnResizeMap();
afx_msg void OnViewTerrainGrid();
afx_msg void OnUpdateViewTerrainGrid(CCmdUI* pCmdUI);
afx_msg void OnViewTerrainSolid();
afx_msg void OnUpdateViewTerrainSolid(CCmdUI* pCmdUI);
afx_msg void OnViewTerrainWireframe();
afx_msg void OnUpdateViewTerrainWireframe(CCmdUI* pCmdUI);
afx_msg void OnViewModelGrid();
afx_msg void OnUpdateViewModelGrid(CCmdUI* pCmdUI);
afx_msg void OnViewModelSolid();
afx_msg void OnUpdateViewModelSolid(CCmdUI* pCmdUI);
afx_msg void OnViewModelWireframe();
afx_msg void OnUpdateViewModelWireframe(CCmdUI* pCmdUI);
afx_msg void OnFileSaveMap();
afx_msg void OnFileLoadMap();
afx_msg void OnViewRenderStats();
afx_msg void OnUpdateViewRenderStats(CCmdUI* pCmdUI);
afx_msg LRESULT OnMouseWheel(WPARAM wParam,LPARAM lParam);
afx_msg void OnTestGo();
afx_msg void OnUpdateTestGo(CCmdUI* pCmdUI);
afx_msg void OnTestStop();
afx_msg void OnUpdateTestStop(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
#define AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MainFrameDlgBar.h"
#include "TexToolsDlgBar.h"
#include "ElevToolsDlgBar.h"
#include "UnitToolsDlgBar.h"
#include "UnitPropertiesDlgBar.h"
#include "BrushShapeEditorDlgBar.h"
class CObjectEntry;
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
public:
// Operations
public:
void OnUnitTools();
void OnObjectProperties(CObjectEntry* obj);
void DeselectTools();
void SetTitle();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CMainFrameDlgBar m_wndDlgBar;
CTexToolsDlgBar m_wndTexToolsBar;
CElevToolsDlgBar m_wndElevToolsBar;
CUnitToolsDlgBar m_wndUnitToolsBar;
CUnitPropertiesDlgBar m_wndUnitPropsBar;
CBrushShapeEditorDlgBar m_wndBrushShapeEditorBar;
// Generated message map functions
protected:
friend class CMainFrameDlgBar;
friend class CScEdView;
void DisableCtrlBars();
void DisableToolbarButtons();
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTerrainLoad();
afx_msg void OnLightingSettings();
afx_msg void OnViewScreenshot();
afx_msg void OnTextureTools();
afx_msg void OnToolsOptions();
afx_msg void OnToolsBrushShapeEditor();
afx_msg void OnEditUndo();
afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
afx_msg void OnEditRedo();
afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
afx_msg void OnElevationTools();
afx_msg void OnResizeMap();
afx_msg void OnViewTerrainGrid();
afx_msg void OnUpdateViewTerrainGrid(CCmdUI* pCmdUI);
afx_msg void OnViewTerrainSolid();
afx_msg void OnUpdateViewTerrainSolid(CCmdUI* pCmdUI);
afx_msg void OnViewTerrainWireframe();
afx_msg void OnUpdateViewTerrainWireframe(CCmdUI* pCmdUI);
afx_msg void OnViewModelGrid();
afx_msg void OnUpdateViewModelGrid(CCmdUI* pCmdUI);
afx_msg void OnViewModelSolid();
afx_msg void OnUpdateViewModelSolid(CCmdUI* pCmdUI);
afx_msg void OnViewModelWireframe();
afx_msg void OnUpdateViewModelWireframe(CCmdUI* pCmdUI);
afx_msg void OnFileSaveMap();
afx_msg void OnFileLoadMap();
afx_msg void OnViewRenderStats();
afx_msg void OnUpdateViewRenderStats(CCmdUI* pCmdUI);
afx_msg LRESULT OnMouseWheel(WPARAM wParam,LPARAM lParam);
afx_msg void OnTestGo();
afx_msg void OnUpdateTestGo(CCmdUI* pCmdUI);
afx_msg void OnTestStop();
afx_msg void OnUpdateTestStop(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)

View File

@ -1,86 +1,86 @@
// MapSizeDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "MapSizeDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CMapSizeDlg dialog
CMapSizeDlg::CMapSizeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMapSizeDlg::IDD, pParent), m_MapSize(11)
{
//{{AFX_DATA_INIT(CMapSizeDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CMapSizeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMapSizeDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMapSizeDlg, CDialog)
//{{AFX_MSG_MAP(CMapSizeDlg)
ON_BN_CLICKED(IDC_RADIO_HUGE, OnRadioHuge)
ON_BN_CLICKED(IDC_RADIO_LARGE, OnRadioLarge)
ON_BN_CLICKED(IDC_RADIO_MEDIUM, OnRadioMedium)
ON_BN_CLICKED(IDC_RADIO_SMALL, OnRadioSmall)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMapSizeDlg message handlers
BOOL CMapSizeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
OnRadioMedium();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CMapSizeDlg::OnRadioHuge()
{
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
CheckDlgButton(IDC_RADIO_HUGE,TRUE);
m_MapSize=17;
}
void CMapSizeDlg::OnRadioLarge()
{
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
CheckDlgButton(IDC_RADIO_LARGE,TRUE);
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
m_MapSize=13;
}
void CMapSizeDlg::OnRadioMedium()
{
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
CheckDlgButton(IDC_RADIO_MEDIUM,TRUE);
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
m_MapSize=11;
}
void CMapSizeDlg::OnRadioSmall()
{
CheckDlgButton(IDC_RADIO_SMALL,TRUE);
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
m_MapSize=9;
}
// MapSizeDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "MapSizeDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CMapSizeDlg dialog
CMapSizeDlg::CMapSizeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMapSizeDlg::IDD, pParent), m_MapSize(11)
{
//{{AFX_DATA_INIT(CMapSizeDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CMapSizeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMapSizeDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMapSizeDlg, CDialog)
//{{AFX_MSG_MAP(CMapSizeDlg)
ON_BN_CLICKED(IDC_RADIO_HUGE, OnRadioHuge)
ON_BN_CLICKED(IDC_RADIO_LARGE, OnRadioLarge)
ON_BN_CLICKED(IDC_RADIO_MEDIUM, OnRadioMedium)
ON_BN_CLICKED(IDC_RADIO_SMALL, OnRadioSmall)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMapSizeDlg message handlers
BOOL CMapSizeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
OnRadioMedium();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CMapSizeDlg::OnRadioHuge()
{
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
CheckDlgButton(IDC_RADIO_HUGE,TRUE);
m_MapSize=17;
}
void CMapSizeDlg::OnRadioLarge()
{
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
CheckDlgButton(IDC_RADIO_LARGE,TRUE);
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
m_MapSize=13;
}
void CMapSizeDlg::OnRadioMedium()
{
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
CheckDlgButton(IDC_RADIO_MEDIUM,TRUE);
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
m_MapSize=11;
}
void CMapSizeDlg::OnRadioSmall()
{
CheckDlgButton(IDC_RADIO_SMALL,TRUE);
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
m_MapSize=9;
}

View File

@ -1,52 +1,52 @@
#if !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
#define AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MapSizeDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CMapSizeDlg dialog
class CMapSizeDlg : public CDialog
{
// Construction
public:
CMapSizeDlg(CWnd* pParent = NULL); // standard constructor
int m_MapSize;
// Dialog Data
//{{AFX_DATA(CMapSizeDlg)
enum { IDD = IDD_DIALOG_MAPSIZE };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMapSizeDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CMapSizeDlg)
virtual BOOL OnInitDialog();
afx_msg void OnRadioHuge();
afx_msg void OnRadioLarge();
afx_msg void OnRadioMedium();
afx_msg void OnRadioSmall();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
#if !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
#define AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MapSizeDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CMapSizeDlg dialog
class CMapSizeDlg : public CDialog
{
// Construction
public:
CMapSizeDlg(CWnd* pParent = NULL); // standard constructor
int m_MapSize;
// Dialog Data
//{{AFX_DATA(CMapSizeDlg)
enum { IDD = IDD_DIALOG_MAPSIZE };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMapSizeDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CMapSizeDlg)
virtual BOOL OnInitDialog();
afx_msg void OnRadioHuge();
afx_msg void OnRadioLarge();
afx_msg void OnRadioMedium();
afx_msg void OnRadioSmall();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)

View File

@ -1,259 +1,259 @@
#include "MiniMap.h"
#include "UIGlobals.h"
#include "TextureManager.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ogl.h"
extern CTerrain g_Terrain;
static unsigned int ScaleColor(unsigned int color,float x)
{
unsigned int r=unsigned int(float(color & 0xff)*x);
unsigned int g=unsigned int(float((color>>8) & 0xff)*x);
unsigned int b=unsigned int(float((color>>16) & 0xff)*x);
return (0xff000000 | r | g<<8 | b<<16);
}
static int RoundUpToPowerOf2(int x)
{
if ((x & (x-1))==0) return x;
int d=x;
while (d & (d-1)) {
d&=(d-1);
}
return d<<1;
}
CMiniMap::CMiniMap() : m_Handle(0)
{
}
void CMiniMap::Initialise()
{
// get rid of existing texture, if we've got one
if (m_Handle) {
glDeleteTextures(1,&m_Handle);
}
// allocate a handle, bind to it
glGenTextures(1,&m_Handle);
g_Renderer.BindTexture(0,m_Handle);
// allocate an image big enough to fit the entire map into
m_Size=RoundUpToPowerOf2(g_Terrain.GetVerticesPerSide());
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,m_Size,m_Size,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,0);
// set texture parameters
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
// force a rebuild to get correct initial view
Rebuild();
}
void CMiniMap::Render()
{
// setup renderstate
glDisable(GL_DEPTH_TEST);
glDepthMask(0);
// load identity modelview
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// setup ortho view
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
int w=g_Renderer.GetWidth();
int h=g_Renderer.GetHeight();
glOrtho(0,w,0,h,-1,1);
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
float tclimit=float(g_Terrain.GetVerticesPerSide()-1)/float(m_Size);
// render minimap as quad
glBegin(GL_QUADS);
glTexCoord2f(0,tclimit);
glVertex2i(w-200,200);
glTexCoord2f(0,0);
glVertex2i(w-200,2);
glTexCoord2f(tclimit,0);
glVertex2i(w-3,2);
glTexCoord2f(tclimit,tclimit);
glVertex2i(w-3,200);
glEnd();
// switch off textures
glDisable(GL_TEXTURE_2D);
// render border
glLineWidth(2);
glColor3f(0.4f,0.35f,0.8f);
glBegin(GL_LINE_LOOP);
glVertex2i(w-202,202);
glVertex2i(w-1,202);
glVertex2i(w-1,1);
glVertex2i(w-202,1);
glEnd();
// render view rect
glScissor(w-200,2,w,198);
glEnable(GL_SCISSOR_TEST);
glLineWidth(2);
glColor3f(1.0f,0.3f,0.3f);
glBegin(GL_LINE_LOOP);
glVertex2f(w-200+m_ViewRect[0][0],m_ViewRect[0][1]);
glVertex2f(w-200+m_ViewRect[1][0],m_ViewRect[1][1]);
glVertex2f(w-200+m_ViewRect[2][0],m_ViewRect[2][1]);
glVertex2f(w-200+m_ViewRect[3][0],m_ViewRect[3][1]);
glEnd();
glDisable(GL_SCISSOR_TEST);
// restore matrices
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// restore renderstate
glEnable(GL_DEPTH_TEST);
glDepthMask(1);
}
void CMiniMap::Update(int x,int y,unsigned int color)
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
// get height at this pixel
int hmap=(int) g_Terrain.GetHeightMap()[y*g_Terrain.GetVerticesPerSide() + x]>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
// get modulated color
unsigned int mcolor=ScaleColor(color,float(val)/255.0f);
// subimage to update pixel (ugh)
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,1,1,GL_BGRA_EXT,GL_UNSIGNED_BYTE,&mcolor);
}
void CMiniMap::Update(int x,int y,int w,int h,unsigned int color)
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
u32 mapSize=g_Terrain.GetVerticesPerSide();
unsigned int* data=new unsigned int[w*h];
unsigned int* dataptr=data;
for (int j=0;j<h;j++) {
for (int i=0;i<w;i++) {
// get height at this pixel
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
// load scaled color into data pointer
*dataptr++=ScaleColor(color,float(val)/255.0f);
}
}
// subimage to update pixels
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
delete[] data;
}
void CMiniMap::Rebuild()
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
u32 mapSize=g_Terrain.GetVerticesPerSide();
unsigned int* data=new unsigned int[(mapSize-1)*(mapSize-1)];
unsigned int* dataptr=data;
for (uint pj=0; pj<g_Terrain.GetPatchesPerSide(); pj++)
{
for (int tj=0; tj<16; tj++)
{
for (uint pi=0; pi<g_Terrain.GetPatchesPerSide(); pi++)
{
for (int ti=0; ti<16; ti++)
{
int i=pi*16+ti;
int j=pj*16+tj;
// get base color from textures on tile
unsigned int color;
CMiniPatch* mp=g_Terrain.GetTile(i,j);
if (mp) {
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
color=tex ? tex->m_BaseColor : 0xffffffff;
} else {
color=0xffffffff;
}
// get height at this pixel
int hmap=int(g_Terrain.GetHeightMap()[j*mapSize + i])>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
// load scaled color into data pointer
*dataptr++=ScaleColor(color,float(val)/255.0f);
}
}
}
}
// subimage to update pixels
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,(mapSize-1),(mapSize-1),GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
delete[] data;
}
void CMiniMap::Rebuild(int x,int y,int w,int h)
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
u32 mapSize=g_Terrain.GetVerticesPerSide();
unsigned int* data=new unsigned int[w*h];
unsigned int* dataptr=data;
for (int j=0;j<h;j++) {
for (int i=0;i<w;i++) {
// get height at this pixel
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
CMiniPatch* mp=g_Terrain.GetTile(x+i,y+j);
unsigned int color;
if (mp) {
// get texture on this time
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
color=tex ? tex->m_BaseColor : 0xffffffff;
} else {
color=0xffffffff;
}
// load scaled color into data pointer
*dataptr++=ScaleColor(color,float(val)/255.0f);
}
}
// subimage to update pixels
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
delete[] data;
}
#include "MiniMap.h"
#include "UIGlobals.h"
#include "TextureManager.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ogl.h"
extern CTerrain g_Terrain;
static unsigned int ScaleColor(unsigned int color,float x)
{
unsigned int r=unsigned int(float(color & 0xff)*x);
unsigned int g=unsigned int(float((color>>8) & 0xff)*x);
unsigned int b=unsigned int(float((color>>16) & 0xff)*x);
return (0xff000000 | r | g<<8 | b<<16);
}
static int RoundUpToPowerOf2(int x)
{
if ((x & (x-1))==0) return x;
int d=x;
while (d & (d-1)) {
d&=(d-1);
}
return d<<1;
}
CMiniMap::CMiniMap() : m_Handle(0)
{
}
void CMiniMap::Initialise()
{
// get rid of existing texture, if we've got one
if (m_Handle) {
glDeleteTextures(1,&m_Handle);
}
// allocate a handle, bind to it
glGenTextures(1,&m_Handle);
g_Renderer.BindTexture(0,m_Handle);
// allocate an image big enough to fit the entire map into
m_Size=RoundUpToPowerOf2(g_Terrain.GetVerticesPerSide());
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,m_Size,m_Size,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,0);
// set texture parameters
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
// force a rebuild to get correct initial view
Rebuild();
}
void CMiniMap::Render()
{
// setup renderstate
glDisable(GL_DEPTH_TEST);
glDepthMask(0);
// load identity modelview
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// setup ortho view
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
int w=g_Renderer.GetWidth();
int h=g_Renderer.GetHeight();
glOrtho(0,w,0,h,-1,1);
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
float tclimit=float(g_Terrain.GetVerticesPerSide()-1)/float(m_Size);
// render minimap as quad
glBegin(GL_QUADS);
glTexCoord2f(0,tclimit);
glVertex2i(w-200,200);
glTexCoord2f(0,0);
glVertex2i(w-200,2);
glTexCoord2f(tclimit,0);
glVertex2i(w-3,2);
glTexCoord2f(tclimit,tclimit);
glVertex2i(w-3,200);
glEnd();
// switch off textures
glDisable(GL_TEXTURE_2D);
// render border
glLineWidth(2);
glColor3f(0.4f,0.35f,0.8f);
glBegin(GL_LINE_LOOP);
glVertex2i(w-202,202);
glVertex2i(w-1,202);
glVertex2i(w-1,1);
glVertex2i(w-202,1);
glEnd();
// render view rect
glScissor(w-200,2,w,198);
glEnable(GL_SCISSOR_TEST);
glLineWidth(2);
glColor3f(1.0f,0.3f,0.3f);
glBegin(GL_LINE_LOOP);
glVertex2f(w-200+m_ViewRect[0][0],m_ViewRect[0][1]);
glVertex2f(w-200+m_ViewRect[1][0],m_ViewRect[1][1]);
glVertex2f(w-200+m_ViewRect[2][0],m_ViewRect[2][1]);
glVertex2f(w-200+m_ViewRect[3][0],m_ViewRect[3][1]);
glEnd();
glDisable(GL_SCISSOR_TEST);
// restore matrices
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// restore renderstate
glEnable(GL_DEPTH_TEST);
glDepthMask(1);
}
void CMiniMap::Update(int x,int y,unsigned int color)
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
// get height at this pixel
int hmap=(int) g_Terrain.GetHeightMap()[y*g_Terrain.GetVerticesPerSide() + x]>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
// get modulated color
unsigned int mcolor=ScaleColor(color,float(val)/255.0f);
// subimage to update pixel (ugh)
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,1,1,GL_BGRA_EXT,GL_UNSIGNED_BYTE,&mcolor);
}
void CMiniMap::Update(int x,int y,int w,int h,unsigned int color)
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
u32 mapSize=g_Terrain.GetVerticesPerSide();
unsigned int* data=new unsigned int[w*h];
unsigned int* dataptr=data;
for (int j=0;j<h;j++) {
for (int i=0;i<w;i++) {
// get height at this pixel
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
// load scaled color into data pointer
*dataptr++=ScaleColor(color,float(val)/255.0f);
}
}
// subimage to update pixels
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
delete[] data;
}
void CMiniMap::Rebuild()
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
u32 mapSize=g_Terrain.GetVerticesPerSide();
unsigned int* data=new unsigned int[(mapSize-1)*(mapSize-1)];
unsigned int* dataptr=data;
for (uint pj=0; pj<g_Terrain.GetPatchesPerSide(); pj++)
{
for (int tj=0; tj<16; tj++)
{
for (uint pi=0; pi<g_Terrain.GetPatchesPerSide(); pi++)
{
for (int ti=0; ti<16; ti++)
{
int i=pi*16+ti;
int j=pj*16+tj;
// get base color from textures on tile
unsigned int color;
CMiniPatch* mp=g_Terrain.GetTile(i,j);
if (mp) {
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
color=tex ? tex->m_BaseColor : 0xffffffff;
} else {
color=0xffffffff;
}
// get height at this pixel
int hmap=int(g_Terrain.GetHeightMap()[j*mapSize + i])>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
// load scaled color into data pointer
*dataptr++=ScaleColor(color,float(val)/255.0f);
}
}
}
}
// subimage to update pixels
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,(mapSize-1),(mapSize-1),GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
delete[] data;
}
void CMiniMap::Rebuild(int x,int y,int w,int h)
{
// bind to the minimap
g_Renderer.BindTexture(0,m_Handle);
u32 mapSize=g_Terrain.GetVerticesPerSide();
unsigned int* data=new unsigned int[w*h];
unsigned int* dataptr=data;
for (int j=0;j<h;j++) {
for (int i=0;i<w;i++) {
// get height at this pixel
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
// shift from 0-255 to 170-255
int val=(hmap/3)+170;
CMiniPatch* mp=g_Terrain.GetTile(x+i,y+j);
unsigned int color;
if (mp) {
// get texture on this time
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
color=tex ? tex->m_BaseColor : 0xffffffff;
} else {
color=0xffffffff;
}
// load scaled color into data pointer
*dataptr++=ScaleColor(color,float(val)/255.0f);
}
}
// subimage to update pixels
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
delete[] data;
}

View File

@ -1,28 +1,28 @@
#ifndef _MINIMAP_H
#define _MINIMAP_H
class CMiniMap
{
public:
CMiniMap();
void Initialise();
void Render();
void Update(int x,int y,unsigned int color);
void Update(int x,int y,int w,int h,unsigned int color);
void Rebuild();
void Rebuild(int x,int y,int w,int h);
// current viewing frustum, in minimap coordinate space
float m_ViewRect[4][2];
private:
// texture handle
unsigned int m_Handle;
// size of the map texture
unsigned int m_Size;
};
extern CMiniMap g_MiniMap;
#endif
#ifndef _MINIMAP_H
#define _MINIMAP_H
class CMiniMap
{
public:
CMiniMap();
void Initialise();
void Render();
void Update(int x,int y,unsigned int color);
void Update(int x,int y,int w,int h,unsigned int color);
void Rebuild();
void Rebuild(int x,int y,int w,int h);
// current viewing frustum, in minimap coordinate space
float m_ViewRect[4][2];
private:
// texture handle
unsigned int m_Handle;
// size of the map texture
unsigned int m_Size;
};
extern CMiniMap g_MiniMap;
#endif

View File

@ -1,68 +1,68 @@
#include "stdafx.h"
#include "NaviCam.h"
#include "EditorData.h"
#include <stdarg.h>
CNaviCam g_NaviCam;
static void DbgText(char* str, ...)
{
char buf[1024];
va_list args;
va_start(args, str);
vsprintf(buf, str, args);
va_end(args);
OutputDebugString(buf);
}
///////////////////////////////////////////////////////////////////////////////
// CNaviCam constructor
CNaviCam::CNaviCam() : m_CameraZoom(10)
{
}
///////////////////////////////////////////////////////////////////////////////
// OnMouseWheelScroll: handler for wheel scroll event - dir is positive for
// upward scroll (away from user), or negative for downward scroll (towards
// user)
void CNaviCam::OnMouseWheelScroll(u32 flags,int px,int py,float dir)
{
CVector3D forward=m_Camera.m_Orientation.GetIn();
float factor=dir*dir;
if (dir<0) factor=-factor;
// check we're not going to zoom into the terrain, or too far out into space
float h=m_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*m_CameraZoom;
float minh=65536*HEIGHT_SCALE*1.05f;
if (h<minh || h>1500) {
// yup, we will; don't move anywhere (do clamped move instead, at some point)
} else {
// do a full move
m_CameraZoom-=(factor)*0.1f;
if (m_CameraZoom<0.01f) m_CameraZoom=0.01f;
m_Camera.m_Orientation.Translate(forward*(factor*m_CameraZoom));
}
g_EditorData.OnCameraChanged();
}
///////////////////////////////////////////////////////////////////////////////
// OnMButtonDown: handler for middle button down event
void CNaviCam::OnMButtonDown(u32 flags,int px,int py)
{
}
///////////////////////////////////////////////////////////////////////////////
// OnMButtonUp: handler for middle button up event
void CNaviCam::OnMButtonUp(u32 flags,int px,int py)
{
}
///////////////////////////////////////////////////////////////////////////////
// OnMouseMove: handler for mouse move (only called when middle button down)
void CNaviCam::OnMouseMove(u32 flags,int px,int py)
{
}
#include "stdafx.h"
#include "NaviCam.h"
#include "EditorData.h"
#include <stdarg.h>
CNaviCam g_NaviCam;
static void DbgText(char* str, ...)
{
char buf[1024];
va_list args;
va_start(args, str);
vsprintf(buf, str, args);
va_end(args);
OutputDebugString(buf);
}
///////////////////////////////////////////////////////////////////////////////
// CNaviCam constructor
CNaviCam::CNaviCam() : m_CameraZoom(10)
{
}
///////////////////////////////////////////////////////////////////////////////
// OnMouseWheelScroll: handler for wheel scroll event - dir is positive for
// upward scroll (away from user), or negative for downward scroll (towards
// user)
void CNaviCam::OnMouseWheelScroll(u32 flags,int px,int py,float dir)
{
CVector3D forward=m_Camera.m_Orientation.GetIn();
float factor=dir*dir;
if (dir<0) factor=-factor;
// check we're not going to zoom into the terrain, or too far out into space
float h=m_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*m_CameraZoom;
float minh=65536*HEIGHT_SCALE*1.05f;
if (h<minh || h>1500) {
// yup, we will; don't move anywhere (do clamped move instead, at some point)
} else {
// do a full move
m_CameraZoom-=(factor)*0.1f;
if (m_CameraZoom<0.01f) m_CameraZoom=0.01f;
m_Camera.m_Orientation.Translate(forward*(factor*m_CameraZoom));
}
g_EditorData.OnCameraChanged();
}
///////////////////////////////////////////////////////////////////////////////
// OnMButtonDown: handler for middle button down event
void CNaviCam::OnMButtonDown(u32 flags,int px,int py)
{
}
///////////////////////////////////////////////////////////////////////////////
// OnMButtonUp: handler for middle button up event
void CNaviCam::OnMButtonUp(u32 flags,int px,int py)
{
}
///////////////////////////////////////////////////////////////////////////////
// OnMouseMove: handler for mouse move (only called when middle button down)
void CNaviCam::OnMouseMove(u32 flags,int px,int py)
{
}

View File

@ -1,46 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////////
// navicam.h
//
// - header containing NaviCam class, used to produce MAX style navigation controls
/////////////////////////////////////////////////////////////////////////////////////
#ifndef _NAVICAM_H
#define _NAVICAM_H
#include "res/res.h"
#include "Camera.h"
/////////////////////////////////////////////////////////////////////////////////////
// CNaviCam: MAX style navigation controller
class CNaviCam
{
public:
// constructor
CNaviCam();
// handler for wheel scroll event - dir is positive for
// upward scroll (away from user), or negative for downward scroll (towards
// user)
void OnMouseWheelScroll(u32 flags,int px,int py,float dir);
// handler for middle button down event
void OnMButtonDown(u32 flags,int px,int py);
// handler for middle button up event
void OnMButtonUp(u32 flags,int px,int py);
// handler for mouse move (only called when middle button down)
void OnMouseMove(u32 flags,int px,int py);
// return the regular camera object
CCamera& GetCamera() { return m_Camera; }
private:
// the regular camera object that defines FOV, orientation, etc
CCamera m_Camera;
// current zoom of camera
float m_CameraZoom;
};
extern CNaviCam g_NaviCam;
#endif
/////////////////////////////////////////////////////////////////////////////////////
// navicam.h
//
// - header containing NaviCam class, used to produce MAX style navigation controls
/////////////////////////////////////////////////////////////////////////////////////
#ifndef _NAVICAM_H
#define _NAVICAM_H
#include "res/res.h"
#include "Camera.h"
/////////////////////////////////////////////////////////////////////////////////////
// CNaviCam: MAX style navigation controller
class CNaviCam
{
public:
// constructor
CNaviCam();
// handler for wheel scroll event - dir is positive for
// upward scroll (away from user), or negative for downward scroll (towards
// user)
void OnMouseWheelScroll(u32 flags,int px,int py,float dir);
// handler for middle button down event
void OnMButtonDown(u32 flags,int px,int py);
// handler for middle button up event
void OnMButtonUp(u32 flags,int px,int py);
// handler for mouse move (only called when middle button down)
void OnMouseMove(u32 flags,int px,int py);
// return the regular camera object
CCamera& GetCamera() { return m_Camera; }
private:
// the regular camera object that defines FOV, orientation, etc
CCamera m_Camera;
// current zoom of camera
float m_CameraZoom;
};
extern CNaviCam g_NaviCam;
#endif

View File

@ -1,46 +1,46 @@
// NavigatePropPage.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "NavigatePropPage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNavigatePropPage property page
IMPLEMENT_DYNCREATE(CNavigatePropPage, CPropertyPage)
CNavigatePropPage::CNavigatePropPage() : CPropertyPage(CNavigatePropPage::IDD)
{
//{{AFX_DATA_INIT(CNavigatePropPage)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
CNavigatePropPage::~CNavigatePropPage()
{
}
void CNavigatePropPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNavigatePropPage)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CNavigatePropPage, CPropertyPage)
//{{AFX_MSG_MAP(CNavigatePropPage)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNavigatePropPage message handlers
// NavigatePropPage.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "NavigatePropPage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNavigatePropPage property page
IMPLEMENT_DYNCREATE(CNavigatePropPage, CPropertyPage)
CNavigatePropPage::CNavigatePropPage() : CPropertyPage(CNavigatePropPage::IDD)
{
//{{AFX_DATA_INIT(CNavigatePropPage)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
CNavigatePropPage::~CNavigatePropPage()
{
}
void CNavigatePropPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNavigatePropPage)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CNavigatePropPage, CPropertyPage)
//{{AFX_MSG_MAP(CNavigatePropPage)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNavigatePropPage message handlers

View File

@ -1,51 +1,51 @@
#if !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
#define AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// NavigatePropPage.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CNavigatePropPage dialog
class CNavigatePropPage : public CPropertyPage
{
DECLARE_DYNCREATE(CNavigatePropPage)
// Construction
public:
CNavigatePropPage();
~CNavigatePropPage();
// Dialog Data
//{{AFX_DATA(CNavigatePropPage)
enum { IDD = IDD_PROPPAGE_NAVIGATION };
int m_ScrollSpeed;
// NOTE - ClassWizard will add data members here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_DATA
// Overrides
// ClassWizard generate virtual function overrides
//{{AFX_VIRTUAL(CNavigatePropPage)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CNavigatePropPage)
// NOTE: the ClassWizard will add member functions here
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
#if !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
#define AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// NavigatePropPage.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CNavigatePropPage dialog
class CNavigatePropPage : public CPropertyPage
{
DECLARE_DYNCREATE(CNavigatePropPage)
// Construction
public:
CNavigatePropPage();
~CNavigatePropPage();
// Dialog Data
//{{AFX_DATA(CNavigatePropPage)
enum { IDD = IDD_PROPPAGE_NAVIGATION };
int m_ScrollSpeed;
// NOTE - ClassWizard will add data members here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_DATA
// Overrides
// ClassWizard generate virtual function overrides
//{{AFX_VIRTUAL(CNavigatePropPage)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CNavigatePropPage)
// NOTE: the ClassWizard will add member functions here
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)

View File

@ -1,50 +1,50 @@
// OptionsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "OptionsDlg.h"
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg dialog
COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
: CDialog(COptionsDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(COptionsDlg)
m_ScrollSpeed = 0;
//}}AFX_DATA_INIT
}
void COptionsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COptionsDlg)
DDX_Slider(pDX, IDC_SLIDER_RTSSCROLLSPEED, m_ScrollSpeed);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
//{{AFX_MSG_MAP(COptionsDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg message handlers
BOOL COptionsDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// set up scroll speed slider
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
sliderctrl->SetRange(0,10,TRUE);
sliderctrl->SetPos(m_ScrollSpeed);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// OptionsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "OptionsDlg.h"
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg dialog
COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
: CDialog(COptionsDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(COptionsDlg)
m_ScrollSpeed = 0;
//}}AFX_DATA_INIT
}
void COptionsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COptionsDlg)
DDX_Slider(pDX, IDC_SLIDER_RTSSCROLLSPEED, m_ScrollSpeed);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
//{{AFX_MSG_MAP(COptionsDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg message handlers
BOOL COptionsDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// set up scroll speed slider
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
sliderctrl->SetRange(0,10,TRUE);
sliderctrl->SetPos(m_ScrollSpeed);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

View File

@ -1,46 +1,46 @@
#if !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
#define AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OptionsDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg dialog
class COptionsDlg : public CDialog
{
// Construction
public:
COptionsDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(COptionsDlg)
enum { IDD = IDD_DIALOG_OPTIONS };
int m_ScrollSpeed;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COptionsDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(COptionsDlg)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
#if !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
#define AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OptionsDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg dialog
class COptionsDlg : public CDialog
{
// Construction
public:
COptionsDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(COptionsDlg)
enum { IDD = IDD_DIALOG_OPTIONS };
int m_ScrollSpeed;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COptionsDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(COptionsDlg)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)

View File

@ -1,67 +1,67 @@
// OptionsPropSheet.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "OptionsPropSheet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COptionsPropSheet
IMPLEMENT_DYNAMIC(COptionsPropSheet, CPropertySheet)
COptionsPropSheet::COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
AddPage(&m_NavigatePage);
AddPage(&m_ShadowsPage);
}
COptionsPropSheet::COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
AddPage(&m_NavigatePage);
AddPage(&m_ShadowsPage);
}
COptionsPropSheet::~COptionsPropSheet()
{
}
BEGIN_MESSAGE_MAP(COptionsPropSheet, CPropertySheet)
//{{AFX_MSG_MAP(COptionsPropSheet)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COptionsPropSheet message handlers
BOOL COptionsPropSheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
// NAVIGATION CONTROLS:
// setup scroll speed slider
CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
sliderctrl->SetRange(0,10,TRUE);
sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
// SHADOW CONTROLS:
// setup checkbox
// CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
// sliderctrl->SetRange(0,10,TRUE);
// sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
// setup shadow colour
// setup quality slider
return bResult;
}
// OptionsPropSheet.cpp : implementation file
//
#include "stdafx.h"
#include "ScEd.h"
#include "OptionsPropSheet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COptionsPropSheet
IMPLEMENT_DYNAMIC(COptionsPropSheet, CPropertySheet)
COptionsPropSheet::COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
AddPage(&m_NavigatePage);
AddPage(&m_ShadowsPage);
}
COptionsPropSheet::COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
AddPage(&m_NavigatePage);
AddPage(&m_ShadowsPage);
}
COptionsPropSheet::~COptionsPropSheet()
{
}
BEGIN_MESSAGE_MAP(COptionsPropSheet, CPropertySheet)
//{{AFX_MSG_MAP(COptionsPropSheet)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COptionsPropSheet message handlers
BOOL COptionsPropSheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
// NAVIGATION CONTROLS:
// setup scroll speed slider
CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
sliderctrl->SetRange(0,10,TRUE);
sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
// SHADOW CONTROLS:
// setup checkbox
// CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
// sliderctrl->SetRange(0,10,TRUE);
// sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
// setup shadow colour
// setup quality slider
return bResult;
}

View File

@ -1,57 +1,57 @@
#if !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
#define AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OptionsPropSheet.h : header file
//
#include "NavigatePropPage.h"
#include "ShadowsPropPage.h"
/////////////////////////////////////////////////////////////////////////////
// COptionsPropSheet
class COptionsPropSheet : public CPropertySheet
{
DECLARE_DYNAMIC(COptionsPropSheet)
// Construction
public:
COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
// Attributes
public:
CNavigatePropPage m_NavigatePage;
CShadowsPropPage m_ShadowsPage;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COptionsPropSheet)
public:
virtual BOOL OnInitDialog();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~COptionsPropSheet();
// Generated message map functions
protected:
//{{AFX_MSG(COptionsPropSheet)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
#if !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
#define AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OptionsPropSheet.h : header file
//
#include "NavigatePropPage.h"
#include "ShadowsPropPage.h"
/////////////////////////////////////////////////////////////////////////////
// COptionsPropSheet
class COptionsPropSheet : public CPropertySheet
{
DECLARE_DYNAMIC(COptionsPropSheet)
// Construction
public:
COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
// Attributes
public:
CNavigatePropPage m_NavigatePage;
CShadowsPropPage m_ShadowsPage;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COptionsPropSheet)
public:
virtual BOOL OnInitDialog();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~COptionsPropSheet();
// Generated message map functions
protected:
//{{AFX_MSG(COptionsPropSheet)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)

View File

@ -1,56 +1,56 @@
#include "PaintObjectCommand.h"
#include "UnitManager.h"
#include "ObjectEntry.h"
#include "Model.h"
#include "BaseEntity.h"
#include "BaseEntityCollection.h"
#include "EntityManager.h"
CPaintObjectCommand::CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform)
: m_Object(object), m_Transform(transform), m_Unit(0)
{
}
CPaintObjectCommand::~CPaintObjectCommand()
{
}
void CPaintObjectCommand::Execute()
{
// create new unit
m_Unit=new CUnit(m_Object,m_Object->m_Model->Clone());
m_Unit->GetModel()->SetTransform(m_Transform);
// add this unit to list of units stored in unit manager
g_UnitMan.AddUnit(m_Unit);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// Finalize: notification that command has finished (ie object stopped rotating) - convert
// unit to entity if there's a template for it
void CPaintObjectCommand::Finalize()
{
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_Object);
if( templateObject )
{
CVector3D orient = m_Unit->GetModel()->GetTransform().GetIn();
CVector3D position = m_Unit->GetModel()->GetTransform().GetTranslation();
g_UnitMan.RemoveUnit(m_Unit);
g_EntityManager.create( templateObject, position, atan2( orient.X, orient.Z ) );
}
}
void CPaintObjectCommand::Undo()
{
// remove model from unit managers list
g_UnitMan.RemoveUnit(m_Unit);
}
void CPaintObjectCommand::Redo()
{
// add the unit back to the unit manager
g_UnitMan.AddUnit(m_Unit);
}
#include "PaintObjectCommand.h"
#include "UnitManager.h"
#include "ObjectEntry.h"
#include "Model.h"
#include "BaseEntity.h"
#include "BaseEntityCollection.h"
#include "EntityManager.h"
CPaintObjectCommand::CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform)
: m_Object(object), m_Transform(transform), m_Unit(0)
{
}
CPaintObjectCommand::~CPaintObjectCommand()
{
}
void CPaintObjectCommand::Execute()
{
// create new unit
m_Unit=new CUnit(m_Object,m_Object->m_Model->Clone());
m_Unit->GetModel()->SetTransform(m_Transform);
// add this unit to list of units stored in unit manager
g_UnitMan.AddUnit(m_Unit);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// Finalize: notification that command has finished (ie object stopped rotating) - convert
// unit to entity if there's a template for it
void CPaintObjectCommand::Finalize()
{
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_Object);
if( templateObject )
{
CVector3D orient = m_Unit->GetModel()->GetTransform().GetIn();
CVector3D position = m_Unit->GetModel()->GetTransform().GetTranslation();
g_UnitMan.RemoveUnit(m_Unit);
g_EntityManager.create( templateObject, position, atan2( orient.X, orient.Z ) );
}
}
void CPaintObjectCommand::Undo()
{
// remove model from unit managers list
g_UnitMan.RemoveUnit(m_Unit);
}
void CPaintObjectCommand::Redo()
{
// add the unit back to the unit manager
g_UnitMan.AddUnit(m_Unit);
}

View File

@ -1,46 +1,46 @@
#ifndef _PAINTOBJECTCOMMAND_H
#define _PAINTOBJECTCOMMAND_H
#include "Command.h"
#include "Matrix3D.h"
class CUnit;
class CObjectEntry;
class CPaintObjectCommand : public CCommand
{
public:
// constructor, destructor
CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform);
~CPaintObjectCommand();
// return the texture name of this command
const char* GetName() const { return "Add Unit"; }
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return false; }
// undo
void Undo();
// redo
void Redo();
// notification that command has finished (ie object stopped rotating) - convert
// unit to entity if there's a template for it
void Finalize();
// return unit added to world
CUnit* GetUnit() { return m_Unit; }
private:
// unit to add to world
CUnit* m_Unit;
// object to paint
CObjectEntry* m_Object;
// model transformation
CMatrix3D m_Transform;
};
#endif
#ifndef _PAINTOBJECTCOMMAND_H
#define _PAINTOBJECTCOMMAND_H
#include "Command.h"
#include "Matrix3D.h"
class CUnit;
class CObjectEntry;
class CPaintObjectCommand : public CCommand
{
public:
// constructor, destructor
CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform);
~CPaintObjectCommand();
// return the texture name of this command
const char* GetName() const { return "Add Unit"; }
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return false; }
// undo
void Undo();
// redo
void Redo();
// notification that command has finished (ie object stopped rotating) - convert
// unit to entity if there's a template for it
void Finalize();
// return unit added to world
CUnit* GetUnit() { return m_Unit; }
private:
// unit to add to world
CUnit* m_Unit;
// object to paint
CObjectEntry* m_Object;
// model transformation
CMatrix3D m_Transform;
};
#endif

View File

@ -1,85 +1,85 @@
#include "timer.h"
#include "CommandManager.h"
#include "ObjectEntry.h"
#include "Unit.h"
#include "PaintObjectTool.h"
#include "MiniPatch.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ObjectManager.h"
#include "PaintObjectCommand.h"
// rotate object at 180 degrees each second when applying to terrain
#define ROTATION_SPEED PI
// default tool instance
CPaintObjectTool CPaintObjectTool::m_PaintObjectTool;
CPaintObjectTool::CPaintObjectTool() : m_PaintCmd(0), m_Rotation(0)
{
m_BrushSize=0;
}
void CPaintObjectTool::BuildTransform()
{
m_ObjectTransform.SetIdentity();
m_ObjectTransform.RotateY(m_Rotation);
m_ObjectTransform.Translate(m_Position);
}
void CPaintObjectTool::PaintSelection()
{
if (m_PaintCmd) {
// already applied object to terrain, now we're just rotating it
double curtime=get_time();
m_Rotation+=ROTATION_SPEED*float(curtime-m_LastTriggerTime);
BuildTransform();
m_PaintCmd->GetUnit()->GetModel()->SetTransform(m_ObjectTransform);
m_LastTriggerTime=curtime;
} else {
m_Rotation=0;
m_Position=m_SelectionPoint;
m_LastTriggerTime=get_time();
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
if (obj && obj->m_Model) {
// get up to date transform
BuildTransform();
// now paint the object
m_PaintCmd=new CPaintObjectCommand(obj,m_ObjectTransform);
m_PaintCmd->Execute();
g_CmdMan.Append(m_PaintCmd);
}
}
}
void CPaintObjectTool::OnLButtonUp(unsigned int flags,int px,int py)
{
CBrushTool::OnLButtonUp(flags,px,py);
// terminate current command, if we've got one
if (m_PaintCmd) {
m_PaintCmd->Finalize();
m_PaintCmd=0;
m_Rotation=0;
}
}
void CPaintObjectTool::OnDraw()
{
// don't draw object if we're currently rotating it on the terrain
if (m_PaintCmd) return;
// don't draw unless we have a valid object to apply
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
if (!obj || !obj->m_Model) return;
// try to get object transform, in world space
m_Position=m_SelectionPoint;
BuildTransform();
// render the current object at the same position as the selected tile
m_Model=obj->m_Model;
m_Model->SetTransform(m_ObjectTransform);
g_Renderer.Submit(m_Model);
}
#include "timer.h"
#include "CommandManager.h"
#include "ObjectEntry.h"
#include "Unit.h"
#include "PaintObjectTool.h"
#include "MiniPatch.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ObjectManager.h"
#include "PaintObjectCommand.h"
// rotate object at 180 degrees each second when applying to terrain
#define ROTATION_SPEED PI
// default tool instance
CPaintObjectTool CPaintObjectTool::m_PaintObjectTool;
CPaintObjectTool::CPaintObjectTool() : m_PaintCmd(0), m_Rotation(0)
{
m_BrushSize=0;
}
void CPaintObjectTool::BuildTransform()
{
m_ObjectTransform.SetIdentity();
m_ObjectTransform.RotateY(m_Rotation);
m_ObjectTransform.Translate(m_Position);
}
void CPaintObjectTool::PaintSelection()
{
if (m_PaintCmd) {
// already applied object to terrain, now we're just rotating it
double curtime=get_time();
m_Rotation+=ROTATION_SPEED*float(curtime-m_LastTriggerTime);
BuildTransform();
m_PaintCmd->GetUnit()->GetModel()->SetTransform(m_ObjectTransform);
m_LastTriggerTime=curtime;
} else {
m_Rotation=0;
m_Position=m_SelectionPoint;
m_LastTriggerTime=get_time();
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
if (obj && obj->m_Model) {
// get up to date transform
BuildTransform();
// now paint the object
m_PaintCmd=new CPaintObjectCommand(obj,m_ObjectTransform);
m_PaintCmd->Execute();
g_CmdMan.Append(m_PaintCmd);
}
}
}
void CPaintObjectTool::OnLButtonUp(unsigned int flags,int px,int py)
{
CBrushTool::OnLButtonUp(flags,px,py);
// terminate current command, if we've got one
if (m_PaintCmd) {
m_PaintCmd->Finalize();
m_PaintCmd=0;
m_Rotation=0;
}
}
void CPaintObjectTool::OnDraw()
{
// don't draw object if we're currently rotating it on the terrain
if (m_PaintCmd) return;
// don't draw unless we have a valid object to apply
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
if (!obj || !obj->m_Model) return;
// try to get object transform, in world space
m_Position=m_SelectionPoint;
BuildTransform();
// render the current object at the same position as the selected tile
m_Model=obj->m_Model;
m_Model->SetTransform(m_ObjectTransform);
g_Renderer.Submit(m_Model);
}

View File

@ -1,57 +1,57 @@
#ifndef _PAINTOBJECTTOOL_H
#define _PAINTOBJECTTOOL_H
#include <set>
#include "res/res.h"
#include "BrushTool.h"
#include "Vector3D.h"
#include "Matrix3D.h"
#include "Model.h"
class CObjectEntry;
class CPaintObjectCommand;
class CPaintObjectTool : public CBrushTool
{
public:
CPaintObjectTool();
// draw this tool
void OnDraw();
// callback for left button up event
void OnLButtonUp(unsigned int flags,int px,int py);
// tool triggered via left mouse button; paint current selection
void OnTriggerLeft() { PaintSelection(); }
// allow multiple triggers by click and hold - subsequent triggers rotate
// the last applied object, rather than adding new objects
bool SupportDragTrigger() { return true; }
// get the default paint model instance
static CPaintObjectTool* GetTool() { return &m_PaintObjectTool; }
private:
// apply current object to current selection
void PaintSelection();
// build the m_ObjectTransform member from current tile selection
void BuildTransform();
// currently active command, or null if no object currently being applied
CPaintObjectCommand* m_PaintCmd;
// Y-rotation of object currently being applied
float m_Rotation;
// position of object when first dropped
CVector3D m_Position;
// time of last trigger
double m_LastTriggerTime;
// current transform of selected object
CMatrix3D m_ObjectTransform;
// model of current object
CModel* m_Model;
// default tool instance
static CPaintObjectTool m_PaintObjectTool;
};
#endif
#ifndef _PAINTOBJECTTOOL_H
#define _PAINTOBJECTTOOL_H
#include <set>
#include "res/res.h"
#include "BrushTool.h"
#include "Vector3D.h"
#include "Matrix3D.h"
#include "Model.h"
class CObjectEntry;
class CPaintObjectCommand;
class CPaintObjectTool : public CBrushTool
{
public:
CPaintObjectTool();
// draw this tool
void OnDraw();
// callback for left button up event
void OnLButtonUp(unsigned int flags,int px,int py);
// tool triggered via left mouse button; paint current selection
void OnTriggerLeft() { PaintSelection(); }
// allow multiple triggers by click and hold - subsequent triggers rotate
// the last applied object, rather than adding new objects
bool SupportDragTrigger() { return true; }
// get the default paint model instance
static CPaintObjectTool* GetTool() { return &m_PaintObjectTool; }
private:
// apply current object to current selection
void PaintSelection();
// build the m_ObjectTransform member from current tile selection
void BuildTransform();
// currently active command, or null if no object currently being applied
CPaintObjectCommand* m_PaintCmd;
// Y-rotation of object currently being applied
float m_Rotation;
// position of object when first dropped
CVector3D m_Position;
// time of last trigger
double m_LastTriggerTime;
// current transform of selected object
CMatrix3D m_ObjectTransform;
// model of current object
CModel* m_Model;
// default tool instance
static CPaintObjectTool m_PaintObjectTool;
};
#endif

View File

@ -1,97 +1,97 @@
#include "PaintTextureCommand.h"
#include "UIGlobals.h"
#include "MiniMap.h"
#include "textureEntry.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
CPaintTextureCommand::CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2])
{
m_Texture=tex;
m_BrushSize=brushSize;
m_SelectionCentre[0]=selectionCentre[0];
m_SelectionCentre[1]=selectionCentre[1];
}
CPaintTextureCommand::~CPaintTextureCommand()
{
}
void CPaintTextureCommand::Execute()
{
int r=m_BrushSize;
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
u32 mapSize=g_Terrain.GetVerticesPerSide();
// get range of tiles affected by brush
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
// iterate through tiles affected by brush
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
// try and get minipatch, if there is one
CMiniPatch* nmp=g_Terrain.GetTile(i,j);
if (nmp) {
nmp->Tex1=m_Texture ? m_Texture->m_Handle : 0;
nmp->Tex1Priority=m_Texture ? ((int) m_Texture->m_Type) : 0;
}
}
}
// invalidate affected patches
int px0=clamp(-1+(x0/16),0,patchesPerSide);
int px1=clamp(1+(x1/16),0,patchesPerSide);
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
int pz1=clamp(1+(z1/16),0,patchesPerSide);
for (j=pz0;j<pz1;j++) {
for (int i=px0;i<px1;i++) {
CPatch* patch=g_Terrain.GetPatch(i,j);
patch->SetDirty(RENDERDATA_UPDATE_INDICES);
}
}
// rebuild this bit of the minimap
int w=1+2*m_BrushSize;
int x=m_SelectionCentre[1]-m_BrushSize;
if (x<0) {
w+=x;
x=0;
}
int h=1+2*m_BrushSize;
int y=m_SelectionCentre[0]-m_BrushSize;
if (y<0) {
h+=y;
y=0;
}
g_MiniMap.Rebuild(x,y,w,h);
}
void CPaintTextureCommand::Undo()
{
ApplyDataToSelection(m_DataIn);
}
void CPaintTextureCommand::Redo()
{
ApplyDataToSelection(m_DataOut);
}
void CPaintTextureCommand::ApplyDataToSelection(const CArray2D<TextureSet>& data)
{
}
#include "PaintTextureCommand.h"
#include "UIGlobals.h"
#include "MiniMap.h"
#include "textureEntry.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
CPaintTextureCommand::CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2])
{
m_Texture=tex;
m_BrushSize=brushSize;
m_SelectionCentre[0]=selectionCentre[0];
m_SelectionCentre[1]=selectionCentre[1];
}
CPaintTextureCommand::~CPaintTextureCommand()
{
}
void CPaintTextureCommand::Execute()
{
int r=m_BrushSize;
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
u32 mapSize=g_Terrain.GetVerticesPerSide();
// get range of tiles affected by brush
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
// iterate through tiles affected by brush
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
// try and get minipatch, if there is one
CMiniPatch* nmp=g_Terrain.GetTile(i,j);
if (nmp) {
nmp->Tex1=m_Texture ? m_Texture->m_Handle : 0;
nmp->Tex1Priority=m_Texture ? ((int) m_Texture->m_Type) : 0;
}
}
}
// invalidate affected patches
int px0=clamp(-1+(x0/16),0,patchesPerSide);
int px1=clamp(1+(x1/16),0,patchesPerSide);
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
int pz1=clamp(1+(z1/16),0,patchesPerSide);
for (j=pz0;j<pz1;j++) {
for (int i=px0;i<px1;i++) {
CPatch* patch=g_Terrain.GetPatch(i,j);
patch->SetDirty(RENDERDATA_UPDATE_INDICES);
}
}
// rebuild this bit of the minimap
int w=1+2*m_BrushSize;
int x=m_SelectionCentre[1]-m_BrushSize;
if (x<0) {
w+=x;
x=0;
}
int h=1+2*m_BrushSize;
int y=m_SelectionCentre[0]-m_BrushSize;
if (y<0) {
h+=y;
y=0;
}
g_MiniMap.Rebuild(x,y,w,h);
}
void CPaintTextureCommand::Undo()
{
ApplyDataToSelection(m_DataIn);
}
void CPaintTextureCommand::Redo()
{
ApplyDataToSelection(m_DataOut);
}
void CPaintTextureCommand::ApplyDataToSelection(const CArray2D<TextureSet>& data)
{
}

View File

@ -1,68 +1,68 @@
#ifndef _PAINTTEXTURECOMMAND_H
#define _PAINTTEXTURECOMMAND_H
#include <set>
#include "res/res.h"
#include "Command.h"
#include "Array2D.h"
struct TextureSet
{
Handle m_Texture;
int m_Priority;
};
class CTextureEntry;
class CPaintTextureCommand : public CCommand
{
public:
// constructor, destructor
CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2]);
~CPaintTextureCommand();
// return the texture name of this command
const char* GetName() const { return "Apply Texture"; }
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return true; }
// undo
void Undo();
// redo
void Redo();
private:
bool IsValidDataIndex(const CArray2D<TextureSet>& array,int x,int y) {
if (x<0 || y<0) return 0;
int ix=x-m_SelectionOrigin[0];
int iy=y-m_SelectionOrigin[1];
return ix>=0 && ix<array.usize() && iy>=0 && iy<array.vsize();
}
TextureSet* DataIn(int x,int y) {
return IsValidDataIndex(m_DataIn,x,y) ? &m_DataIn(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
}
TextureSet* DataOut(int x,int y) {
return IsValidDataIndex(m_DataOut,x,y) ? &m_DataOut(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
}
void ApplyDataToSelection(const CArray2D<TextureSet>& data);
// texture being painted
CTextureEntry* m_Texture;
// size of brush
int m_BrushSize;
// centre of brush
int m_SelectionCentre[2];
// origin of data set
int m_SelectionOrigin[2];
// input data (textures applied to the selection)
CArray2D<TextureSet> m_DataIn;
// output data (new textures applied to the selection after painting)
CArray2D<TextureSet> m_DataOut;
};
#endif
#ifndef _PAINTTEXTURECOMMAND_H
#define _PAINTTEXTURECOMMAND_H
#include <set>
#include "res/res.h"
#include "Command.h"
#include "Array2D.h"
struct TextureSet
{
Handle m_Texture;
int m_Priority;
};
class CTextureEntry;
class CPaintTextureCommand : public CCommand
{
public:
// constructor, destructor
CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2]);
~CPaintTextureCommand();
// return the texture name of this command
const char* GetName() const { return "Apply Texture"; }
// execute this command
void Execute();
// can undo command?
bool IsUndoable() const { return true; }
// undo
void Undo();
// redo
void Redo();
private:
bool IsValidDataIndex(const CArray2D<TextureSet>& array,int x,int y) {
if (x<0 || y<0) return 0;
int ix=x-m_SelectionOrigin[0];
int iy=y-m_SelectionOrigin[1];
return ix>=0 && ix<array.usize() && iy>=0 && iy<array.vsize();
}
TextureSet* DataIn(int x,int y) {
return IsValidDataIndex(m_DataIn,x,y) ? &m_DataIn(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
}
TextureSet* DataOut(int x,int y) {
return IsValidDataIndex(m_DataOut,x,y) ? &m_DataOut(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
}
void ApplyDataToSelection(const CArray2D<TextureSet>& data);
// texture being painted
CTextureEntry* m_Texture;
// size of brush
int m_BrushSize;
// centre of brush
int m_SelectionCentre[2];
// origin of data set
int m_SelectionOrigin[2];
// input data (textures applied to the selection)
CArray2D<TextureSet> m_DataIn;
// output data (new textures applied to the selection after painting)
CArray2D<TextureSet> m_DataOut;
};
#endif

View File

@ -1,21 +1,21 @@
#include "CommandManager.h"
#include "TextureEntry.h"
#include "PaintTextureTool.h"
#include "PaintTextureCommand.h"
// default tool instance
CPaintTextureTool CPaintTextureTool::m_PaintTextureTool;
CPaintTextureTool::CPaintTextureTool()
{
m_SelectedTexture=0;
}
void CPaintTextureTool::PaintSelection()
{
// apply current texture to current selection
CPaintTextureCommand* paintCmd=new CPaintTextureCommand(m_SelectedTexture,m_BrushSize,m_SelectionCentre);
g_CmdMan.Execute(paintCmd);
}
#include "CommandManager.h"
#include "TextureEntry.h"
#include "PaintTextureTool.h"
#include "PaintTextureCommand.h"
// default tool instance
CPaintTextureTool CPaintTextureTool::m_PaintTextureTool;
CPaintTextureTool::CPaintTextureTool()
{
m_SelectedTexture=0;
}
void CPaintTextureTool::PaintSelection()
{
// apply current texture to current selection
CPaintTextureCommand* paintCmd=new CPaintTextureCommand(m_SelectedTexture,m_BrushSize,m_SelectionCentre);
g_CmdMan.Execute(paintCmd);
}

View File

@ -1,43 +1,43 @@
#ifndef _PAINTTEXTURETOOL_H
#define _PAINTTEXTURETOOL_H
#include <set>
#include "res/res.h"
#include "BrushTool.h"
class CTextureEntry;
class CPaintTextureTool : public CBrushTool
{
public:
enum { MAX_BRUSH_SIZE=8 };
public:
CPaintTextureTool();
// tool triggered via left mouse button; paint current selection
void OnTriggerLeft() { PaintSelection(); }
// set current painting texture
void SetSelectedTexture(CTextureEntry* tex) { m_SelectedTexture=tex; }
// get current painting texture
CTextureEntry* GetSelectedTexture() { return m_SelectedTexture; }
// allow multiple triggers by click and drag
bool SupportDragTrigger() { return true; }
// get the default paint texture instance
static CPaintTextureTool* GetTool() { return &m_PaintTextureTool; }
private:
// apply current texture to current selection
void PaintSelection();
// currently selected texture for painting
CTextureEntry* m_SelectedTexture;
// default tool instance
static CPaintTextureTool m_PaintTextureTool;
};
#endif
#ifndef _PAINTTEXTURETOOL_H
#define _PAINTTEXTURETOOL_H
#include <set>
#include "res/res.h"
#include "BrushTool.h"
class CTextureEntry;
class CPaintTextureTool : public CBrushTool
{
public:
enum { MAX_BRUSH_SIZE=8 };
public:
CPaintTextureTool();
// tool triggered via left mouse button; paint current selection
void OnTriggerLeft() { PaintSelection(); }
// set current painting texture
void SetSelectedTexture(CTextureEntry* tex) { m_SelectedTexture=tex; }
// get current painting texture
CTextureEntry* GetSelectedTexture() { return m_SelectedTexture; }
// allow multiple triggers by click and drag
bool SupportDragTrigger() { return true; }
// get the default paint texture instance
static CPaintTextureTool* GetTool() { return &m_PaintTextureTool; }
private:
// apply current texture to current selection
void PaintSelection();
// currently selected texture for painting
CTextureEntry* m_SelectedTexture;
// default tool instance
static CPaintTextureTool m_PaintTextureTool;
};
#endif

View File

@ -1,36 +1,36 @@
#include "RaiseElevationCommand.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
CRaiseElevationCommand::CRaiseElevationCommand(int deltaheight,int brushSize,int selectionCentre[2])
: CAlterElevationCommand(brushSize,selectionCentre), m_DeltaHeight(deltaheight)
{
}
CRaiseElevationCommand::~CRaiseElevationCommand()
{
}
void CRaiseElevationCommand::CalcDataOut(int x0,int x1,int z0,int z1)
{
// fill output data
u32 mapSize=g_Terrain.GetVerticesPerSide();
int i,j;
for (j=z0;j<=z1;j++) {
for (i=x0;i<=x1;i++) {
u32 input=g_Terrain.GetHeightMap()[j*mapSize+i];
u16 output=clamp(input+m_DeltaHeight,0,65535);
m_DataOut(i-x0,j-z0)=output;
}
}
}
#include "RaiseElevationCommand.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
inline int clamp(int x,int min,int max)
{
if (x<min) return min;
else if (x>max) return max;
else return x;
}
CRaiseElevationCommand::CRaiseElevationCommand(int deltaheight,int brushSize,int selectionCentre[2])
: CAlterElevationCommand(brushSize,selectionCentre), m_DeltaHeight(deltaheight)
{
}
CRaiseElevationCommand::~CRaiseElevationCommand()
{
}
void CRaiseElevationCommand::CalcDataOut(int x0,int x1,int z0,int z1)
{
// fill output data
u32 mapSize=g_Terrain.GetVerticesPerSide();
int i,j;
for (j=z0;j<=z1;j++) {
for (i=x0;i<=x1;i++) {
u32 input=g_Terrain.GetHeightMap()[j*mapSize+i];
u16 output=clamp(input+m_DeltaHeight,0,65535);
m_DataOut(i-x0,j-z0)=output;
}
}
}

Some files were not shown because too many files have changed in this diff Show More