Difference between revisions of "User:Michelinux/3DGlasses"
(Line class documentation) |
(PolyLine and Ellipse classes documentation added) |
||
Line 38: | Line 38: | ||
It's the main class of the library; you need to instanziate one (probably no more than one) object of this class. | It's the main class of the library; you need to instanziate one (probably no more than one) object of this class. | ||
− | This class incapsulates a GRRLIB_texImg where the drawing of the 3D scene happens. ''startDrawing()'' method clears internal image while ''doneDrawing()'' puts it on the screen. | + | This class incapsulates a ''GRRLIB_texImg'' where the drawing of the 3D scene happens. ''startDrawing()'' method clears internal image while ''doneDrawing()'' puts it on the screen. |
You can provide a callback function to the constructor of this class; if configuration file is not found, che callback is called to ask user some parameters. If configuration file is found, callback is not called. | You can provide a callback function to the constructor of this class; if configuration file is not found, che callback is called to ask user some parameters. If configuration file is found, callback is not called. | ||
− | Glasses class objects have the ''quality'' attribute which can be ''FAST'' or ''ACCURATE'' (the default). Many objects use different rendering algorithms according the value of this attribute. | + | ''Glasses'' class objects have the ''quality'' attribute which can be ''FAST'' or ''ACCURATE'' (the default). Many objects use different rendering algorithms according the value of this attribute. |
That's the public part of the class: | That's the public part of the class: | ||
Line 73: | Line 73: | ||
==== Sample code ==== | ==== Sample code ==== | ||
− | The user can select parameter using up/down buttons of wiimote, adjust values with left/right buttons. A rectangle is shown to adjust xYRatioCorrection: make it a square to set proper value. Press button A when finished. | + | The user can select parameter using up/down buttons of wiimote, adjust values with left/right buttons. A rectangle is shown to adjust ''xYRatioCorrection'': make it a square to set proper value. Press button A when finished. |
#include <wiiuse/wpad.h> | #include <wiiuse/wpad.h> | ||
Line 188: | Line 188: | ||
This abstract class is the ancestor of all the objects you can draw with 3DGlasses library. | This abstract class is the ancestor of all the objects you can draw with 3DGlasses library. | ||
− | The constructor needs a reference to a Glasses | + | The constructor needs a reference to a ''Glasses'' class object to learn about geometry. |
Every object has its own ''visible'' attribute: ''visibility'' is an enum wich can be ''NOT_VISIBLE'', ''PERHAPS_VISIBLE'' or ''VISIBLE''. | Every object has its own ''visible'' attribute: ''visibility'' is an enum wich can be ''NOT_VISIBLE'', ''PERHAPS_VISIBLE'' or ''VISIBLE''. | ||
Line 211: | Line 211: | ||
=== l3dg::Point === | === l3dg::Point === | ||
− | A Point is the simplest object you can draw: it is projected to two screen points of different color, each one seen by only one eye. | + | A ''Point'' is the simplest object you can draw: it is projected to two screen points of different color, each one seen by only one eye. |
class Point : public DrawableObject { | class Point : public DrawableObject { | ||
Line 236: | Line 236: | ||
=== l3dg::Line === | === l3dg::Line === | ||
− | A line is described by an array of two endpoints: the first endpoint is considered the ''position'' of the object, the other one is the '' | + | A line is described by an array of two endpoints: the first endpoint is considered the ''position'' of the object, the other one is the ''end''. |
class Line : public DrawableObject { | class Line : public DrawableObject { | ||
Line 268: | Line 268: | ||
glasses.doneDrawing(); | glasses.doneDrawing(); | ||
GRRLIB_Render(); | GRRLIB_Render(); | ||
+ | |||
+ | === l3dg::PolyLine === | ||
+ | A ''PolyLine'' is a sequence of lines, each one (except the first line) beginning at the end of the previous one. | ||
+ | |||
+ | The polyline is defined by an array of n + 1 points; where n is the number of lines. | ||
+ | |||
+ | You can create a closed polyline (such as a polygon) making the last point egual to the first one. | ||
+ | |||
+ | The first point is the ''position'' of the polyline. | ||
+ | |||
+ | class PolyLine : public DrawableObject { | ||
+ | public: | ||
+ | PolyLine(Glasses &glasses, unsigned int pointsNumber, const Vector3D points[], u32 color); | ||
+ | PolyLine(const PolyLine &pl); | ||
+ | ~PolyLine(); | ||
+ | void setPosition(const Vector3D &position); | ||
+ | unsigned int getPointsNumber() const; | ||
+ | const Vector3D &getPoint(unsigned int pointNumber) const; | ||
+ | void draw() const; | ||
+ | protected: | ||
+ | //... | ||
+ | }; | ||
+ | |||
+ | === l3dg::Ellipse === | ||
+ | An ellipse can be approssimated by a polygon with a convenient number of edges. | ||
+ | |||
+ | An ''Ellipse'' class object can be defined by the center and the two semiaxes; the semiaxes determinates both size and orientation of the ellipse. | ||
+ | |||
+ | The actual number of edges of an ''Ellipse'' class object depends upon the ''quality'' attribute of the ''glasses'' object | ||
+ | |||
+ | class Ellipse : public PolyLine { | ||
+ | public: | ||
+ | Ellipse(Glasses &glasses, const Vector3D ¢er, const Vector3D semiAxes[2], u32 color); | ||
+ | Ellipse(const Ellipse &e); | ||
+ | private: | ||
+ | //... | ||
+ | }; | ||
== Contacts == | == Contacts == |
Revision as of 14:34, 28 January 2010
3DGlasses | |
![]() | |
General | |
---|---|
Author(s) | Michelinux |
Type | Library |
Description
3DGlasses is a C++ library to develop applications that can be seen wearing 3D glasses.
This is not a full featured 3D library: it's your responsability to draw objects in correct z-order.
Development status
- Reading/writing configuration file works
- Geometry init works
- Simple shapes are drawn correctly
Supported glasses
Different kind of 3D glasses exists, this library supports the old ones with each lens of a different color; these glasses are called anaglyphs. Most common anaglyphs have a red lens for left eye, and a cyan lens for the right one, also exists glasses with green - magenta and very rare ones with yellow - blue lenses; 3DGlasses library supports all of them.
Geometry
Origin of the axis is set at the center of the screen, with x incresing towards right, y increasing towards botton and z increasing towards "internal" of screen. For negative values of z the object appears outside the tv, inside the screen for positive values.
For z = 0, x goes from -320 to 320; perspective makes the range narrower for z < 0 and wider for z > 0. Y scale may change because the library tryes to keep 1:1 aspect ratio between axis.
Configuration file
The configuration file 3DGlasses.cfg, inside the main directory of your SD, is shared among all applications using this library. This file contains geometry info about your screen and the kind of anaglyphs you wear.
Probably this file is created the first time you run an application using 3DGlasses. If you change tv or glasses just delete this file (it will be recreated) or edit it by hand (instructions are inside the file itself).
Use of colors
Since the two eyes see different colors of the image you must avoid pure colors in your applications: if you draw a monochromatic red object it will be seen only by left eye with no 3D effect at all.
Classes
3DGlasses library defines its own namespace: l3dg with the following classes
l3dg::Glasses
It's the main class of the library; you need to instanziate one (probably no more than one) object of this class.
This class incapsulates a GRRLIB_texImg where the drawing of the 3D scene happens. startDrawing() method clears internal image while doneDrawing() puts it on the screen.
You can provide a callback function to the constructor of this class; if configuration file is not found, che callback is called to ask user some parameters. If configuration file is found, callback is not called.
Glasses class objects have the quality attribute which can be FAST or ACCURATE (the default). Many objects use different rendering algorithms according the value of this attribute.
That's the public part of the class:
class Glasses { public: Glasses(void callback(glassesTypes& , unsigned int&, bool&, float&, unsigned int&)=NULL); Glasses(const Glasses &g); ~Glasses(); u32 getLeftColor() const; u32 getRightColor() const; void splitColor(u32 color, u32 &left, u32 &right) const; qualities getQuality() const; void setQuality(qualities quality); visibility getPerspectives(const Vector3D &point, Vector2D &left, Vector2D &right) const; float getMinX(float z, bool overscanSafe) const; float getMaxX(float z, bool overscanSafe) const; float getMinY(float z, bool overscanSafe) const; float getMaxY(float z, bool overscanSafe) const; float getMinZ(float x, float y, bool overscanSafe) const; void startDrawing(); void doneDrawing() const; void drawDot(int x, int y, eyes eye, u32 color); void drawDot(int x, int y, eyes eye, u32 color, u32 opaqueness, u32 transparency); void drawDot(int x, int y, eyes eye, u32 color, u32 textureColor); void dualDotDraw(int x, int y, u32 color, u32 leftTextureColor, u32 rightTextureColor); private: //... };
Sample code
The user can select parameter using up/down buttons of wiimote, adjust values with left/right buttons. A rectangle is shown to adjust xYRatioCorrection: make it a square to set proper value. Press button A when finished.
#include <wiiuse/wpad.h> #include <3DGlasses.h> #include "BMfont4.h" #define GRAY 0x808080FF #define WHITE 0xFFFFFFFF GRRLIB_texImg *tex_BMfont4; void callback(l3dg::glassesTypes &glassesType, unsigned int &screenSize, bool &isWidescreen, float &xYRatioCorrection, unsigned int &distanceEyesScreen) { guVector v[5]; v[0].x= 280; v[0].y= 320; v[0].z= 0; v[1].x= 370; v[1].y= 320; v[1].z= 0; v[2].x= 370; v[2].y= 320 + 100 * xYRatioCorrection; v[2].z= 0; v[3].x= 280; v[3].y= v[2].y; v[3].z= 0; v[4].x= 280; v[4].y= 320; v[4].z= 0; u32 textColors[4]; u32 quadColors[5]; u32 pressed; int type= glassesType; int i; int hilighted= 0; do { for (i= 0; i < 4; i++) { if (i == hilighted) { textColors[i]= WHITE; } else { textColors[i]= GRAY; } } for (i= 0; i < 5; i++) { if (hilighted == 4) { quadColors[i]= WHITE; } else { quadColors[i]= GRAY; } } WPAD_ScanPads(); pressed= WPAD_ButtonsDown(0); switch (hilighted) { case 0: if (pressed & WPAD_BUTTON_RIGHT) type++; else if (pressed & WPAD_BUTTON_LEFT) type--; if (type < 0) type= l3dg::glassesTypesNumber - 1; else if (type >= l3dg::glassesTypesNumber) type= 0; break; case 1: if (pressed & WPAD_BUTTON_RIGHT) screenSize++; else if (pressed & WPAD_BUTTON_LEFT) screenSize--; break; case 2: if (pressed & (WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT)) isWidescreen= !isWidescreen; break; case 3: if (pressed & WPAD_BUTTON_RIGHT) distanceEyesScreen++; else if (pressed & WPAD_BUTTON_LEFT) distanceEyesScreen--; break; case 4: if (pressed & WPAD_BUTTON_RIGHT) xYRatioCorrection+= 0.05; else if (pressed & WPAD_BUTTON_LEFT) xYRatioCorrection-= 0.05; v[2].y= 320 + 100 * xYRatioCorrection; v[3].y= v[2].y; break; } if (pressed & (WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT)) { } if (pressed & WPAD_BUTTON_DOWN) { hilighted++; if (hilighted > 4) hilighted= 0; } if (pressed & WPAD_BUTTON_UP) { hilighted--; if (hilighted < 0) hilighted= 4; } GRRLIB_FillScreen(0x00000000); GRRLIB_Printf(64, 64, tex_BMfont4, textColors[0], 1, "GLASSES TYPE: %s", l3dg::glassesTypesStrings[type]); GRRLIB_Printf(64, 128, tex_BMfont4, textColors[1], 1, "SCREEN SIZE: %d\"", screenSize); if (isWidescreen) { GRRLIB_Printf(64, 192, tex_BMfont4, textColors[2], 1, "16:9 WIDESCREEN"); } else { GRRLIB_Printf(64, 192, tex_BMfont4, textColors[2], 1, "4:3"); } GRRLIB_Printf(64, 256, tex_BMfont4, textColors[3], 1, "DISTANCE EYES-SCREEN: %d CM", distanceEyesScreen); GRRLIB_NGone(v, quadColors, 5); GRRLIB_Render(); } while (!(pressed & WPAD_BUTTON_A)); glassesType= (l3dg::glassesTypes) type; } int main(int argc, char *argv[]) { GRRLIB_Init(); tex_BMfont4= GRRLIB_LoadTexture(BMfont4); GRRLIB_InitTileSet(tex_BMfont4, 16, 16, 32); WPAD_Init(); l3dg::Glasses glasses= l3dg::Glasses(callback); u32 pressed= WPAD_ButtonsDown(0); while (!(pressed & WPAD_BUTTON_HOME)) { GRRLIB_FillScreen(0x00000000); // draw your own 2D background here using GRRLIB glasses.startDrawing(); // draw 3D scene here using 3DGlasses library glasses.doneDrawing(); // draw your own 2D foreground here using GRRLIB GRRLIB_Render(); WPAD_ScanPads(); pressed= WPAD_ButtonsDown(0); } GRRLIB_Exit(); }
l3dg::DrawableObject
This abstract class is the ancestor of all the objects you can draw with 3DGlasses library.
The constructor needs a reference to a Glasses class object to learn about geometry.
Every object has its own visible attribute: visibility is an enum wich can be NOT_VISIBLE, PERHAPS_VISIBLE or VISIBLE. PERHAPS_VISIBLE is used when the object is near the border of the screen (overscan unsafe area) or when its visibility is hard to compute.
class DrawableObject { public: DrawableObject(Glasses &glasses, const Vector3D &position, u32 color); DrawableObject(const DrawableObject &d); virtual void setPosition(const Vector3D &position); const Vector3D &getPosition() const; void setColor(u32 color); u32 getColor() const; visibility getVisibility() const; virtual void draw() const =0; protected: Glasses *glasses; Vector3D position; u32 color; visibility visible; };
l3dg::Point
A Point is the simplest object you can draw: it is projected to two screen points of different color, each one seen by only one eye.
class Point : public DrawableObject { public: Point(Glasses &glasses, const Vector3D &position, u32 color); Point(const Point &p); void setPosition(const Vector3D &position); void draw() const; private: //... };
Sample code
Draw a single point, half way between screen and observer.
l3dg::Glasses glasses= l3dg::Glasses(callback); l3dg::Vector3D position= l3dg::Vector3D(0, 0, glasses.getMinZ(0, 0, true) / 2); l3dg::Point point= l3dg::Point(glasses, position, WHITE); GRRLIB_FillScreen(0x00000000); glasses.startDrawing(); point.draw(); glasses.doneDrawing(); GRRLIB_Render();
l3dg::Line
A line is described by an array of two endpoints: the first endpoint is considered the position of the object, the other one is the end.
class Line : public DrawableObject { public: Line(Glasses &glasses, const Vector3D points[2], u32 color); Line(const Line &l); void setPosition(const Vector3D &position); Vector3D getEnd() const; void draw() const; private: //... };
Sample code
Draw two lines: the first one with antialiasing, the second one without it.
l3dg::Glasses glasses= l3dg::Glasses(callback); l3dg::Vector3D endpoints[2]; endpoints[0]= l3dg::Vector3D(-100, -50, glasses.getMinZ(-100, -50, true) / 2); endpoints[1]= -endpoints[0]; l3dg::Line line1= l3dg::Line(glasses, endpoints, WHITE); endpoints[0].x = -endpoints[0].x; endpoints[1].x = -endpoints[1].x; l3dg::Line line2= l3dg::Line(glasses, endpoints, WHITE); GRRLIB_FillScreen(0x00000000); glasses.startDrawing(); glasses.setQuality(l3dg::ACCURATE); line1.draw(); glasses.setQuality(l3dg::FAST); line2.draw(); glasses.doneDrawing(); GRRLIB_Render();
l3dg::PolyLine
A PolyLine is a sequence of lines, each one (except the first line) beginning at the end of the previous one.
The polyline is defined by an array of n + 1 points; where n is the number of lines.
You can create a closed polyline (such as a polygon) making the last point egual to the first one.
The first point is the position of the polyline.
class PolyLine : public DrawableObject { public: PolyLine(Glasses &glasses, unsigned int pointsNumber, const Vector3D points[], u32 color); PolyLine(const PolyLine &pl); ~PolyLine(); void setPosition(const Vector3D &position); unsigned int getPointsNumber() const; const Vector3D &getPoint(unsigned int pointNumber) const; void draw() const; protected: //... };
l3dg::Ellipse
An ellipse can be approssimated by a polygon with a convenient number of edges.
An Ellipse class object can be defined by the center and the two semiaxes; the semiaxes determinates both size and orientation of the ellipse.
The actual number of edges of an Ellipse class object depends upon the quality attribute of the glasses object
class Ellipse : public PolyLine { public: Ellipse(Glasses &glasses, const Vector3D ¢er, const Vector3D semiAxes[2], u32 color); Ellipse(const Ellipse &e); private: //... };
Contacts
michelinux AT gmail DOT com