257 lines
6.6 KiB
C++
257 lines
6.6 KiB
C++
// -*- C++ -*-
|
|
|
|
#ifndef MBOSTOCK_MODEL_H
|
|
#define MBOSTOCK_MODEL_H
|
|
|
|
#include <OpenGL/glu.h>
|
|
|
|
#include "physics/shape.h"
|
|
#include "physics/vector.h"
|
|
|
|
namespace mbostock {
|
|
|
|
class Material;
|
|
|
|
/**
|
|
* A generic base class for OpenGL models. Provides a set of convenience
|
|
* methods based on the Vector class. The constructor should not assume that
|
|
* OpenGL is initialized; instead, use the initialize method. Note that a
|
|
* model may be initialized multiple times if the OpenGL context is destroyed
|
|
* and recreated, as is the case with resizing the window or toggling
|
|
* fullscreen mode.
|
|
*/
|
|
class Model {
|
|
public:
|
|
virtual ~Model() {}
|
|
|
|
/** Initializes any OpenGL state used by the model. */
|
|
virtual void initialize() {}
|
|
|
|
/** Displays the model. */
|
|
virtual void display() = 0;
|
|
|
|
protected:
|
|
|
|
/** A convenience wrapper for glTranslatef. */
|
|
inline void glTranslatev(const Vector& v) const {
|
|
glTranslatef(v.x, v.y, v.z);
|
|
}
|
|
|
|
/** A convenience wrapper for glRotatef. */
|
|
inline void glRotatev(float angle, const Vector& axis) const {
|
|
glRotatef(angle, axis.x, axis.y, axis.z);
|
|
}
|
|
|
|
/** A convenience wrapper for glVertex3f. */
|
|
inline void glVertexv(const Vector& v) const {
|
|
glVertex3f(v.x, v.y, v.z);
|
|
}
|
|
|
|
/** A convenience wrapper for glTexCoord2f. Uses the x and y coordinate. */
|
|
inline void glTexCoordv(const Vector& v) const {
|
|
glTexCoord2f(v.x, v.y);
|
|
}
|
|
|
|
/** A convenience wrapper for glNormal3f. */
|
|
inline void glNormalv(const Vector& v) const {
|
|
glNormal3f(v.x, v.y, v.z);
|
|
}
|
|
|
|
/** A convenience wrapper for glMaterialfv. */
|
|
inline void glMaterialv(GLenum face, GLenum pname, const Vector& v) const {
|
|
GLfloat params[] = { v.x, v.y, v.z, 1.f };
|
|
glMaterialfv(face, pname, params);
|
|
}
|
|
|
|
/** A convenience wrapper for glColor3f. */
|
|
inline void glColorv(const Vector& v) const {
|
|
glColor3f(v.x, v.y, v.z);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A model for Wedge. A separate material may be specified for the top face of
|
|
* the wedge.
|
|
*/
|
|
class WedgeModel : public Model {
|
|
public:
|
|
WedgeModel(const Wedge& wedge);
|
|
|
|
virtual void display();
|
|
|
|
void setMaterial(const Material& m);
|
|
void setTopMaterial(const Material& m);
|
|
|
|
inline const Material& material() const { return *material_; }
|
|
const Material& topMaterial() const;
|
|
|
|
private:
|
|
const Wedge& wedge_;
|
|
const Material* material_;
|
|
const Material* topMaterial_;
|
|
};
|
|
|
|
/**
|
|
* A model for AxisAlignedBox. A separate material may be specified for the
|
|
* top face of the box. In addition, the texture may be oriented along either
|
|
* the X or Z axis, and the texture may be offset (e.g., for escalatars).
|
|
*/
|
|
class AxisAlignedBoxModel : public Model {
|
|
public:
|
|
AxisAlignedBoxModel(const AxisAlignedBox& box);
|
|
|
|
virtual void display();
|
|
|
|
enum Orientation { POSITIVE_X, NEGATIVE_X, POSITIVE_Z, NEGATIVE_Z };
|
|
|
|
void setMaterial(const Material& m);
|
|
void setTopMaterial(const Material& m);
|
|
void setTexOffset(float u, float v);
|
|
void setTexOrientation(Orientation orientation);
|
|
|
|
inline const Material& material() const { return *material_; }
|
|
const Material& topMaterial() const;
|
|
|
|
private:
|
|
const AxisAlignedBox& box_;
|
|
const Material* material_;
|
|
const Material* topMaterial_;
|
|
Orientation orientation_;
|
|
float u_, v_;
|
|
};
|
|
|
|
/**
|
|
* A model for Box. A separate material may be specified for the top face of
|
|
* the box.
|
|
*/
|
|
class BoxModel : public Model {
|
|
public:
|
|
BoxModel(const Box& box);
|
|
|
|
virtual void display();
|
|
|
|
void setMaterial(const Material& m);
|
|
void setTopMaterial(const Material& m);
|
|
|
|
inline const Material& material() const { return *material_; }
|
|
const Material& topMaterial() const;
|
|
|
|
private:
|
|
const Box& box_;
|
|
const Material* material_;
|
|
const Material* topMaterial_;
|
|
};
|
|
|
|
/**
|
|
* A model for Quad. The texture coordinates may be specified explicitly, or
|
|
* they will be inferred from the vertex coordinates.
|
|
*/
|
|
class QuadModel : public Model {
|
|
public:
|
|
QuadModel(const Quad& quad);
|
|
|
|
virtual void display();
|
|
|
|
void setMaterial(const Material& m);
|
|
void setTexCoords(const Vector& t0, const Vector& t1,
|
|
const Vector& t2, const Vector& t3);
|
|
|
|
inline const Material& material() const { return *material_; }
|
|
|
|
private:
|
|
void displaySide(bool front);
|
|
|
|
const Quad& quad_;
|
|
const Material* material_;
|
|
Vector texCoords_[4];
|
|
};
|
|
|
|
/**
|
|
* A model for Triangle. The texture coordinates may be specified explicitly,
|
|
* or they will be inferred from the vertex coordinates.
|
|
*/
|
|
class TriangleModel : public Model {
|
|
public:
|
|
TriangleModel(const Triangle& triangle);
|
|
|
|
virtual void display();
|
|
|
|
void setMaterial(const Material& m);
|
|
void setTexCoords(const Vector& t0, const Vector& t1, const Vector& t2);
|
|
|
|
inline const Material& material() const { return *material_; }
|
|
|
|
private:
|
|
void displaySide(bool front);
|
|
|
|
const Triangle& triangle_;
|
|
const Material* material_;
|
|
Vector texCoords_[3];
|
|
};
|
|
|
|
/**
|
|
* A cylinder model. A separate material may be specified for the end caps. An
|
|
* additional Y-axis is required to orient the texture on the cylinder's
|
|
* surface; this axis must be orthogonal to the main axis of the cylinder. A
|
|
* reference to the Y-axis vector is retained so that changes to the Y-axis
|
|
* will be propagated to the displayed model.
|
|
*/
|
|
class CylinderModel : public Model {
|
|
public:
|
|
CylinderModel(const Cylinder& cylinder, const Vector& y);
|
|
virtual ~CylinderModel();
|
|
|
|
virtual void initialize();
|
|
virtual void display();
|
|
|
|
void setMaterial(const Material& m);
|
|
void setCapMaterial(const Material& m);
|
|
|
|
inline const Material& material() const { return *material_; }
|
|
const Material& capMaterial() const;
|
|
|
|
private:
|
|
float* orientation();
|
|
|
|
const Cylinder& cylinder_;
|
|
const Vector& y_;
|
|
const Material* material_;
|
|
const Material* capMaterial_;
|
|
GLUquadric* quadric_;
|
|
float orientation_[16];
|
|
};
|
|
|
|
/** A model for Sphere. */
|
|
class SphereModel : public Model {
|
|
public:
|
|
SphereModel(const Sphere& sphere);
|
|
virtual ~SphereModel();
|
|
|
|
virtual void initialize();
|
|
virtual void display();
|
|
|
|
void setMaterial(const Material& m);
|
|
inline const Material& material() const { return *material_; }
|
|
|
|
private:
|
|
float* orientation();
|
|
|
|
const Sphere& sphere_;
|
|
const Material* material_;
|
|
GLUquadric* quadric_;
|
|
float orientation_[16];
|
|
};
|
|
|
|
class Models {
|
|
public:
|
|
static Model* teapot();
|
|
static Model* icosahedron();
|
|
static Model* compile(Model* model);
|
|
|
|
private:
|
|
Models();
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|