// Static scenery such as trees
struct IScenery {
- virtual ~IScenery() {}
+ virtual ~IScenery() {}
- virtual void render() const = 0;
- virtual void setPosition(float x, float y, float z) = 0;
+ virtual void render() const = 0;
+ virtual void setPosition(float x, float y, float z) = 0;
};
typedef shared_ptr<IScenery> ISceneryPtr;
// The different types of cargo that may be carried
enum Cargo {
- COAL
+ COAL
};
// A station occupies one of more track segments and supplies and
// The information about which track segments it actually occupies
// are stored in the map
struct IStation {
- virtual ~IStation() {}
-
- // Return or set the name of the station
- // This is only used for the user's benefit and does not identify
- // the station in any way
- virtual const string& name() const = 0;
- virtual void setName(const string& aName) = 0;
-
- // A station has an ID that uniquely identifies it
- // Setting is allowed to support the map loader
- virtual int id() const = 0;
- virtual void setId(int anId) = 0;
-
- // A station has a random colour that is used to identify it when
- // the highlight is drawn
- typedef tuple<float, float, float> HighlightColour;
- virtual HighlightColour highlightColour() const = 0;
- virtual bool highlightVisible() const = 0;
- virtual void setHighlightVisible(bool onOff) = 0;
+ virtual ~IStation() {}
+
+ // Return or set the name of the station
+ // This is only used for the user's benefit and does not identify
+ // the station in any way
+ virtual const string& name() const = 0;
+ virtual void setName(const string& aName) = 0;
+
+ // A station has an ID that uniquely identifies it
+ // Setting is allowed to support the map loader
+ virtual int id() const = 0;
+ virtual void setId(int anId) = 0;
+
+ // A station has a random colour that is used to identify it when
+ // the highlight is drawn
+ typedef tuple<float, float, float> HighlightColour;
+ virtual HighlightColour highlightColour() const = 0;
+ virtual bool highlightVisible() const = 0;
+ virtual void setHighlightVisible(bool onOff) = 0;
};
-typedef std::tr1::shared_ptr<IStation> IStationPtr;
+typedef shared_ptr<IStation> IStationPtr;
IStationPtr makeStation();
template <class T>
class ResourceCache {
public:
- typedef function<T* (IResourcePtr)> LoaderType;
+ typedef function<T* (IResourcePtr)> LoaderType;
- ResourceCache(LoaderType aLoader, const string& aClass)
- : myLoader(aLoader), myClass(aClass) {}
+ ResourceCache(LoaderType aLoader, const string& aClass)
+ : myLoader(aLoader), myClass(aClass) {}
- // Load one single copy of this object
- // -> use this if the object has no state
- shared_ptr<T> load(const string& aResId)
- {
- typename CacheType::iterator it = myCache.find(aResId);
- if (it != myCache.end())
- return (*it).second;
- else {
- T* loaded = myLoader(findResource(aResId, myClass));
- shared_ptr<T> ptr(loaded);
- myCache[aResId] = ptr;
- return ptr;
- }
- }
+ // Load one single copy of this object
+ // -> use this if the object has no state
+ shared_ptr<T> load(const string& aResId)
+ {
+ typename CacheType::iterator it = myCache.find(aResId);
+ if (it != myCache.end())
+ return (*it).second;
+ else {
+ T* loaded = myLoader(findResource(aResId, myClass));
+ shared_ptr<T> ptr(loaded);
+ myCache[aResId] = ptr;
+ return ptr;
+ }
+ }
- // Make a copy each time a new object is loaded but only
- // parse the XML once
- // -> use this if the object has state
- shared_ptr<T> loadCopy(const string& aResId)
- {
- shared_ptr<T> original = load(aResId);
- return shared_ptr<T>(new T(*original.get()));
- }
+ // Make a copy each time a new object is loaded but only
+ // parse the XML once
+ // -> use this if the object has state
+ shared_ptr<T> loadCopy(const string& aResId)
+ {
+ shared_ptr<T> original = load(aResId);
+ return shared_ptr<T>(new T(*original.get()));
+ }
private:
- LoaderType myLoader;
- const string myClass;
+ LoaderType myLoader;
+ const string myClass;
- typedef map<string, shared_ptr<T> > CacheType;
- CacheType myCache;
+ typedef map<string, shared_ptr<T> > CacheType;
+ CacheType myCache;
};
#endif
namespace gui {
- // A canvas which arbitrary 3D scenes can be rendered on
- class Canvas3D : public Widget {
- public:
- Canvas3D(const AttributeSet& attrs);
+ // A canvas which arbitrary 3D scenes can be rendered on
+ class Canvas3D : public Widget {
+ public:
+ Canvas3D(const AttributeSet& attrs);
- void render(RenderContext& rc) const;
- private:
- bool clear;
- };
+ void render(RenderContext& rc) const;
+ private:
+ bool clear;
+ };
}
#endif
namespace gui {
- // A complete set of UI elements
- struct ILayout {
- virtual ~ILayout() {}
+ // A complete set of UI elements
+ struct ILayout {
+ virtual ~ILayout() {}
- template <class T>
- T& cast(const string& path) const
- {
- return dynamic_cast<T&>(get(path));
- }
+ template <class T>
+ T& cast(const string& path) const
+ {
+ return dynamic_cast<T&>(get(path));
+ }
- virtual Widget& get(const string& path) const = 0;
- virtual void render() const = 0;
+ virtual Widget& get(const string& path) const = 0;
+ virtual void render() const = 0;
- virtual bool click(int x, int y) = 0;
- };
+ virtual bool click(int x, int y) = 0;
+ };
- typedef shared_ptr<ILayout> ILayoutPtr;
+ typedef shared_ptr<ILayout> ILayoutPtr;
- ILayoutPtr makeLayout(const string& file_name);
- string parentPath(const string& path);
+ ILayoutPtr makeLayout(const string& file_name);
+ string parentPath(const string& path);
}
namespace gui {
- // A button with an icon instead of text
- class ImageButton : public Widget {
- public:
- ImageButton(const AttributeSet& attrs);
+ // A button with an icon instead of text
+ class ImageButton : public Widget {
+ public:
+ ImageButton(const AttributeSet& attrs);
- void render(RenderContext& rc) const;
+ void render(RenderContext& rc) const;
- private:
- ITexturePtr texture;
- };
+ private:
+ ITexturePtr texture;
+ };
}
namespace gui {
- class Label : public Widget {
- public:
- Label(const AttributeSet& attrs);
+ class Label : public Widget {
+ public:
+ Label(const AttributeSet& attrs);
- const string& text() const { return text_; }
- void text(const string& t) { text_ = t; }
+ const string& text() const { return text_; }
+ void text(const string& t) { text_ = t; }
- Colour colour() const { return colour_; }
- void colour(Colour c) { colour_ = c; }
+ Colour colour() const { return colour_; }
+ void colour(Colour c) { colour_ = c; }
- void format(const char* fmt, ...);
+ void format(const char* fmt, ...);
- void render(RenderContext& rc) const;
- void adjustForTheme(const Theme& theme);
- private:
- string text_, fontName;
- Colour colour_;
- };
+ void render(RenderContext& rc) const;
+ void adjustForTheme(const Theme& theme);
+ private:
+ string text_, fontName;
+ Colour colour_;
+ };
}
#endif
namespace gui {
- class Widget;
+ class Widget;
- class RenderContext {
- public:
- RenderContext(const Theme& theme);
- ~RenderContext();
+ class RenderContext {
+ public:
+ RenderContext(const Theme& theme);
+ ~RenderContext();
- void pushOrigin(const Widget* w);
- void popOrigin();
+ void pushOrigin(const Widget* w);
+ void popOrigin();
- void scissor(Widget* w);
+ void scissor(Widget* w);
- void rectangle(int x, int y, int w, int h, Colour c);
- void border(int x, int y, int w, int h, Colour c);
- void image(int x, int y, int w, int h, ITexturePtr tex);
+ void rectangle(int x, int y, int w, int h, Colour c);
+ void border(int x, int y, int w, int h, Colour c);
+ void image(int x, int y, int w, int h, ITexturePtr tex);
- void print(IFontPtr font, int x, int y, const string& s,
- Colour col = colour::WHITE);
+ void print(IFontPtr font, int x, int y, const string& s,
+ Colour col = colour::WHITE);
- const Theme& theme() const { return theme_; }
+ const Theme& theme() const { return theme_; }
- void offset(int& x, int& y) const;
+ void offset(int& x, int& y) const;
- private:
- const Theme& theme_;
- int origin_x, origin_y;
+ private:
+ const Theme& theme_;
+ int origin_x, origin_y;
- stack<const Widget*> origin_stack;
- };
+ stack<const Widget*> origin_stack;
+ };
}
namespace gui {
- class Theme {
- public:
- Theme();
+ class Theme {
+ public:
+ Theme();
- // Colours
- Colour background() const;
- Colour border() const;
+ // Colours
+ Colour background() const;
+ Colour border() const;
- // Fonts
- IFontPtr normalFont() const { return normal_font_; }
- IFontPtr font(const string& fontName) const;
+ // Fonts
+ IFontPtr normalFont() const { return normal_font_; }
+ IFontPtr font(const string& fontName) const;
- void addFont(const string& name, IFontPtr f);
+ void addFont(const string& name, IFontPtr f);
- private:
- IFontPtr normal_font_;
+ private:
+ IFontPtr normal_font_;
- typedef map<string, IFontPtr> FontMap;
- FontMap fonts;
- };
+ typedef map<string, IFontPtr> FontMap;
+ FontMap fonts;
+ };
}
namespace gui {
- // Like a toolbar but one item is always shown selected
- class ToggleBar : public ContainerWidget {
- public:
- ToggleBar(const AttributeSet& attrs);
+ // Like a toolbar but one item is always shown selected
+ class ToggleBar : public ContainerWidget {
+ public:
+ ToggleBar(const AttributeSet& attrs);
- void render(RenderContext& rc) const;
- bool handleClick(int x, int y);
- private:
- void childAdded(Widget* w);
+ void render(RenderContext& rc) const;
+ bool handleClick(int x, int y);
+ private:
+ void childAdded(Widget* w);
- int nextX;
- int buttonWidth, buttonHeight;
- };
+ int nextX;
+ int buttonWidth, buttonHeight;
+ };
}
namespace gui {
- class Widget {
- public:
- Widget(const AttributeSet& attrs);
-
- const string& name() const { return name_; }
- int x() const { return x_; }
- int y() const { return y_; }
- int width() const { return width_; }
- int height() const { return height_; }
- bool visible() const { return visible_; }
-
- void x(int x) { x_ = x; }
- void y(int y) { y_ = y; }
- void width(int w) { width_ = w; }
- void height(int h) { height_ = h; }
- void visible(bool v);
-
- enum Signal {
- SIG_CLICK, SIG_RENDER, SIG_SHOW, SIG_HIDE,
- SIG_ENTER, SIG_LEAVE
- };
-
- typedef function<void (Widget&)> SignalHandler;
-
- void connect(Signal sig, SignalHandler handler);
-
- virtual void render(RenderContext& rc) const = 0;
- virtual void adjustForTheme(const Theme& theme) {}
+ class Widget {
+ public:
+ Widget(const AttributeSet& attrs);
+
+ const string& name() const { return name_; }
+ int x() const { return x_; }
+ int y() const { return y_; }
+ int width() const { return width_; }
+ int height() const { return height_; }
+ bool visible() const { return visible_; }
+
+ void x(int x) { x_ = x; }
+ void y(int y) { y_ = y; }
+ void width(int w) { width_ = w; }
+ void height(int h) { height_ = h; }
+ void visible(bool v);
+
+ enum Signal {
+ SIG_CLICK, SIG_RENDER, SIG_SHOW, SIG_HIDE,
+ SIG_ENTER, SIG_LEAVE
+ };
+
+ typedef function<void (Widget&)> SignalHandler;
+
+ void connect(Signal sig, SignalHandler handler);
+
+ virtual void render(RenderContext& rc) const = 0;
+ virtual void adjustForTheme(const Theme& theme) {}
- virtual bool handleClick(int x, int y);
+ virtual bool handleClick(int x, int y);
- void dumpLocation() const;
+ void dumpLocation() const;
- protected:
- void raise(Signal sig);
+ protected:
+ void raise(Signal sig);
- private:
- static string uniqueName();
+ private:
+ static string uniqueName();
- string name_;
- int x_, y_, width_, height_;
- bool visible_;
+ string name_;
+ int x_, y_, width_, height_;
+ bool visible_;
- map<Signal, SignalHandler> handlers;
+ map<Signal, SignalHandler> handlers;
- static int ourUniqueId;
- };
+ static int ourUniqueId;
+ };
}
namespace gui {
- class Window : public ContainerWidget {
- public:
- Window(const AttributeSet& attrs);
+ class Window : public ContainerWidget {
+ public:
+ Window(const AttributeSet& attrs);
- const string& title() const { return title_; }
- void title(const string& t) { title_ = t; }
+ const string& title() const { return title_; }
+ void title(const string& t) { title_ = t; }
- void render(RenderContext& rc) const;
- private:
- string title_;
- };
+ void render(RenderContext& rc) const;
+ private:
+ string title_;
+ };
}
// Concrete editor class
class Editor : public IScreen {
public:
- Editor(IMapPtr aMap);
- Editor(const string& aMapName);
- ~Editor();
+ Editor(IMapPtr aMap);
+ Editor(const string& aMapName);
+ ~Editor();
- void display(IGraphicsPtr aContext) const;
- void overlay() const;
- void update(IPickBufferPtr aPickBuffer, int aDelta);
- void onKeyDown(SDLKey aKey);
- void onKeyUp(SDLKey aKey);
- void onMouseMove(IPickBufferPtr aPickBuffer, int x, int y, int xrel, int yrel);
- void onMouseClick(IPickBufferPtr aPickBuffer, int x, int y,
- MouseButton aButton);
- void onMouseRelease(IPickBufferPtr aPickBuffer, int x, int y,
- MouseButton aButton);
+ void display(IGraphicsPtr aContext) const;
+ void overlay() const;
+ void update(IPickBufferPtr aPickBuffer, int aDelta);
+ void onKeyDown(SDLKey aKey);
+ void onKeyUp(SDLKey aKey);
+ void onMouseMove(IPickBufferPtr aPickBuffer, int x, int y, int xrel, int yrel);
+ void onMouseClick(IPickBufferPtr aPickBuffer, int x, int y,
+ MouseButton aButton);
+ void onMouseRelease(IPickBufferPtr aPickBuffer, int x, int y,
+ MouseButton aButton);
- // Different tools the user can be using
- enum Tool {
- TRACK_TOOL, RAISE_TOOL, LOWER_TOOL, DELETE_TOOL,
- LEVEL_TOOL, START_TOOL, STATION_TOOL, BUILDING_TOOL,
- TREE_TOOL
- };
- void setTool(Tool aTool) { myTool = aTool; }
-
- IMapPtr getMap() { return map; }
- void setMap(IMapPtr aMap);
+ // Different tools the user can be using
+ enum Tool {
+ TRACK_TOOL, RAISE_TOOL, LOWER_TOOL, DELETE_TOOL,
+ LEVEL_TOOL, START_TOOL, STATION_TOOL, BUILDING_TOOL,
+ TREE_TOOL
+ };
+ void setTool(Tool aTool) { myTool = aTool; }
+
+ IMapPtr getMap() { return map; }
+ void setMap(IMapPtr aMap);
private:
- void buildGUI();
- void drawDraggedTrack();
- bool drawTrackTile(const Point<int>& aPoint, const track::Direction& anAxis);
- void drawDraggedStraight(const track::Direction& anAxis, int aLength);
- void drawDraggedCurve(int xLength, int yLength);
- bool canConnect(const Point<int>& aFirstPoint,
- const Point<int>& aSecondPoint) const;
- void dragBoxBounds(int& xMin, int& xMax, int &yMin, int& yMax) const;
- void deleteObjects();
+ void buildGUI();
+ void drawDraggedTrack();
+ bool drawTrackTile(const Point<int>& aPoint, const track::Direction& anAxis);
+ void drawDraggedStraight(const track::Direction& anAxis, int aLength);
+ void drawDraggedCurve(int xLength, int yLength);
+ bool canConnect(const Point<int>& aFirstPoint,
+ const Point<int>& aSecondPoint) const;
+ void dragBoxBounds(int& xMin, int& xMax, int &yMin, int& yMax) const;
+ void deleteObjects();
void plantTrees();
- void save();
+ void save();
- IMapPtr map;
+ IMapPtr map;
- ILightPtr mySun;
- Vector<float> myPosition;
+ ILightPtr mySun;
+ Vector<float> myPosition;
- Tool myTool;
- bool amScrolling;
+ Tool myTool;
+ bool amScrolling;
- // Variables for dragging track segments
- Point<int> dragBegin, dragEnd;
- bool amDragging;
+ // Variables for dragging track segments
+ Point<int> dragBegin, dragEnd;
+ bool amDragging;
- // GUI elements
- gui::ILayoutPtr layout;
- IBuildingPickerPtr buildingPicker;
+ // GUI elements
+ gui::ILayoutPtr layout;
+ IBuildingPickerPtr buildingPicker;
};
Editor::Editor(IMapPtr aMap)
- : map(aMap), myPosition(4.5, -17.5, -21.5),
- myTool(TRACK_TOOL), amScrolling(false), amDragging(false)
+ : map(aMap), myPosition(4.5, -17.5, -21.5),
+ myTool(TRACK_TOOL), amScrolling(false), amDragging(false)
{
- mySun = makeSunLight();
+ mySun = makeSunLight();
- buildGUI();
+ buildGUI();
- map->setGrid(true);
+ map->setGrid(true);
- log() << "Editing " << aMap->name();
+ log() << "Editing " << aMap->name();
}
Editor::~Editor()
void Editor::setMap(IMapPtr aMap)
{
- map = aMap;
- map->setGrid(true);
+ map = aMap;
+ map->setGrid(true);
}
void Editor::save()
{
- map->save();
+ map->save();
}
// Calculate the bounds of the drag box accounting for the different
using namespace boost::filesystem;
namespace {
- IWindowPtr window;
+ IWindowPtr window;
- void SIGINT_handler(int unused)
- {
- log() << "Caught SIGINT";
- ::window->quit();
- }
+ void SIGINT_handler(int unused)
+ {
+ log() << "Caught SIGINT";
+ ::window->quit();
+ }
- void setupSignalHandlers()
- {
- struct sigaction sa;
- sa.sa_handler = SIGINT_handler;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
+ void setupSignalHandlers()
+ {
+ struct sigaction sa;
+ sa.sa_handler = SIGINT_handler;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
- sigaction(SIGINT, &sa, NULL);
- }
+ sigaction(SIGINT, &sa, NULL);
+ }
}
IWindowPtr getGameWindow()
{
- return ::window;
+ return ::window;
}
int main(int argc, char** argv)
{
- cout << PACKAGE << " " << VERSION << "." << PATCH << endl << endl
- << "Copyright (C) 2009-2010 Nick Gasson" << endl
- << "This program comes with ABSOLUTELY NO WARRANTY. "
- << "This is free software, and" << endl
- << "you are welcome to redistribute it under certain conditions. "
- << "See the GNU" << endl
- << "General Public Licence for details." << endl << endl;
+ cout << PACKAGE << " " << VERSION << "." << PATCH << endl << endl
+ << "Copyright (C) 2009-2010 Nick Gasson" << endl
+ << "This program comes with ABSOLUTELY NO WARRANTY. "
+ << "This is free software, and" << endl
+ << "you are welcome to redistribute it under certain conditions. "
+ << "See the GNU" << endl
+ << "General Public Licence for details." << endl << endl;
- log() << "Program started";
+ log() << "Program started";
- setupSignalHandlers();
+ setupSignalHandlers();
- try {
+ try {
#ifndef WIN32
- if (argc != 2 && argc != 3)
- throw runtime_error("Usage: TrainGame (edit|play) [map]");
- initResources();
+ if (argc != 2 && argc != 3)
+ throw runtime_error("Usage: TrainGame (edit|play) [map]");
+ initResources();
- const string mapFile(argc == 3 ? argv[2] : "");
- const string cmd(argv[1]);
+ const string mapFile(argc == 3 ? argv[2] : "");
+ const string cmd(argv[1]);
#else
- // For ease of debugging, specify a default map
- const string mapFile("figure8");
- const string cmd("play");
+ // For ease of debugging, specify a default map
+ const string mapFile("figure8");
+ const string cmd("play");
#endif // #ifndef WIN32
- IConfigPtr cfg = getConfig();
+ IConfigPtr cfg = getConfig();
- ::window = makeSDLWindow();
+ ::window = makeSDLWindow();
- IScreenPtr screen;
- if (cmd == "edit") {
- if (resourceExists(mapFile, "maps"))
- screen = makeEditorScreen(loadMap(mapFile));
- else {
- screen = makeEditorScreen(makeEmptyMap(mapFile, 32, 32));
- }
- }
- else if (cmd == "play") {
- screen = makeGameScreen(loadMap(mapFile));
- }
- else if (cmd == "uidemo") {
- screen = makeUIDemo();
- }
- else if (cmd == "ltree") {
- screen = makeLTreeDemo();
- }
- else
- throw runtime_error("Unrecognised command: " + cmd);
+ IScreenPtr screen;
+ if (cmd == "edit") {
+ if (resourceExists(mapFile, "maps"))
+ screen = makeEditorScreen(loadMap(mapFile));
+ else {
+ screen = makeEditorScreen(makeEmptyMap(mapFile, 32, 32));
+ }
+ }
+ else if (cmd == "play") {
+ screen = makeGameScreen(loadMap(mapFile));
+ }
+ else if (cmd == "uidemo") {
+ screen = makeUIDemo();
+ }
+ else if (cmd == "ltree") {
+ screen = makeLTreeDemo();
+ }
+ else
+ throw runtime_error("Unrecognised command: " + cmd);
- ::window->run(screen);
+ ::window->run(screen);
- cfg->flush();
- }
- catch (const runtime_error& e) {
- error() << "Fatal: " << e.what();
+ cfg->flush();
+ }
+ catch (const runtime_error& e) {
+ error() << "Fatal: " << e.what();
#ifdef WIN32
- MessageBox(NULL, e.what(), "Fatal error", MB_ICONERROR | MB_OK);
+ MessageBox(NULL, e.what(), "Fatal error", MB_ICONERROR | MB_OK);
#endif
- }
+ }
- log() << "Finished";
- return 0;
+ log() << "Finished";
+ return 0;
}
// Concrete implementation of mesh buffers
struct MeshBuffer : IMeshBuffer {
- MeshBuffer();
- ~MeshBuffer() {}
+ MeshBuffer();
+ ~MeshBuffer() {}
- size_t vertexCount() const { return vertices.size(); }
+ size_t vertexCount() const { return vertices.size(); }
- void add(const Vertex& aVertex, const Normal& aNormal);
- void add(const Vertex& aVertex, const Normal& aNormal,
- const TexCoord& aTexCoord);
- void add(const Vertex& aVertex, const Normal& aNormal,
- const Colour& aColour);
-
- void addQuad(Vertex a, Vertex b, Vertex c, Vertex d,
- Colour aColour);
- void addQuad(Vertex a, Vertex b, Vertex c, Vertex d,
- Normal na, Normal nb, Normal nc, Normal nd,
- Colour aColour);
+ void add(const Vertex& aVertex, const Normal& aNormal);
+ void add(const Vertex& aVertex, const Normal& aNormal,
+ const TexCoord& aTexCoord);
+ void add(const Vertex& aVertex, const Normal& aNormal,
+ const Colour& aColour);
+
+ void addQuad(Vertex a, Vertex b, Vertex c, Vertex d,
+ Colour aColour);
+ void addQuad(Vertex a, Vertex b, Vertex c, Vertex d,
+ Normal na, Normal nb, Normal nc, Normal nd,
+ Colour aColour);
- void bindMaterial(const Material& aMaterial);
+ void bindMaterial(const Material& aMaterial);
- void printStats() const;
+ void printStats() const;
- static MeshBuffer* get(IMeshBufferPtr aPtr)
- {
- return polymorphic_cast<MeshBuffer*>(aPtr.get());
- }
-
- static bool mergeVector(const Vector<float>& v1, const Vector<float>& v2)
- {
- const float tolerance = 0.0001f;
+ static MeshBuffer* get(IMeshBufferPtr aPtr)
+ {
+ return polymorphic_cast<MeshBuffer*>(aPtr.get());
+ }
+
+ static bool mergeVector(const Vector<float>& v1, const Vector<float>& v2)
+ {
+ const float tolerance = 0.0001f;
- return abs(v1.x - v2.x) < tolerance
- && abs(v1.y - v2.y) < tolerance
- && abs(v1.z - v2.z) < tolerance;
- }
+ return abs(v1.x - v2.x) < tolerance
+ && abs(v1.y - v2.y) < tolerance
+ && abs(v1.z - v2.z) < tolerance;
+ }
- vector<Vertex> vertices;
- vector<Normal> normals;
- vector<Colour> colours;
- vector<Index> indices;
- vector<TexCoord> texCoords;
- bool hasTexture, hasMaterial;
- Material material;
- int reused;
+ vector<Vertex> vertices;
+ vector<Normal> normals;
+ vector<Colour> colours;
+ vector<Index> indices;
+ vector<TexCoord> texCoords;
+ bool hasTexture, hasMaterial;
+ Material material;
+ int reused;
};
MeshBuffer::MeshBuffer()
- : hasTexture(false), hasMaterial(false), reused(0)
+ : hasTexture(false), hasMaterial(false), reused(0)
{
}
void MeshBuffer::bindMaterial(const Material& aMaterial)
{
- material = aMaterial;
- hasTexture = aMaterial.texture;
- hasMaterial = true;
+ material = aMaterial;
+ hasTexture = aMaterial.texture;
+ hasMaterial = true;
}
void MeshBuffer::printStats() const
{
- debug() << "Mesh: " << vertices.size() << " vertices, "
- << reused << " reused";
+ debug() << "Mesh: " << vertices.size() << " vertices, "
+ << reused << " reused";
}
void MeshBuffer::add(const Vertex& aVertex, const Normal& aNormal)
{
- if (hasTexture)
- throw runtime_error("MeshBuffer::add called without texture coordinate "
- "on a mesh which has a texture");
+ if (hasTexture)
+ throw runtime_error("MeshBuffer::add called without texture coordinate "
+ "on a mesh which has a texture");
- if (!hasMaterial)
- throw runtime_error("MeshBuffer::add called without colour on a mesh "
- " without a material");
+ if (!hasMaterial)
+ throw runtime_error("MeshBuffer::add called without colour on a mesh "
+ " without a material");
- // See if this vertex has already been added
- for (vector<Index>::iterator it = indices.begin();
- it != indices.end(); ++it) {
- if (mergeVector(aVertex, vertices[*it])
- && mergeVector(aNormal, normals[*it])) {
- indices.push_back(*it);
- reused++;
- return;
- }
- }
+ // See if this vertex has already been added
+ for (vector<Index>::iterator it = indices.begin();
+ it != indices.end(); ++it) {
+ if (mergeVector(aVertex, vertices[*it])
+ && mergeVector(aNormal, normals[*it])) {
+ indices.push_back(*it);
+ reused++;
+ return;
+ }
+ }
- const int index = vertices.size();
- vertices.push_back(aVertex);
- normals.push_back(aNormal);
- indices.push_back(index);
+ const int index = vertices.size();
+ vertices.push_back(aVertex);
+ normals.push_back(aNormal);
+ indices.push_back(index);
}
void MeshBuffer::add(const Vertex& aVertex, const Normal& aNormal,
- const Colour& aColour)
+ const Colour& aColour)
{
- if (hasTexture)
- throw runtime_error("MeshBuffer::add called without texture coordinate "
- "on a mesh which has a texture");
+ if (hasTexture)
+ throw runtime_error("MeshBuffer::add called without texture coordinate "
+ "on a mesh which has a texture");
- if (hasMaterial)
- throw runtime_error("MeshBuffer::add called with a colour on a mesh "
- " with a material");
+ if (hasMaterial)
+ throw runtime_error("MeshBuffer::add called with a colour on a mesh "
+ " with a material");
- // See if this vertex has already been added
- for (vector<Index>::iterator it = indices.begin();
- it != indices.end(); ++it) {
- if (mergeVector(aVertex, vertices[*it])
- && mergeVector(aNormal, normals[*it])) {
-
- const Colour& other = colours[*it];
- if (abs(tr1::get<0>(other) - tr1::get<0>(aColour)) < 0.01f
- && abs(tr1::get<1>(other) - tr1::get<1>(aColour)) < 0.01f
- && abs(tr1::get<2>(other) - tr1::get<2>(aColour)) < 0.01f) {
+ // See if this vertex has already been added
+ for (vector<Index>::iterator it = indices.begin();
+ it != indices.end(); ++it) {
+ if (mergeVector(aVertex, vertices[*it])
+ && mergeVector(aNormal, normals[*it])) {
+
+ const Colour& other = colours[*it];
+ if (abs(tr1::get<0>(other) - tr1::get<0>(aColour)) < 0.01f
+ && abs(tr1::get<1>(other) - tr1::get<1>(aColour)) < 0.01f
+ && abs(tr1::get<2>(other) - tr1::get<2>(aColour)) < 0.01f) {
- indices.push_back(*it);
- reused++;
- return;
- }
- }
- }
+ indices.push_back(*it);
+ reused++;
+ return;
+ }
+ }
+ }
- const int index = vertices.size();
- vertices.push_back(aVertex);
- normals.push_back(aNormal);
- colours.push_back(aColour);
- indices.push_back(index);
+ const int index = vertices.size();
+ vertices.push_back(aVertex);
+ normals.push_back(aNormal);
+ colours.push_back(aColour);
+ indices.push_back(index);
}
void MeshBuffer::add(const Vertex& aVertex, const Normal& aNormal,
- const TexCoord& aTexCoord)
+ const TexCoord& aTexCoord)
{
- if (!hasTexture)
- throw runtime_error("MeshBuffer::add called with a texture coordinate "
- "on a mesh without a texture");
+ if (!hasTexture)
+ throw runtime_error(
+ "MeshBuffer::add called with a texture coordinate "
+ "on a mesh without a texture");
- // See if this vertex has already been added
- for (vector<Index>::iterator it = indices.begin();
- it != indices.end(); ++it) {
- if (mergeVector(aVertex, vertices[*it])
- && mergeVector(aNormal, normals[*it])) {
- TexCoord& tc = texCoords[*it];
- if (abs(tc.x - aTexCoord.x) < 0.001f
- && abs(tc.y - aTexCoord.y) < 0.001f) {
- indices.push_back(*it);
- reused++;
- return;
- }
- }
- }
+ // See if this vertex has already been added
+ for (vector<Index>::iterator it = indices.begin();
+ it != indices.end(); ++it) {
+ if (mergeVector(aVertex, vertices[*it])
+ && mergeVector(aNormal, normals[*it])) {
+ TexCoord& tc = texCoords[*it];
+ if (abs(tc.x - aTexCoord.x) < 0.001f
+ && abs(tc.y - aTexCoord.y) < 0.001f) {
+ indices.push_back(*it);
+ reused++;
+ return;
+ }
+ }
+ }
- const int index = vertices.size();
- vertices.push_back(aVertex);
- normals.push_back(aNormal);
- texCoords.push_back(aTexCoord);
- indices.push_back(index);
+ const int index = vertices.size();
+ vertices.push_back(aVertex);
+ normals.push_back(aNormal);
+ texCoords.push_back(aTexCoord);
+ indices.push_back(index);
}
-void MeshBuffer::addQuad(Vertex a, Vertex b, Vertex c, Vertex d, Colour aColour)
+void MeshBuffer::addQuad(Vertex a, Vertex b, Vertex c,
+ Vertex d, Colour aColour)
{
- Vector<float> n1 = surfaceNormal(b, c, d);
- Vector<float> n2 = surfaceNormal(d, a, b);
+ Vector<float> n1 = surfaceNormal(b, c, d);
+ Vector<float> n2 = surfaceNormal(d, a, b);
- add(b, n1, aColour);
- add(c, n1, aColour);
- add(d, n1, aColour);
+ add(b, n1, aColour);
+ add(c, n1, aColour);
+ add(d, n1, aColour);
- add(d, n2, aColour);
- add(a, n2, aColour);
- add(b, n2, aColour);
+ add(d, n2, aColour);
+ add(a, n2, aColour);
+ add(b, n2, aColour);
}
void MeshBuffer::addQuad(Vertex a, Vertex b, Vertex c, Vertex d,
- Normal na, Normal nb, Normal nc, Normal nd,
- Colour aColour)
+ Normal na, Normal nb, Normal nc, Normal nd,
+ Colour aColour)
{
- add(b, na, aColour);
- add(c, nb, aColour);
- add(d, nc, aColour);
+ add(b, na, aColour);
+ add(c, nb, aColour);
+ add(d, nc, aColour);
- add(d, nd, aColour);
- add(a, na, aColour);
- add(b, nb, aColour);
+ add(d, nd, aColour);
+ add(a, na, aColour);
+ add(b, nb, aColour);
}
// Default material
Material::Material()
- : diffuseR(1.0f), diffuseG(1.0f), diffuseB(1.0f),
- ambientR(1.0f), ambientG(1.0f), ambientB(1.0f),
- specularR(0.0f), specularG(0.0f), specularB(0.0f)
+ : diffuseR(1.0f), diffuseG(1.0f), diffuseB(1.0f),
+ ambientR(1.0f), ambientG(1.0f), ambientB(1.0f),
+ specularR(0.0f), specularG(0.0f), specularB(0.0f)
{
}
void Material::apply() const
{
- if (texture) {
- glEnable(GL_TEXTURE_2D);
- texture->bind();
+ if (texture) {
+ glEnable(GL_TEXTURE_2D);
+ texture->bind();
- glEnable(GL_COLOR_MATERIAL);
- glColor3f(1.0f, 1.0f, 1.0f);
- }
- else {
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_TEXTURE_2D);
+ glEnable(GL_COLOR_MATERIAL);
+ glColor3f(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_TEXTURE_2D);
- float diffuse[] = { diffuseR, diffuseG, diffuseB, 1.0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
+ float diffuse[] = { diffuseR, diffuseG, diffuseB, 1.0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
- float ambient[] = { ambientR, ambientG, ambientB, 1.0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
+ float ambient[] = { ambientR, ambientG, ambientB, 1.0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
- // Note we're ignoring the specular values in the model
- float specular[] = { 0, 0, 0, 1.0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
+ // Note we're ignoring the specular values in the model
+ float specular[] = { 0, 0, 0, 1.0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
- float emission[] = { 0, 0, 0, 1 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission);
- }
+ float emission[] = { 0, 0, 0, 1 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission);
+ }
}
// Simple implementation using display lists
class DisplayListMesh : public IMesh {
public:
- DisplayListMesh(IMeshBufferPtr aBuffer);
- ~DisplayListMesh();
+ DisplayListMesh(IMeshBufferPtr aBuffer);
+ ~DisplayListMesh();
- void render() const;
+ void render() const;
private:
- GLuint myDisplayList;
+ GLuint myDisplayList;
};
DisplayListMesh::DisplayListMesh(IMeshBufferPtr aBuffer)
{
- myDisplayList = glGenLists(1);
+ myDisplayList = glGenLists(1);
- glNewList(myDisplayList, GL_COMPILE);
+ glNewList(myDisplayList, GL_COMPILE);
- const MeshBuffer* buf = MeshBuffer::get(aBuffer);
+ const MeshBuffer* buf = MeshBuffer::get(aBuffer);
- if (buf->hasMaterial)
- buf->material.apply();
- else
- glEnable(GL_COLOR_MATERIAL);
+ if (buf->hasMaterial)
+ buf->material.apply();
+ else
+ glEnable(GL_COLOR_MATERIAL);
- glBegin(GL_TRIANGLES);
+ glBegin(GL_TRIANGLES);
- vector<MeshBuffer::Index>::const_iterator it;
- for (it = buf->indices.begin();
- it != buf->indices.end(); ++it) {
+ vector<MeshBuffer::Index>::const_iterator it;
+ for (it = buf->indices.begin();
+ it != buf->indices.end(); ++it) {
- if (!buf->hasMaterial) {
- const MeshBuffer::Colour& c = buf->colours[*it];
- glColor3f(get<0>(c), get<1>(c), get<2>(c));
- }
+ if (!buf->hasMaterial) {
+ const MeshBuffer::Colour& c = buf->colours[*it];
+ glColor3f(get<0>(c), get<1>(c), get<2>(c));
+ }
- const MeshBuffer::Normal& n = buf->normals[*it];
- glNormal3f(n.x, n.y, n.z);
+ const MeshBuffer::Normal& n = buf->normals[*it];
+ glNormal3f(n.x, n.y, n.z);
- const MeshBuffer::Vertex& v = buf->vertices[*it];
- glVertex3f(v.x, v.y, v.z);
- }
+ const MeshBuffer::Vertex& v = buf->vertices[*it];
+ glVertex3f(v.x, v.y, v.z);
+ }
- glEnd();
+ glEnd();
- for (it = buf->indices.begin();
- it != buf->indices.end(); ++it) {
- const MeshBuffer::Vertex& v = buf->vertices[*it];
- const MeshBuffer::Normal& n = buf->normals[*it];
- drawNormal(v, n);
- }
-
- glEndList();
+ for (it = buf->indices.begin();
+ it != buf->indices.end(); ++it) {
+ const MeshBuffer::Vertex& v = buf->vertices[*it];
+ const MeshBuffer::Normal& n = buf->normals[*it];
+ drawNormal(v, n);
+ }
+
+ glEndList();
}
DisplayListMesh::~DisplayListMesh()
{
- glDeleteLists(myDisplayList, 1);
+ glDeleteLists(myDisplayList, 1);
}
void DisplayListMesh::render() const
{
- glPushAttrib(GL_ENABLE_BIT);
+ glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_BLEND);
- glEnable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glEnable(GL_CULL_FACE);
- glCallList(myDisplayList);
+ glCallList(myDisplayList);
- glPopAttrib();
+ glPopAttrib();
}
// Packed vertex data used by vertex array and VBO mesh implementations
struct VertexData {
- float x, y, z;
- float nx, ny, nz;
- float tx, ty;
- float r, g, b;
- float padding[5]; // Best performance on some cards if 32-byte aligned
+ float x, y, z;
+ float nx, ny, nz;
+ float tx, ty;
+ float r, g, b;
+ float padding[5]; // Best performance on some cards if 32-byte aligned
};
BOOST_STATIC_ASSERT(sizeof(VertexData) == 64);
namespace {
- // Get the vertex data out of a mesh buffer into a VertexData array
- void copyVertexData(const MeshBuffer* buf, VertexData* vertexData)
- {
- for (size_t i = 0; i < buf->vertices.size(); i++) {
- VertexData* vd = &vertexData[i];
+ // Get the vertex data out of a mesh buffer into a VertexData array
+ void copyVertexData(const MeshBuffer* buf, VertexData* vertexData)
+ {
+ for (size_t i = 0; i < buf->vertices.size(); i++) {
+ VertexData* vd = &vertexData[i];
- vd->x = buf->vertices[i].x;
- vd->y = buf->vertices[i].y;
- vd->z = buf->vertices[i].z;
+ vd->x = buf->vertices[i].x;
+ vd->y = buf->vertices[i].y;
+ vd->z = buf->vertices[i].z;
- vd->nx = buf->normals[i].x;
- vd->ny = buf->normals[i].y;
- vd->nz = buf->normals[i].z;
+ vd->nx = buf->normals[i].x;
+ vd->ny = buf->normals[i].y;
+ vd->nz = buf->normals[i].z;
- if (buf->hasTexture) {
- vd->tx = buf->texCoords[i].x;
- vd->ty = 1.0f - buf->texCoords[i].y;
- }
+ if (buf->hasTexture) {
+ vd->tx = buf->texCoords[i].x;
+ vd->ty = 1.0f - buf->texCoords[i].y;
+ }
- if (!buf->hasMaterial) {
- vd->r = get<0>(buf->colours[i]);
- vd->g = get<1>(buf->colours[i]);
- vd->b = get<2>(buf->colours[i]);
- }
- }
- }
+ if (!buf->hasMaterial) {
+ vd->r = get<0>(buf->colours[i]);
+ vd->g = get<1>(buf->colours[i]);
+ vd->b = get<2>(buf->colours[i]);
+ }
+ }
+ }
}
// Implementation of meshes using client side vertex arrays
class VertexArrayMesh : public IMesh {
public:
- VertexArrayMesh(IMeshBufferPtr aBuffer);
- ~VertexArrayMesh();
+ VertexArrayMesh(IMeshBufferPtr aBuffer);
+ ~VertexArrayMesh();
- void render() const;
+ void render() const;
private:
- Material material;
- bool hasMaterial, hasTexture;
- int myVertexCount;
- VertexData* myVertexData;
- int myIndexCount;
- GLushort* myIndices;
+ Material material;
+ bool hasMaterial, hasTexture;
+ int myVertexCount;
+ VertexData* myVertexData;
+ int myIndexCount;
+ GLushort* myIndices;
};
VertexArrayMesh::VertexArrayMesh(IMeshBufferPtr aBuffer)
{
- const MeshBuffer* buf = MeshBuffer::get(aBuffer);
+ const MeshBuffer* buf = MeshBuffer::get(aBuffer);
- material = buf->material;
- hasMaterial = buf->hasMaterial;
- hasTexture = buf->hasTexture;
+ material = buf->material;
+ hasMaterial = buf->hasMaterial;
+ hasTexture = buf->hasTexture;
- myVertexCount = buf->vertices.size();
- myVertexData = new VertexData[myVertexCount];
+ myVertexCount = buf->vertices.size();
+ myVertexData = new VertexData[myVertexCount];
- copyVertexData(buf, myVertexData);
+ copyVertexData(buf, myVertexData);
- myIndexCount = buf->indices.size();
- myIndices = new GLushort[myIndexCount];
+ myIndexCount = buf->indices.size();
+ myIndices = new GLushort[myIndexCount];
- copy(buf->indices.begin(), buf->indices.end(), myIndices);
+ copy(buf->indices.begin(), buf->indices.end(), myIndices);
}
VertexArrayMesh::~VertexArrayMesh()
{
- delete[] myVertexData;
- delete[] myIndices;
+ delete[] myVertexData;
+ delete[] myIndices;
}
void VertexArrayMesh::render() const
{
- glPushAttrib(GL_ENABLE_BIT);
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glPushAttrib(GL_ENABLE_BIT);
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
- if (hasMaterial)
- material.apply();
- else {
- glEnable(GL_COLOR_MATERIAL);
-
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(3, GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(&myVertexData->r));
- }
+ if (hasMaterial)
+ material.apply();
+ else {
+ glEnable(GL_COLOR_MATERIAL);
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(&myVertexData->r));
+ }
- if (hasTexture) {
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(&myVertexData->tx));
- }
+ if (hasTexture) {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(&myVertexData->tx));
+ }
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(myVertexData));
- glNormalPointer(GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(&myVertexData->nx));
-
- glDrawElements(GL_TRIANGLES, myIndexCount, GL_UNSIGNED_SHORT, myIndices);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(myVertexData));
+ glNormalPointer(GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(&myVertexData->nx));
+
+ glDrawElements(GL_TRIANGLES, myIndexCount, GL_UNSIGNED_SHORT, myIndices);
- glPopClientAttrib();
- glPopAttrib();
+ glPopClientAttrib();
+ glPopAttrib();
}
// Implementation of meshes using server side VBOs
class VBOMesh : public IMesh {
public:
- VBOMesh(IMeshBufferPtr aBuffer);
- ~VBOMesh();
+ VBOMesh(IMeshBufferPtr aBuffer);
+ ~VBOMesh();
- void render() const;
+ void render() const;
private:
- GLuint vboBuf, indexBuf;
- Material material;
- bool hasTexture, hasMaterial;
- size_t myIndexCount;
+ GLuint vboBuf, indexBuf;
+ Material material;
+ bool hasTexture, hasMaterial;
+ size_t myIndexCount;
};
VBOMesh::VBOMesh(IMeshBufferPtr aBuffer)
{
- // Get the data out of the buffer;
- const MeshBuffer* buf = MeshBuffer::get(aBuffer);
+ // Get the data out of the buffer;
+ const MeshBuffer* buf = MeshBuffer::get(aBuffer);
- material = buf->material;
- hasMaterial = buf->hasMaterial;
- hasTexture = buf->hasTexture;
+ material = buf->material;
+ hasMaterial = buf->hasMaterial;
+ hasTexture = buf->hasTexture;
- const size_t vertexCount = buf->vertices.size();
- VertexData* pVertexData = new VertexData[vertexCount];
+ const size_t vertexCount = buf->vertices.size();
+ VertexData* pVertexData = new VertexData[vertexCount];
- copyVertexData(buf, pVertexData);
+ copyVertexData(buf, pVertexData);
- // Generate the VBO
- glGenBuffersARB(1, &vboBuf);
- glBindBufferARB(GL_ARRAY_BUFFER, vboBuf);
- glBufferDataARB(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexData),
- NULL, GL_STATIC_DRAW);
+ // Generate the VBO
+ glGenBuffersARB(1, &vboBuf);
+ glBindBufferARB(GL_ARRAY_BUFFER, vboBuf);
+ glBufferDataARB(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexData),
+ NULL, GL_STATIC_DRAW);
- // Copy the vertex data in
- glBufferSubDataARB(GL_ARRAY_BUFFER, 0,
- vertexCount * sizeof(VertexData), pVertexData);
+ // Copy the vertex data in
+ glBufferSubDataARB(GL_ARRAY_BUFFER, 0,
+ vertexCount * sizeof(VertexData), pVertexData);
- // Copy the indices into a temporary array
- myIndexCount = buf->indices.size();
- GLshort* pIndices = new GLshort[myIndexCount];
+ // Copy the indices into a temporary array
+ myIndexCount = buf->indices.size();
+ GLshort* pIndices = new GLshort[myIndexCount];
- copy(buf->indices.begin(), buf->indices.end(), pIndices);
+ copy(buf->indices.begin(), buf->indices.end(), pIndices);
- // Build the index buffer
- glGenBuffersARB(1, &indexBuf);
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, myIndexCount * sizeof(GLushort),
- NULL, GL_STATIC_DRAW);
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER, 0,
- myIndexCount * sizeof(GLushort), pIndices);
-
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ // Build the index buffer
+ glGenBuffersARB(1, &indexBuf);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, myIndexCount * sizeof(GLushort),
+ NULL, GL_STATIC_DRAW);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER, 0,
+ myIndexCount * sizeof(GLushort), pIndices);
+
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
- delete[] pVertexData;
- delete[] pIndices;
+ delete[] pVertexData;
+ delete[] pIndices;
}
VBOMesh::~VBOMesh()
{
- glDeleteBuffersARB(1, &vboBuf);
- glDeleteBuffersARB(1, &indexBuf);
+ glDeleteBuffersARB(1, &vboBuf);
+ glDeleteBuffersARB(1, &indexBuf);
}
void VBOMesh::render() const
{
- glPushAttrib(GL_ENABLE_BIT);
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glPushAttrib(GL_ENABLE_BIT);
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glBindBufferARB(GL_ARRAY_BUFFER, vboBuf);
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
+ glBindBufferARB(GL_ARRAY_BUFFER, vboBuf);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
- if (hasTexture)
- glEnable(GL_TEXTURE_2D);
- else
- glDisable(GL_TEXTURE_2D);
-
- if (hasMaterial)
- material.apply();
- else {
- glEnable(GL_COLOR_MATERIAL);
-
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(3, GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(offsetof(VertexData, r)));
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
-
- // Pointers are relative to start of VBO
- glNormalPointer(GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(offsetof(VertexData, nx)));
- glVertexPointer(3, GL_FLOAT, sizeof(VertexData),
- reinterpret_cast<GLvoid*>(0));
+ if (hasTexture)
+ glEnable(GL_TEXTURE_2D);
+ else
+ glDisable(GL_TEXTURE_2D);
+
+ if (hasMaterial)
+ material.apply();
+ else {
+ glEnable(GL_COLOR_MATERIAL);
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(offsetof(VertexData, r)));
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // Pointers are relative to start of VBO
+ glNormalPointer(GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(offsetof(VertexData, nx)));
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexData),
+ reinterpret_cast<GLvoid*>(0));
- glDrawElements(GL_TRIANGLES, myIndexCount, GL_UNSIGNED_SHORT, 0);
+ glDrawElements(GL_TRIANGLES, myIndexCount, GL_UNSIGNED_SHORT, 0);
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
- glPopClientAttrib();
- glPopAttrib();
+ glPopClientAttrib();
+ glPopAttrib();
}
IMeshPtr makeMesh(IMeshBufferPtr aBuffer)
{
- //aBuffer->printStats();
+ //aBuffer->printStats();
- // Prefer VBOs for large meshes
- if (aBuffer->vertexCount() > 50 && GLEW_ARB_vertex_buffer_object)
- return IMeshPtr(new VBOMesh(aBuffer));
- else
- return IMeshPtr(new VertexArrayMesh(aBuffer));
+ // Prefer VBOs for large meshes
+ if (aBuffer->vertexCount() > 50 && GLEW_ARB_vertex_buffer_object)
+ return IMeshPtr(new VBOMesh(aBuffer));
+ else
+ return IMeshPtr(new VertexArrayMesh(aBuffer));
}
IMeshBufferPtr makeMeshBuffer()
{
- return IMeshBufferPtr(new MeshBuffer);
+ return IMeshBufferPtr(new MeshBuffer);
}
// A resource that reads data from a filesystem directory
class FilesystemResource : public IResource {
public:
- FilesystemResource(const path& aPath)
- : myPath(aPath)
- {
-
- }
-
- // IResource interface
- string name() const { return myPath.filename(); }
- string xmlFileName() const
- {
- return (myPath / (name() + ".xml")).file_string();
- }
-
- Handle openFile(const string& aFileName)
- {
- return Handle((myPath / aFileName).file_string(), Handle::READ);
- }
-
- Handle writeFile(const string& aFileName)
- {
- return Handle((myPath / aFileName).file_string(), Handle::WRITE);
- }
+ FilesystemResource(const path& aPath)
+ : myPath(aPath)
+ {
+
+ }
+
+ // IResource interface
+ string name() const { return myPath.filename(); }
+ string xmlFileName() const
+ {
+ return (myPath / (name() + ".xml")).file_string();
+ }
+
+ Handle openFile(const string& aFileName)
+ {
+ return Handle((myPath / aFileName).file_string(), Handle::READ);
+ }
+
+ Handle writeFile(const string& aFileName)
+ {
+ return Handle((myPath / aFileName).file_string(), Handle::WRITE);
+ }
private:
- const path myPath;
+ const path myPath;
};
IResource::Handle::Handle(const string& aFileName, Mode aMode)
- : myFileName(aFileName)
+ : myFileName(aFileName)
{
- if (aMode == READ) {
- myReadStream = shared_ptr<ifstream>(new ifstream(aFileName.c_str()));
+ if (aMode == READ) {
+ myReadStream = shared_ptr<ifstream>(new ifstream(aFileName.c_str()));
- if (!myReadStream->good())
- throw runtime_error("Failed to open resource file " + aFileName);
- }
- else if (aMode == WRITE) {
- myWriteStream = shared_ptr<ofstream>(new ofstream(aFileName.c_str()));
+ if (!myReadStream->good())
+ throw runtime_error("Failed to open resource file " + aFileName);
+ }
+ else if (aMode == WRITE) {
+ myWriteStream = shared_ptr<ofstream>(new ofstream(aFileName.c_str()));
- if (!myWriteStream->good())
- throw runtime_error("Failed to open resource file " + aFileName);
- }
- else
- throw runtime_error("Bad mode for Handle");
+ if (!myWriteStream->good())
+ throw runtime_error("Failed to open resource file " + aFileName);
+ }
+ else
+ throw runtime_error("Bad mode for Handle");
}
namespace {
- const char* classes[] = {
- "maps", "buildings", "engines", "waggons",
- NULL
- };
-
- typedef map<string, ResourceList> ResourceMap;
- ResourceMap theResources;
-
- ResourceList& resClassList(const string& aClass)
- {
- if (theResources.find(aClass) == theResources.end())
- theResources[aClass] = ResourceList();
- return theResources[aClass];
- }
-
- void addResource(const string& aClass, IResourcePtr aRes)
- {
- resClassList(aClass).push_back(aRes);
- }
-
- void addResourceDir(const char* aClass, const path& aPath)
- {
- debug() << "Adding " << aPath << " to " << aClass << " class";
-
- const path xmlFile = aPath / (aPath.filename() + ".xml");
-
- if (!exists(xmlFile))
- warn() << "Missing resource XML file: " << xmlFile;
- else
- addResource(aClass, IResourcePtr(new FilesystemResource(aPath)));
- }
+ const char* classes[] = {
+ "maps", "buildings", "engines", "waggons",
+ NULL
+ };
+
+ typedef map<string, ResourceList> ResourceMap;
+ ResourceMap theResources;
+
+ ResourceList& resClassList(const string& aClass)
+ {
+ if (theResources.find(aClass) == theResources.end())
+ theResources[aClass] = ResourceList();
+ return theResources[aClass];
+ }
+
+ void addResource(const string& aClass, IResourcePtr aRes)
+ {
+ resClassList(aClass).push_back(aRes);
+ }
+
+ void addResourceDir(const char* aClass, const path& aPath)
+ {
+ debug() << "Adding " << aPath << " to " << aClass << " class";
+
+ const path xmlFile = aPath / (aPath.filename() + ".xml");
+
+ if (!exists(xmlFile))
+ warn() << "Missing resource XML file: " << xmlFile;
+ else
+ addResource(aClass, IResourcePtr(new FilesystemResource(aPath)));
+ }
- void lookInDir(const path& aPath)
- {
- log() << "Looking for resources in " << aPath;
-
- for (const char** p = classes; *p != NULL; ++p) {
- if (exists(aPath / *p)) {
- for (directory_iterator it(aPath / *p);
- it != directory_iterator(); ++it)
- if (is_directory(it->status()))
- addResourceDir(*p, *it);
- }
- }
- }
+ void lookInDir(const path& aPath)
+ {
+ log() << "Looking for resources in " << aPath;
+
+ for (const char** p = classes; *p != NULL; ++p) {
+ if (exists(aPath / *p)) {
+ for (directory_iterator it(aPath / *p);
+ it != directory_iterator(); ++it)
+ if (is_directory(it->status()))
+ addResourceDir(*p, *it);
+ }
+ }
+ }
}
// Set up the resource database and cache available objects
void initResources()
{
- lookInDir(current_path());
+ lookInDir(current_path());
}
// Find all the resources of the given type
void enumResources(const string& aClass, ResourceList& aList)
{
- ResourceList& lst = resClassList(aClass);
- copy(lst.begin(), lst.end(), back_inserter(aList));
+ ResourceList& lst = resClassList(aClass);
+ copy(lst.begin(), lst.end(), back_inserter(aList));
}
namespace {
- // Find a resource of a particular type
- // Returns null pointer on failure
- IResourcePtr maybeFindResource(const string& aResId, const string& aClass)
- {
- ResourceList& rlist = resClassList(aClass);
- for (ResourceListIt it = rlist.begin(); it != rlist.end(); ++it) {
- if ((*it)->name() == aResId)
- return *it;
- }
-
- return IResourcePtr();
- }
+ // Find a resource of a particular type
+ // Returns null pointer on failure
+ IResourcePtr maybeFindResource(const string& aResId, const string& aClass)
+ {
+ ResourceList& rlist = resClassList(aClass);
+ for (ResourceListIt it = rlist.begin(); it != rlist.end(); ++it) {
+ if ((*it)->name() == aResId)
+ return *it;
+ }
+
+ return IResourcePtr();
+ }
}
// Find a resource or throw an exception on failure
IResourcePtr findResource(const string& aResId, const string& aClass)
{
- IResourcePtr r = maybeFindResource(aResId, aClass);
- if (r)
- return r;
- else
- throw runtime_error("Failed to find resource " + aResId
- + " in class " + aClass);
+ IResourcePtr r = maybeFindResource(aResId, aClass);
+ if (r)
+ return r;
+ else
+ throw runtime_error("Failed to find resource " + aResId
+ + " in class " + aClass);
}
// True if the given resource exists
bool resourceExists(const string& aResId, const string& aClass)
{
- return maybeFindResource(aResId, aClass);
+ return maybeFindResource(aResId, aClass);
}
// Create an empty resource directory
IResourcePtr makeNewResource(const string& aResId, const string& aClass)
{
- const path p = path(aClass) / aResId;
+ const path p = path(aClass) / aResId;
- if (exists(p))
- throw runtime_error("Cannot create resource " + aResId
- + " in class " + aClass + ": already exists!");
+ if (exists(p))
+ throw runtime_error("Cannot create resource " + aResId
+ + " in class " + aClass + ": already exists!");
- if (!create_directories(p))
- throw runtime_error("Failed to create resource directory "
- + p.file_string());
+ if (!create_directories(p))
+ throw runtime_error("Failed to create resource directory "
+ + p.file_string());
- IResourcePtr r = IResourcePtr(new FilesystemResource(p));
- addResource(aClass, r);
+ IResourcePtr r = IResourcePtr(new FilesystemResource(p));
+ addResource(aClass, r);
- return r;
+ return r;
}
class StraightTrack : public ITrackSegment,
public enable_shared_from_this<StraightTrack> {
public:
- StraightTrack(const Direction& aDirection);
- ~StraightTrack();
+ StraightTrack(const Direction& aDirection);
+ ~StraightTrack();
- void render() const;
+ void render() const;
- void setOrigin(int x, int y) { origin.x = x; origin.y = y; }
- double segmentLength(const track::TravelToken& aToken) const { return 1.0; }
+ void setOrigin(int x, int y) { origin.x = x; origin.y = y; }
+ double segmentLength(const track::TravelToken& aToken) const { return 1.0; }
- Vector<double> offsetForDelta(double aDelta) const;
- Connection nextPosition(const track::TravelToken& aDirection) const;
- bool isValidDirection(const Direction& aDirection) const;
- void getEndpoints(list<Point<int> >& aList) const;
+ Vector<double> offsetForDelta(double aDelta) const;
+ Connection nextPosition(const track::TravelToken& aDirection) const;
+ bool isValidDirection(const Direction& aDirection) const;
+ void getEndpoints(list<Point<int> >& aList) const;
- ITrackSegmentPtr mergeExit(const Point<int>& aPoint,
- const track::Direction& aDirection);
- track::TravelToken getTravelToken(track::Position aPosition,
- track::Direction aDirection) const;
- xml::element toXml() const;
+ ITrackSegmentPtr mergeExit(const Point<int>& aPoint,
+ const track::Direction& aDirection);
+ track::TravelToken getTravelToken(track::Position aPosition,
+ track::Direction aDirection) const;
+ xml::element toXml() const;
private:
- void transform(const track::TravelToken& aToken, double aDelta) const;
- void ensureValidDirection(const track::Direction& aDirection) const;
+ void transform(const track::TravelToken& aToken, double aDelta) const;
+ void ensureValidDirection(const track::Direction& aDirection) const;
- Point<int> origin; // Absolute position
- Direction direction;
+ Point<int> origin; // Absolute position
+ Direction direction;
};
StraightTrack::StraightTrack(const Direction& aDirection)
- : direction(aDirection)
+ : direction(aDirection)
{
}
track::TravelToken
StraightTrack::getTravelToken(track::Position aPosition,
- track::Direction aDirection) const
+ track::Direction aDirection) const
{
- ensureValidDirection(aDirection);
-
- track::TravelToken tok = {
- aDirection,
- aPosition,
- track::CHOOSE_STRAIGHT_ON,
- bind(&StraightTrack::transform, this, _1, _2)
- };
- tok.choices.insert(track::CHOOSE_STRAIGHT_ON);
- return tok;
+ ensureValidDirection(aDirection);
+
+ track::TravelToken tok = {
+ aDirection,
+ aPosition,
+ track::CHOOSE_STRAIGHT_ON,
+ bind(&StraightTrack::transform, this, _1, _2)
+ };
+ tok.choices.insert(track::CHOOSE_STRAIGHT_ON);
+ return tok;
}
void StraightTrack::transform(const track::TravelToken& aToken,
- double aDelta) const
+ double aDelta) const
{
- assert(aDelta < 1.0);
+ assert(aDelta < 1.0);
- if (aToken.direction == -direction)
- aDelta = 1.0 - aDelta;
+ if (aToken.direction == -direction)
+ aDelta = 1.0 - aDelta;
- const double xTrans = direction == axis::X ? aDelta : 0;
- const double yTrans = direction == axis::Y ? aDelta : 0;
+ const double xTrans = direction == axis::X ? aDelta : 0;
+ const double yTrans = direction == axis::Y ? aDelta : 0;
- glTranslated(static_cast<double>(origin.x) + xTrans,
- 0.0,
- static_cast<double>(origin.y) + yTrans);
+ glTranslated(static_cast<double>(origin.x) + xTrans,
+ 0.0,
+ static_cast<double>(origin.y) + yTrans);
- if (direction == axis::Y)
- glRotated(-90.0, 0.0, 1.0, 0.0);
+ if (direction == axis::Y)
+ glRotated(-90.0, 0.0, 1.0, 0.0);
- glTranslated(-0.5, 0.0, 0.0);
+ glTranslated(-0.5, 0.0, 0.0);
- if (aToken.direction == -direction)
- glRotated(-180.0, 0.0, 1.0, 0.0);
+ if (aToken.direction == -direction)
+ glRotated(-180.0, 0.0, 1.0, 0.0);
}
ITrackSegmentPtr StraightTrack::mergeExit(const Point<int>& aPoint,
- const track::Direction& aDirection)
+ const track::Direction& aDirection)
{
- debug() << "mergeExit aPoint=" << aPoint
- << " aDirection=" << aDirection
- << " me=" << origin;
-
- // See if this is already a valid exit
- if (isValidDirection(aDirection) && aPoint == origin)
- return shared_from_this();
-
- // See if we can make this a crossover track
- if (direction != aDirection && aPoint == origin)
- return makeCrossoverTrack();
-
- // See if we can make some points
- if (isValidDirection(aDirection)) {
- // X-aligned points
- if (aPoint == origin + makePoint(-2, 1))
- return makePoints(-axis::X, true);
- else if (aPoint == origin + makePoint(-2, -1))
- return makePoints(-axis::X, false);
- else if (aPoint == origin + makePoint(2, 1))
- return makePoints(axis::X, false);
- else if (aPoint == origin + makePoint(2, -1))
- return makePoints(axis::X, true);
-
- // Y-aligned points
- if (aPoint == origin + makePoint(1, -2))
- return makePoints(-axis::Y, false);
- else if (aPoint == origin + makePoint(-1, -2))
- return makePoints(-axis::Y, true);
- else if (aPoint == origin + makePoint(1, 2))
- return makePoints(axis::Y, true);
- else if (aPoint == origin + makePoint(-1, 2))
- return makePoints(axis::Y, false);
- }
+ debug() << "mergeExit aPoint=" << aPoint
+ << " aDirection=" << aDirection
+ << " me=" << origin;
+
+ // See if this is already a valid exit
+ if (isValidDirection(aDirection) && aPoint == origin)
+ return shared_from_this();
+
+ // See if we can make this a crossover track
+ if (direction != aDirection && aPoint == origin)
+ return makeCrossoverTrack();
+
+ // See if we can make some points
+ if (isValidDirection(aDirection)) {
+ // X-aligned points
+ if (aPoint == origin + makePoint(-2, 1))
+ return makePoints(-axis::X, true);
+ else if (aPoint == origin + makePoint(-2, -1))
+ return makePoints(-axis::X, false);
+ else if (aPoint == origin + makePoint(2, 1))
+ return makePoints(axis::X, false);
+ else if (aPoint == origin + makePoint(2, -1))
+ return makePoints(axis::X, true);
+
+ // Y-aligned points
+ if (aPoint == origin + makePoint(1, -2))
+ return makePoints(-axis::Y, false);
+ else if (aPoint == origin + makePoint(-1, -2))
+ return makePoints(-axis::Y, true);
+ else if (aPoint == origin + makePoint(1, 2))
+ return makePoints(axis::Y, true);
+ else if (aPoint == origin + makePoint(-1, 2))
+ return makePoints(axis::Y, false);
+ }
- // Not possible to merge
- return ITrackSegmentPtr();
+ // Not possible to merge
+ return ITrackSegmentPtr();
}
bool StraightTrack::isValidDirection(const Direction& aDirection) const
{
- if (direction == axis::X)
- return aDirection == axis::X || -aDirection == axis::X;
- else
- return aDirection == axis::Y || -aDirection == axis::Y;
+ if (direction == axis::X)
+ return aDirection == axis::X || -aDirection == axis::X;
+ else
+ return aDirection == axis::Y || -aDirection == axis::Y;
}
void StraightTrack::getEndpoints(list<Point<int> >& aList) const
{
- aList.push_back(origin);
+ aList.push_back(origin);
}
void StraightTrack::ensureValidDirection(const Direction& aDirection) const
{
- if (!isValidDirection(aDirection))
- throw runtime_error
- ("Invalid direction on straight track: "
- + lexical_cast<string>(aDirection)
- + " (should be parallel to "
- + lexical_cast<string>(direction) + ")");
+ if (!isValidDirection(aDirection))
+ throw runtime_error
+ ("Invalid direction on straight track: "
+ + lexical_cast<string>(aDirection)
+ + " (should be parallel to "
+ + lexical_cast<string>(direction) + ")");
}
Connection StraightTrack::nextPosition(const track::TravelToken& aToken) const
{
- ensureValidDirection(aToken.direction);
-
- if (aToken.direction == axis::X)
- return make_pair(makePoint(origin.x + 1, origin.y), axis::X);
- else if (aToken.direction == -axis::X)
- return make_pair(makePoint(origin.x - 1, origin.y), -axis::X);
- else if (aToken.direction == axis::Y)
- return make_pair(makePoint(origin.x, origin.y + 1), axis::Y);
- else if (aToken.direction == -axis::Y)
- return make_pair(makePoint(origin.x, origin.y - 1), -axis::Y);
- else
- assert(false);
+ ensureValidDirection(aToken.direction);
+
+ if (aToken.direction == axis::X)
+ return make_pair(makePoint(origin.x + 1, origin.y), axis::X);
+ else if (aToken.direction == -axis::X)
+ return make_pair(makePoint(origin.x - 1, origin.y), -axis::X);
+ else if (aToken.direction == axis::Y)
+ return make_pair(makePoint(origin.x, origin.y + 1), axis::Y);
+ else if (aToken.direction == -axis::Y)
+ return make_pair(makePoint(origin.x, origin.y - 1), -axis::Y);
+ else
+ assert(false);
}
void StraightTrack::render() const
{
- glPushMatrix();
+ glPushMatrix();
- if (direction == axis::X)
- glRotated(90.0, 0.0, 1.0, 0.0);
+ if (direction == axis::X)
+ glRotated(90.0, 0.0, 1.0, 0.0);
- renderStraightRail();
+ renderStraightRail();
- // Draw the sleepers
- glRotated(90.0, 0.0, 1.0, 0.0);
- glTranslated(-0.4, 0.0, 0.0);
-
- for (int i = 0; i < 4; i++) {
- renderSleeper();
- glTranslated(0.25, 0.0, 0.0);
- }
+ // Draw the sleepers
+ glRotated(90.0, 0.0, 1.0, 0.0);
+ glTranslated(-0.4, 0.0, 0.0);
+
+ for (int i = 0; i < 4; i++) {
+ renderSleeper();
+ glTranslated(0.25, 0.0, 0.0);
+ }
- glPopMatrix();
+ glPopMatrix();
}
xml::element StraightTrack::toXml() const
{
- return xml::element("straightTrack")
- .addAttribute("align", direction == axis::X ? "x" : "y");
+ return xml::element("straightTrack")
+ .addAttribute("align", direction == axis::X ? "x" : "y");
}
ITrackSegmentPtr makeStraightTrack(const Direction& aDirection)
{
- Direction realDir(aDirection);
+ Direction realDir(aDirection);
- // Direction must either be along axis::X or axis::Y but we
- // allow the opositite direction here too
- if (realDir == -axis::X || realDir == -axis::Y)
- realDir = -realDir;
-
- if (realDir != axis::X && realDir != axis::Y)
- throw runtime_error("Illegal straight track direction: "
- + lexical_cast<string>(aDirection));
+ // Direction must either be along axis::X or axis::Y but we
+ // allow the opositite direction here too
+ if (realDir == -axis::X || realDir == -axis::Y)
+ realDir = -realDir;
+
+ if (realDir != axis::X && realDir != axis::Y)
+ throw runtime_error("Illegal straight track direction: "
+ + lexical_cast<string>(aDirection));
- return ITrackSegmentPtr(new StraightTrack(realDir));
+ return ITrackSegmentPtr(new StraightTrack(realDir));
}
#include <GL/gl.h>
-using namespace std;
-using namespace std::tr1;
-
namespace {
const float RAIL_WIDTH = 0.05f;
const float GAUGE = 0.5f;
class Tree : public IScenery {
public:
- Tree();
+ Tree();
- // IScenery interface
- void render() const;
- void setPosition(float x, float y, float z);
+ // IScenery interface
+ void render() const;
+ void setPosition(float x, float y, float z);
private:
- IBillboardPtr billboard;
- int texHeight;
+ IBillboardPtr billboard;
+ int texHeight;
};
Tree::Tree()
{
- const char* trees[] = {
- "images/a-tree.png",
- "images/a-nother-tree.png",
- "images/cloud-tree.png",
- "images/real_tree.png",
- };
+ const char* trees[] = {
+ "images/a-tree.png",
+ "images/a-nother-tree.png",
+ "images/cloud-tree.png",
+ "images/real_tree.png",
+ };
- static UniformInt rnd(0, sizeof(trees)/sizeof(char*) - 1);
+ static UniformInt rnd(0, sizeof(trees)/sizeof(char*) - 1);
- billboard = makeCylindricalBillboard(
- loadTexture(trees[rnd()]));
- billboard->setScale(1.2f);
+ billboard = makeCylindricalBillboard(
+ loadTexture(trees[rnd()]));
+ billboard->setScale(1.2f);
}
void Tree::render() const
{
- billboard->render();
+ billboard->render();
}
void Tree::setPosition(float x, float y, float z)
{
- billboard->setPosition(x, y + 0.6f, z);
+ billboard->setPosition(x, y + 0.6f, z);
}
ISceneryPtr makeTree()
{
- return ISceneryPtr(new Tree);
+ return ISceneryPtr(new Tree);
}
class UIDemo : public IScreen {
public:
- UIDemo();
+ UIDemo();
- // IScreen interface
- void display(IGraphicsPtr aContext) const {}
- void overlay() const;
- void update(IPickBufferPtr aPickBuffer, int aDelta) {}
- void onKeyDown(SDLKey aKey) {}
- void onKeyUp(SDLKey aKey) {}
- void onMouseMove(IPickBufferPtr aPickBuffer, int x, int y,
- int xrel, int yrel) {}
- void onMouseClick(IPickBufferPtr pick_buffer, int x, int y,
- MouseButton button);
- void onMouseRelease(IPickBufferPtr pick_buffer, int x, int y,
- MouseButton button) {}
+ // IScreen interface
+ void display(IGraphicsPtr aContext) const {}
+ void overlay() const;
+ void update(IPickBufferPtr aPickBuffer, int aDelta) {}
+ void onKeyDown(SDLKey aKey) {}
+ void onKeyUp(SDLKey aKey) {}
+ void onMouseMove(IPickBufferPtr aPickBuffer, int x, int y,
+ int xrel, int yrel) {}
+ void onMouseClick(IPickBufferPtr pick_buffer, int x, int y,
+ MouseButton button);
+ void onMouseRelease(IPickBufferPtr pick_buffer, int x, int y,
+ MouseButton button) {}
private:
- void btn1Click(gui::Widget& w);
+ void btn1Click(gui::Widget& w);
- gui::ILayoutPtr layout;
+ gui::ILayoutPtr layout;
};
UIDemo::UIDemo()
{
- using namespace placeholders;
+ using namespace placeholders;
- layout = gui::makeLayout("layouts/demo.xml");
+ layout = gui::makeLayout("layouts/demo.xml");
- layout->get("/wnd1/btn1").connect(gui::Widget::SIG_CLICK,
- bind(&UIDemo::btn1Click, this, _1));
+ layout->get("/wnd1/btn1").connect(gui::Widget::SIG_CLICK,
+ bind(&UIDemo::btn1Click, this, _1));
}
void UIDemo::btn1Click(gui::Widget& w)
{
- static int cnt = 0;
- debug() << "Clicked button 1!";
+ static int cnt = 0;
+ debug() << "Clicked button 1!";
- layout->cast<gui::Label>("/wnd1/cntlabel").text(
- boost::lexical_cast<string>(++cnt));
+ layout->cast<gui::Label>("/wnd1/cntlabel").text(
+ boost::lexical_cast<string>(++cnt));
}
void UIDemo::overlay() const
{
- layout->render();
+ layout->render();
}
void UIDemo::onMouseClick(IPickBufferPtr pick_buffer, int x, int y,
- MouseButton button)
+ MouseButton button)
{
- layout->click(x, y);
+ layout->click(x, y);
}
IScreenPtr makeUIDemo()
{
- return IScreenPtr(new UIDemo);
+ return IScreenPtr(new UIDemo);
}