mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Bazaar/FTGL_Demo : a demo application for FTGL library
git-svn-id: svn://ultimatepp.org/upp/trunk@3872 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
97367a3496
commit
2c4e23d3d8
13 changed files with 2154 additions and 0 deletions
542
bazaar/FTGL_Demo/FTGLCtrl.cpp
Normal file
542
bazaar/FTGL_Demo/FTGLCtrl.cpp
Normal file
|
|
@ -0,0 +1,542 @@
|
|||
#include "FTGLCtrl.h"
|
||||
|
||||
FTGLCtrl::FTGLCtrl() : trackBall(this)
|
||||
{
|
||||
mode = INTERACTIVE;
|
||||
|
||||
currentFont = FTGL_EXTRUDE;
|
||||
|
||||
myString =
|
||||
"OpenGL is a powerful software interface for graphics "
|
||||
"hardware that allows graphics programmers to produce high-quality "
|
||||
"color images of 3D objects. abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL"
|
||||
"MNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
totalFonts = 0;
|
||||
|
||||
layouts.Add(new FTSimpleLayout);
|
||||
currentLayout = 0;
|
||||
|
||||
OX = -100;
|
||||
OY = 200;
|
||||
|
||||
#ifdef PLATFORM_OSX11
|
||||
SetFontFiles(Vector<String>()
|
||||
<< "/System/Library/Fonts/Helvetica.dfont",
|
||||
<< "/System/Library/Fonts/Geneva.dfont"
|
||||
;
|
||||
#elif defined(WIN32)
|
||||
SetFontFiles(Vector<String>()
|
||||
<< "C:\\WINDOWS\\Fonts\\arial.ttf"
|
||||
);
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
SetFontFiles(Vector<String>()
|
||||
<< "/usr/share/fonts/truetype/msttcorefonts/arial.ttf"
|
||||
);
|
||||
#else
|
||||
#error "UNSUPPORTED PLATFORM -- ADD HERE DEFAULT FONTS"
|
||||
#endif
|
||||
|
||||
initialLineLength = 300.0f;
|
||||
|
||||
FTSimpleLayout &sl = (FTSimpleLayout &)layouts.Top();
|
||||
sl.SetLineLength(initialLineLength);
|
||||
sl.SetFont(&fonts[currentFont]);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.13, 0.17, 0.32, 0.0);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
glPolygonOffset(1.0, 1.0); // ????
|
||||
|
||||
SetCamera();
|
||||
}
|
||||
|
||||
bool FTGLCtrl::Key(dword key, int count)
|
||||
{
|
||||
FTSimpleLayout *l = NULL;
|
||||
|
||||
// If the currentLayout is a SimpleLayout store a pointer in l
|
||||
if(hasLayout() && (dynamic_cast <FTSimpleLayout *>(&layouts[currentLayout])))
|
||||
l = (FTSimpleLayout *)&layouts[currentLayout];
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
GetMainWindow()->Break();
|
||||
break;
|
||||
|
||||
case K_RETURN:
|
||||
if(mode == EDITING)
|
||||
mode = INTERACTIVE;
|
||||
else
|
||||
mode = EDITING;
|
||||
break;
|
||||
|
||||
case K_TAB:
|
||||
if(l)
|
||||
{
|
||||
// Decrement the layout
|
||||
switch (l->GetAlignment())
|
||||
{
|
||||
case FTGL::ALIGN_LEFT:
|
||||
l->SetAlignment(FTGL::ALIGN_RIGHT);
|
||||
break;
|
||||
|
||||
case FTGL::ALIGN_RIGHT:
|
||||
l->SetAlignment(FTGL::ALIGN_CENTER);
|
||||
break;
|
||||
|
||||
case FTGL::ALIGN_CENTER:
|
||||
l->SetAlignment(FTGL::ALIGN_JUSTIFY);
|
||||
break;
|
||||
|
||||
case FTGL::ALIGN_JUSTIFY:
|
||||
l->SetAlignment(FTGL::ALIGN_LEFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case K_UP:
|
||||
currentFont = (GetFace()*NumStyles + (currentFont + 1) % NumStyles) % totalFonts;
|
||||
break;
|
||||
|
||||
case K_DOWN:
|
||||
currentFont = (GetFace()*NumStyles + (currentFont + NumStyles - 1) % NumStyles) % totalFonts;
|
||||
break;
|
||||
|
||||
case K_LEFT:
|
||||
fonts[currentFont].FaceSize(fonts[currentFont].FaceSize() - 1);
|
||||
break;
|
||||
|
||||
case K_RIGHT:
|
||||
fonts[currentFont].FaceSize(fonts[currentFont].FaceSize() + 1);
|
||||
break;
|
||||
|
||||
case K_PAGEUP:
|
||||
currentFont = (currentFont + NumStyles) % totalFonts;
|
||||
break;
|
||||
|
||||
case K_PAGEDOWN:
|
||||
currentFont = (currentFont + totalFonts - NumStyles) % totalFonts;
|
||||
break;
|
||||
|
||||
case K_HOME:
|
||||
currentLayout = (currentLayout + 1) % layouts.GetCount();
|
||||
break;
|
||||
|
||||
case K_END:
|
||||
currentLayout = (currentLayout + layouts.GetCount() - 1) % layouts.GetCount();
|
||||
break;
|
||||
|
||||
case K_F1:
|
||||
case K_F10:
|
||||
// If the current layout is simple decrement its line length
|
||||
if (l)
|
||||
l->SetLineLength(l->GetLineLength() - 10.0f);
|
||||
break;
|
||||
|
||||
case K_F2:
|
||||
case K_F11:
|
||||
// If the current layout is simple increment its line length
|
||||
if (l)
|
||||
l->SetLineLength(l->GetLineLength() + 10.0f);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(mode == EDITING)
|
||||
{
|
||||
if(isprint(key))
|
||||
myString << (char)key;
|
||||
else if(key == K_BACKSPACE && myString.GetCount() > 0)
|
||||
myString.Trim(myString.GetCount() - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If the current layout is a SimpleLayout, update its font.
|
||||
if(l)
|
||||
l->SetFont(&fonts[currentFont]);
|
||||
|
||||
Refresh();
|
||||
Sync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FTGLCtrl::SetUpLighting()
|
||||
{
|
||||
// Set up lighting.
|
||||
float light1_ambient[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
float light1_diffuse[4] = { 1.0, 0.9, 0.9, 1.0 };
|
||||
float light1_specular[4] = { 1.0, 0.7, 0.7, 1.0 };
|
||||
float light1_position[4] = { -1.0, 1.0, 1.0, 0.0 };
|
||||
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
|
||||
glEnable(GL_LIGHT1);
|
||||
|
||||
float light2_ambient[4] = { 0.2, 0.2, 0.2, 1.0 };
|
||||
float light2_diffuse[4] = { 0.9, 0.9, 0.9, 1.0 };
|
||||
float light2_specular[4] = { 0.7, 0.7, 0.7, 1.0 };
|
||||
float light2_position[4] = { 1.0, -1.0, -1.0, 0.0 };
|
||||
glLightfv(GL_LIGHT2, GL_AMBIENT, light2_ambient);
|
||||
glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse);
|
||||
glLightfv(GL_LIGHT2, GL_SPECULAR, light2_specular);
|
||||
glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
|
||||
//glEnable(GL_LIGHT2);
|
||||
|
||||
float front_emission[4] = { 0.3, 0.2, 0.1, 0.0 };
|
||||
float front_ambient[4] = { 0.2, 0.2, 0.2, 0.0 };
|
||||
float front_diffuse[4] = { 0.95, 0.95, 0.8, 0.0 };
|
||||
float front_specular[4] = { 0.6, 0.6, 0.6, 0.0 };
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, front_emission);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, front_diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, front_specular);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, 16.0);
|
||||
glColor4fv(front_diffuse);
|
||||
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glColorMaterial(GL_FRONT, GL_DIFFUSE);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
}
|
||||
|
||||
|
||||
void FTGLCtrl::SetFontFiles(Vector<String> const &files)
|
||||
{
|
||||
// copy font file names, it's needed later...
|
||||
fontFiles <<= files;
|
||||
|
||||
// The total number of fonts is styles * faces
|
||||
totalFonts = files.GetCount() * NumStyles;
|
||||
|
||||
// Instantiate and configure named fonts
|
||||
for(int i = 0; i < files.GetCount(); i++)
|
||||
{
|
||||
fonts.Add(new FTBitmapFont(files[i]));
|
||||
fonts.Add(new FTPixmapFont(files[i]));
|
||||
fonts.Add(new FTOutlineFont(files[i]));
|
||||
fonts.Add(new FTPolygonFont(files[i]));
|
||||
fonts.Add(new FTExtrudeFont(files[i]));
|
||||
fonts.Add(new FTTextureFont(files[i]));
|
||||
|
||||
for(int x = 0; x < NumStyles; ++x)
|
||||
{
|
||||
int j = i * NumStyles + x;
|
||||
if(fonts[j].Error())
|
||||
{
|
||||
Exclamation(Format("Failed to open font %s", fontFiles[i]));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!fonts[j].FaceSize(24))
|
||||
{
|
||||
Exclamation("Failed to set size");
|
||||
exit(1);
|
||||
}
|
||||
fonts[j].Depth(20);
|
||||
fonts[j].CharMap(ft_encoding_unicode);
|
||||
}
|
||||
}
|
||||
|
||||
infoFont = new FTPixmapFont(files[0]);
|
||||
if(infoFont->Error())
|
||||
{
|
||||
Exclamation(Format("Failed to open font %s\n", files[0]));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
infoFont->FaceSize(18);
|
||||
}
|
||||
|
||||
|
||||
void FTGLCtrl::RenderFontmetrics()
|
||||
{
|
||||
FTBBox bbox;
|
||||
float x1, y1, z1, x2, y2, z2;
|
||||
|
||||
// If there is a layout, use it to compute the bbox, otherwise query as
|
||||
// a string.
|
||||
if(hasLayout())
|
||||
bbox = layouts[currentLayout].BBox(myString);
|
||||
else
|
||||
bbox = fonts[currentFont].BBox(myString);
|
||||
|
||||
x1 = bbox.Lower().Xf(); y1 = bbox.Lower().Yf(); z1 = bbox.Lower().Zf();
|
||||
x2 = bbox.Upper().Xf(); y2 = bbox.Upper().Yf(); z2 = bbox.Upper().Zf();
|
||||
|
||||
// Draw the bounding box
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // GL_ONE_MINUS_SRC_ALPHA
|
||||
|
||||
glColor3f(0.0, 1.0, 0.0);
|
||||
// Draw the front face
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(x1, y1, z1);
|
||||
glVertex3f(x1, y2, z1);
|
||||
glVertex3f(x2, y2, z1);
|
||||
glVertex3f(x2, y1, z1);
|
||||
glEnd();
|
||||
// Draw the back face
|
||||
if((GetStyle() == FTGL_EXTRUDE) && (z1 != z2))
|
||||
{
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(x1, y1, z2);
|
||||
glVertex3f(x1, y2, z2);
|
||||
glVertex3f(x2, y2, z2);
|
||||
glVertex3f(x2, y1, z2);
|
||||
glEnd();
|
||||
// Join the faces
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(x1, y1, z1);
|
||||
glVertex3f(x1, y1, z2);
|
||||
|
||||
glVertex3f(x1, y2, z1);
|
||||
glVertex3f(x1, y2, z2);
|
||||
|
||||
glVertex3f(x2, y2, z1);
|
||||
glVertex3f(x2, y2, z2);
|
||||
|
||||
glVertex3f(x2, y1, z1);
|
||||
glVertex3f(x2, y1, z2);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Render layout-specific metrics
|
||||
if(!hasLayout())
|
||||
{
|
||||
// There is no layout. Draw the baseline, Ascender and Descender
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(0.0, 0.0, 1.0);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(fonts[currentFont].Advance(myString), 0.0, 0.0);
|
||||
glVertex3f(0.0, fonts[currentFont].Ascender(), 0.0);
|
||||
glVertex3f(0.0, fonts[currentFont].Descender(), 0.0);
|
||||
glEnd();
|
||||
}
|
||||
else if (dynamic_cast <FTSimpleLayout *>(&layouts[currentLayout]))
|
||||
{
|
||||
float lineWidth = ((FTSimpleLayout const &)layouts[currentLayout]).GetLineLength();
|
||||
|
||||
// The layout is a SimpleLayout. Render guides that mark the edges
|
||||
// of the wrap region.
|
||||
glColor3f(0.5, 1.0, 1.0);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(0, 10000, 0);
|
||||
glVertex3f(0, -10000, 0);
|
||||
glVertex3f(lineWidth, 10000, 0);
|
||||
glVertex3f(lineWidth, -10000, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Draw the origin
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
glPointSize(5.0);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void FTGLCtrl::RenderFontInfo()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, GetSize().cx, 0, GetSize().cy);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// draw mode
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glRasterPos2f(20.0f , GetSize().cy - (20.0f + infoFont->Ascender()));
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case EDITING:
|
||||
infoFont->Render("Edit Mode");
|
||||
break;
|
||||
|
||||
case INTERACTIVE:
|
||||
break;
|
||||
}
|
||||
|
||||
// draw font type
|
||||
glRasterPos2i(20 , 20);
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
infoFont->Render("Bitmap Font");
|
||||
break;
|
||||
|
||||
case FTGL_PIXMAP:
|
||||
infoFont->Render("Pixmap Font");
|
||||
break;
|
||||
|
||||
case FTGL_OUTLINE:
|
||||
infoFont->Render("Outline Font");
|
||||
break;
|
||||
|
||||
case FTGL_POLYGON:
|
||||
infoFont->Render("Polygon Font");
|
||||
break;
|
||||
|
||||
case FTGL_EXTRUDE:
|
||||
infoFont->Render("Extruded Font");
|
||||
break;
|
||||
|
||||
case FTGL_TEXTURE:
|
||||
infoFont->Render("Texture Font");
|
||||
break;
|
||||
}
|
||||
|
||||
glRasterPos2f(20.0f , 20.0f + infoFont->Ascender() - infoFont->Descender());
|
||||
infoFont->Render(fontFiles[GetFace()]);
|
||||
|
||||
// If the current layout is a SimpleLayout, output the alignemnt mode
|
||||
if(hasLayout() && (dynamic_cast <FTSimpleLayout *>(&layouts[currentLayout])))
|
||||
{
|
||||
glRasterPos2f(20.0f , 20.0f + 2*(infoFont->Ascender() - infoFont->Descender()));
|
||||
|
||||
// Output the alignment mode of the layout
|
||||
switch (((FTSimpleLayout const &)layouts[currentLayout]).GetAlignment())
|
||||
{
|
||||
case FTGL::ALIGN_LEFT:
|
||||
infoFont->Render("Align Left");
|
||||
break;
|
||||
|
||||
case FTGL::ALIGN_RIGHT:
|
||||
infoFont->Render("Align Right");
|
||||
break;
|
||||
|
||||
case FTGL::ALIGN_CENTER:
|
||||
infoFont->Render("Align Center");
|
||||
break;
|
||||
|
||||
case FTGL::ALIGN_JUSTIFY:
|
||||
infoFont->Render("Align Justified");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FTGLCtrl::Paint0(void)
|
||||
{
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
case FTGL_PIXMAP:
|
||||
case FTGL_OUTLINE:
|
||||
break;
|
||||
|
||||
case FTGL_POLYGON:
|
||||
glDisable(GL_BLEND);
|
||||
SetUpLighting();
|
||||
break;
|
||||
|
||||
case FTGL_EXTRUDE:
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
SetUpLighting();
|
||||
break;
|
||||
|
||||
case FTGL_TEXTURE:
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
SetUpLighting();
|
||||
glNormal3f(0.0, 0.0, 1.0);
|
||||
break;
|
||||
}
|
||||
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
// If you do want to switch the color of bitmaps rendered with glBitmap,
|
||||
// you will need to explicitly call glRasterPos (or its ilk) to lock
|
||||
// in a changed current color.
|
||||
|
||||
// If there is an active layout use it to render the font
|
||||
if (hasLayout())
|
||||
layouts[currentLayout].Render(myString);
|
||||
else
|
||||
fonts[currentFont].Render(myString);
|
||||
RenderFontmetrics();
|
||||
RenderFontInfo();
|
||||
}
|
||||
|
||||
void FTGLCtrl::SetCamera(void)
|
||||
{
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
case FTGL_PIXMAP:
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, GetSize().cx, 0, GetSize().cy);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
break;
|
||||
|
||||
case FTGL_OUTLINE:
|
||||
case FTGL_POLYGON:
|
||||
case FTGL_EXTRUDE:
|
||||
case FTGL_TEXTURE:
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
gluPerspective(90, (float)GetSize().cx / (float)GetSize().cy, 1, 1000);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(0.0, 0.0, (float)GetSize().cy / 2.0f, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FTGLCtrl::Layout()
|
||||
{
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glViewport (0, 0, GetSize().cx, GetSize().cy);
|
||||
glLoadIdentity();
|
||||
SetCamera();
|
||||
trackBall.Reshape(GetSize().cx, GetSize().cy);
|
||||
GLCtrl::Layout();
|
||||
}
|
||||
|
||||
void FTGLCtrl::GLPaint()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
SetCamera();
|
||||
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
case FTGL_PIXMAP:
|
||||
glRasterPos2i((long)(GetSize().cx / 2 + OX), (long)(GetSize().cy / 2 + OY));
|
||||
glTranslatef(GetSize().cx / 2 + OX, GetSize().cy / 2 + OY, 0.0);
|
||||
break;
|
||||
|
||||
case FTGL_OUTLINE:
|
||||
case FTGL_POLYGON:
|
||||
case FTGL_EXTRUDE:
|
||||
case FTGL_TEXTURE:
|
||||
glTranslatef(OX, OY, 0);
|
||||
trackBall.Matrix();
|
||||
break;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
Paint0();
|
||||
glPopMatrix();
|
||||
}
|
||||
70
bazaar/FTGL_Demo/FTGLCtrl.h
Normal file
70
bazaar/FTGL_Demo/FTGLCtrl.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#ifndef _FTGL_Demo_FTGLCtrl_h_
|
||||
#define _FTGL_Demo_FTGLCtrl_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
#include <GLCtrl/GLCtrl.h>
|
||||
|
||||
#include <FTGL/ftgl.h>
|
||||
|
||||
#include "TrackBall.h"
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
class FTGLCtrl : public GLCtrl
|
||||
{
|
||||
private:
|
||||
|
||||
TrackBall trackBall;
|
||||
|
||||
typedef enum { FTGL_BITMAP, FTGL_PIXMAP, FTGL_OUTLINE, FTGL_POLYGON, FTGL_EXTRUDE, FTGL_TEXTURE, NumStyles } Styles;
|
||||
typedef enum { EDITING = 1, INTERACTIVE } Modes;
|
||||
|
||||
Modes mode;
|
||||
|
||||
Vector<String> fontFiles;
|
||||
int currentFont;
|
||||
|
||||
// array containing all fonts
|
||||
Array<FTFont> fonts;
|
||||
int totalFonts;
|
||||
One<FTPixmapFont> infoFont;
|
||||
|
||||
Array<FTLayout> layouts;
|
||||
int currentLayout;
|
||||
bool hasLayout(void) { return currentLayout >= 0 && currentLayout < layouts.GetCount(); }
|
||||
|
||||
// displayed string
|
||||
String myString;
|
||||
|
||||
void SetUpLighting();
|
||||
void SetUpFonts(int numFontFiles);
|
||||
void RenderFontmetrics();
|
||||
void RenderFontInfo();
|
||||
void SetCamera();
|
||||
void Paint0(void);
|
||||
|
||||
int GetStyle() { return currentFont % NumStyles; }
|
||||
int GetFace() { return currentFont / NumStyles; }
|
||||
|
||||
float OX;
|
||||
float OY;
|
||||
|
||||
float initialLineLength;
|
||||
|
||||
protected:
|
||||
virtual void GLPaint();
|
||||
|
||||
virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags) { return trackBall.MouseEvent(event, p, zdelta, keyflags); }
|
||||
virtual bool Key(dword key, int count);
|
||||
|
||||
virtual void Layout();
|
||||
|
||||
public:
|
||||
typedef FTGLCtrl CLASSNAME;
|
||||
|
||||
void SetFontFiles(Vector<String> const &files);
|
||||
|
||||
FTGLCtrl();
|
||||
};
|
||||
|
||||
#endif
|
||||
14
bazaar/FTGL_Demo/FTGLDemo.cpp
Normal file
14
bazaar/FTGL_Demo/FTGLDemo.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "FTGLDemo.h"
|
||||
|
||||
FTGLDemo::FTGLDemo()
|
||||
{
|
||||
Add(ftglCtrl.SizePos());
|
||||
}
|
||||
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
FTGLDemo ftglDemo;
|
||||
ftglDemo.Sizeable().Zoomable().MinimizeBox();
|
||||
ftglDemo.Run();
|
||||
}
|
||||
18
bazaar/FTGL_Demo/FTGLDemo.h
Normal file
18
bazaar/FTGL_Demo/FTGLDemo.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef _FTGL_Demo_FTGLDemo_h_
|
||||
#define _FTGL_Demo_FTGLDemo_h_
|
||||
|
||||
#include "FTGLCtrl.h"
|
||||
|
||||
class FTGLDemo : public TopWindow
|
||||
{
|
||||
typedef FTGLDemo CLASSNAME;
|
||||
|
||||
private:
|
||||
FTGLCtrl ftglCtrl;
|
||||
|
||||
public:
|
||||
FTGLDemo();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
693
bazaar/FTGL_Demo/FTGLMFontDemo.cpp
Normal file
693
bazaar/FTGL_Demo/FTGLMFontDemo.cpp
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
/*
|
||||
* FTGLDemo - advanced demo for FTGL, the OpenGL font library
|
||||
*
|
||||
* Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined HAVE_GL_GLUT_H
|
||||
# include <GL/glut.h>
|
||||
#elif defined HAVE_GLUT_GLUT_H
|
||||
# include <GLUT/glut.h>
|
||||
#else
|
||||
# error GLUT headers not present
|
||||
#endif
|
||||
|
||||
#include <FTGL/ftgl.h>
|
||||
|
||||
#include "tb.h"
|
||||
|
||||
// YOU'LL PROBABLY WANT TO CHANGE THESE
|
||||
#if defined FONT_FILE
|
||||
char const *defaultFonts[] = { FONT_FILE };
|
||||
const int NumDefaultFonts = 1;
|
||||
#elif defined __APPLE_CC__
|
||||
char const *defaultFonts[] = { "/System/Library/Fonts/Helvetica.dfont",
|
||||
"/System/Library/Fonts/Geneva.dfont" };
|
||||
const int NumDefaultFonts = 2;
|
||||
#elif defined WIN32
|
||||
char const *defaultFonts[] = { "C:\\WINNT\\Fonts\\arial.ttf" };
|
||||
const int NumDefaultFonts = 1;
|
||||
#else
|
||||
// Put your font files here if configure did not find any.
|
||||
char const *defaultFonts[] = { };
|
||||
const int NumDefaultFonts = 0;
|
||||
#endif
|
||||
|
||||
/* Set this to 1 to build a Mac os app (ignore the command line args). */
|
||||
#ifndef IGNORE_ARGV
|
||||
# define IGNORE_ARGV 0
|
||||
#endif /* IGNORE_ARGV */
|
||||
|
||||
#define EDITING 1
|
||||
#define INTERACTIVE 2
|
||||
|
||||
#define FTGL_BITMAP 0
|
||||
#define FTGL_PIXMAP 1
|
||||
#define FTGL_OUTLINE 2
|
||||
#define FTGL_POLYGON 3
|
||||
#define FTGL_EXTRUDE 4
|
||||
#define FTGL_TEXTURE 5
|
||||
const int NumStyles = 6;
|
||||
|
||||
char const * const *fontfiles;
|
||||
int current_font = FTGL_EXTRUDE;
|
||||
|
||||
GLint w_win = 640, h_win = 480;
|
||||
int mode = INTERACTIVE;
|
||||
int carat = 0;
|
||||
|
||||
FTSimpleLayout simpleLayout;
|
||||
FTLayout *layouts[] = { &simpleLayout, NULL };
|
||||
int currentLayout = 0;
|
||||
const int NumLayouts = 2;
|
||||
|
||||
const float InitialLineLength = 300.0f;
|
||||
|
||||
const float OX = -100;
|
||||
const float OY = 200;
|
||||
|
||||
//wchar_t myString[16] = { 0x6FB3, 0x9580};
|
||||
char myString[4096];
|
||||
|
||||
int totalFonts;
|
||||
static FTFont** fonts;
|
||||
static FTPixmapFont* infoFont;
|
||||
|
||||
void SetCamera(void);
|
||||
|
||||
inline int GetStyle()
|
||||
{
|
||||
return current_font % NumStyles;
|
||||
}
|
||||
|
||||
inline int GetFace()
|
||||
{
|
||||
return current_font / NumStyles;
|
||||
}
|
||||
|
||||
void setUpLighting()
|
||||
{
|
||||
// Set up lighting.
|
||||
float light1_ambient[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
float light1_diffuse[4] = { 1.0, 0.9, 0.9, 1.0 };
|
||||
float light1_specular[4] = { 1.0, 0.7, 0.7, 1.0 };
|
||||
float light1_position[4] = { -1.0, 1.0, 1.0, 0.0 };
|
||||
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
|
||||
glEnable(GL_LIGHT1);
|
||||
|
||||
float light2_ambient[4] = { 0.2, 0.2, 0.2, 1.0 };
|
||||
float light2_diffuse[4] = { 0.9, 0.9, 0.9, 1.0 };
|
||||
float light2_specular[4] = { 0.7, 0.7, 0.7, 1.0 };
|
||||
float light2_position[4] = { 1.0, -1.0, -1.0, 0.0 };
|
||||
glLightfv(GL_LIGHT2, GL_AMBIENT, light2_ambient);
|
||||
glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse);
|
||||
glLightfv(GL_LIGHT2, GL_SPECULAR, light2_specular);
|
||||
glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
|
||||
//glEnable(GL_LIGHT2);
|
||||
|
||||
float front_emission[4] = { 0.3, 0.2, 0.1, 0.0 };
|
||||
float front_ambient[4] = { 0.2, 0.2, 0.2, 0.0 };
|
||||
float front_diffuse[4] = { 0.95, 0.95, 0.8, 0.0 };
|
||||
float front_specular[4] = { 0.6, 0.6, 0.6, 0.0 };
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, front_emission);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, front_diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, front_specular);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, 16.0);
|
||||
glColor4fv(front_diffuse);
|
||||
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glColorMaterial(GL_FRONT, GL_DIFFUSE);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
}
|
||||
|
||||
|
||||
void setUpFonts(int numFontFiles)
|
||||
{
|
||||
// The total number of fonts is styles * faces
|
||||
totalFonts = numFontFiles*NumStyles;
|
||||
|
||||
// Allocate an array to hold all fonts
|
||||
fonts = new FTFont *[totalFonts];
|
||||
|
||||
// Instantiate and configure named fonts
|
||||
for(int i = 0; i < numFontFiles; i++)
|
||||
{
|
||||
fonts[i*NumStyles + FTGL_BITMAP] = new FTBitmapFont(fontfiles[i]);
|
||||
fonts[i*NumStyles + FTGL_PIXMAP] = new FTPixmapFont(fontfiles[i]);
|
||||
fonts[i*NumStyles + FTGL_OUTLINE] = new FTOutlineFont(fontfiles[i]);
|
||||
fonts[i*NumStyles + FTGL_POLYGON] = new FTPolygonFont(fontfiles[i]);
|
||||
fonts[i*NumStyles + FTGL_EXTRUDE] = new FTExtrudeFont(fontfiles[i]);
|
||||
fonts[i*NumStyles + FTGL_TEXTURE] = new FTTextureFont(fontfiles[i]);
|
||||
|
||||
for(int x = 0; x < NumStyles; ++x)
|
||||
{
|
||||
int j = i * NumStyles + x;
|
||||
|
||||
if(fonts[j]->Error())
|
||||
{
|
||||
fprintf(stderr, "Failed to open font %s\n", fontfiles[i]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!fonts[j]->FaceSize(24))
|
||||
{
|
||||
fprintf(stderr, "Failed to set size\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fonts[j]->Depth(20);
|
||||
fonts[j]->CharMap(ft_encoding_unicode);
|
||||
}
|
||||
}
|
||||
|
||||
infoFont = new FTPixmapFont(fontfiles[0]);
|
||||
|
||||
if(infoFont->Error())
|
||||
{
|
||||
fprintf(stderr, "Failed to open font %s\n", fontfiles[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
infoFont->FaceSize(18);
|
||||
|
||||
strcpy(myString, "OpenGL is a powerful software interface for graphics "
|
||||
"hardware that allows graphics programmers to produce high-quality "
|
||||
"color images of 3D objects. abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL"
|
||||
"MNOPQRSTUVWXYZ0123456789");
|
||||
}
|
||||
|
||||
|
||||
void renderFontmetrics()
|
||||
{
|
||||
FTBBox bbox;
|
||||
float x1, y1, z1, x2, y2, z2;
|
||||
|
||||
// If there is a layout, use it to compute the bbox, otherwise query as
|
||||
// a string.
|
||||
if(layouts[currentLayout])
|
||||
bbox = layouts[currentLayout]->BBox(myString);
|
||||
else
|
||||
bbox = fonts[current_font]->BBox(myString);
|
||||
|
||||
x1 = bbox.Lower().Xf(); y1 = bbox.Lower().Yf(); z1 = bbox.Lower().Zf();
|
||||
x2 = bbox.Upper().Xf(); y2 = bbox.Upper().Yf(); z2 = bbox.Upper().Zf();
|
||||
|
||||
// Draw the bounding box
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // GL_ONE_MINUS_SRC_ALPHA
|
||||
|
||||
glColor3f(0.0, 1.0, 0.0);
|
||||
// Draw the front face
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(x1, y1, z1);
|
||||
glVertex3f(x1, y2, z1);
|
||||
glVertex3f(x2, y2, z1);
|
||||
glVertex3f(x2, y1, z1);
|
||||
glEnd();
|
||||
// Draw the back face
|
||||
if((GetStyle() == FTGL_EXTRUDE) && (z1 != z2))
|
||||
{
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(x1, y1, z2);
|
||||
glVertex3f(x1, y2, z2);
|
||||
glVertex3f(x2, y2, z2);
|
||||
glVertex3f(x2, y1, z2);
|
||||
glEnd();
|
||||
// Join the faces
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(x1, y1, z1);
|
||||
glVertex3f(x1, y1, z2);
|
||||
|
||||
glVertex3f(x1, y2, z1);
|
||||
glVertex3f(x1, y2, z2);
|
||||
|
||||
glVertex3f(x2, y2, z1);
|
||||
glVertex3f(x2, y2, z2);
|
||||
|
||||
glVertex3f(x2, y1, z1);
|
||||
glVertex3f(x2, y1, z2);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Render layout-specific metrics
|
||||
if(!layouts[currentLayout])
|
||||
{
|
||||
// There is no layout. Draw the baseline, Ascender and Descender
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(0.0, 0.0, 1.0);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(fonts[current_font]->Advance(myString), 0.0, 0.0);
|
||||
glVertex3f(0.0, fonts[current_font]->Ascender(), 0.0);
|
||||
glVertex3f(0.0, fonts[current_font]->Descender(), 0.0);
|
||||
glEnd();
|
||||
}
|
||||
else if (layouts[currentLayout]
|
||||
&& (dynamic_cast <FTSimpleLayout *>(layouts[currentLayout])))
|
||||
{
|
||||
float lineWidth = ((FTSimpleLayout *)layouts[currentLayout])->GetLineLength();
|
||||
|
||||
// The layout is a SimpleLayout. Render guides that mark the edges
|
||||
// of the wrap region.
|
||||
glColor3f(0.5, 1.0, 1.0);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(0, 10000, 0);
|
||||
glVertex3f(0, -10000, 0);
|
||||
glVertex3f(lineWidth, 10000, 0);
|
||||
glVertex3f(lineWidth, -10000, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Draw the origin
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
glPointSize(5.0);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
void renderFontInfo()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, w_win, 0, h_win);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// draw mode
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glRasterPos2f(20.0f , h_win - (20.0f + infoFont->Ascender()));
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case EDITING:
|
||||
infoFont->Render("Edit Mode");
|
||||
break;
|
||||
case INTERACTIVE:
|
||||
break;
|
||||
}
|
||||
|
||||
// draw font type
|
||||
glRasterPos2i(20 , 20);
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
infoFont->Render("Bitmap Font");
|
||||
break;
|
||||
case FTGL_PIXMAP:
|
||||
infoFont->Render("Pixmap Font");
|
||||
break;
|
||||
case FTGL_OUTLINE:
|
||||
infoFont->Render("Outline Font");
|
||||
break;
|
||||
case FTGL_POLYGON:
|
||||
infoFont->Render("Polygon Font");
|
||||
break;
|
||||
case FTGL_EXTRUDE:
|
||||
infoFont->Render("Extruded Font");
|
||||
break;
|
||||
case FTGL_TEXTURE:
|
||||
infoFont->Render("Texture Font");
|
||||
break;
|
||||
}
|
||||
|
||||
glRasterPos2f(20.0f , 20.0f + infoFont->Ascender() - infoFont->Descender());
|
||||
infoFont->Render(fontfiles[GetFace()]);
|
||||
|
||||
// If the current layout is a SimpleLayout, output the alignemnt mode
|
||||
if(layouts[currentLayout]
|
||||
&& (dynamic_cast <FTSimpleLayout *>(layouts[currentLayout])))
|
||||
{
|
||||
glRasterPos2f(20.0f , 20.0f + 2*(infoFont->Ascender() - infoFont->Descender()));
|
||||
// Output the alignment mode of the layout
|
||||
switch (((FTSimpleLayout *)layouts[currentLayout])->GetAlignment())
|
||||
{
|
||||
case FTGL::ALIGN_LEFT:
|
||||
infoFont->Render("Align Left");
|
||||
break;
|
||||
case FTGL::ALIGN_RIGHT:
|
||||
infoFont->Render("Align Right");
|
||||
break;
|
||||
case FTGL::ALIGN_CENTER:
|
||||
infoFont->Render("Align Center");
|
||||
break;
|
||||
case FTGL::ALIGN_JUSTIFY:
|
||||
infoFont->Render("Align Justified");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void do_display (void)
|
||||
{
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
case FTGL_PIXMAP:
|
||||
case FTGL_OUTLINE:
|
||||
break;
|
||||
case FTGL_POLYGON:
|
||||
glDisable(GL_BLEND);
|
||||
setUpLighting();
|
||||
break;
|
||||
case FTGL_EXTRUDE:
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
setUpLighting();
|
||||
break;
|
||||
case FTGL_TEXTURE:
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
setUpLighting();
|
||||
glNormal3f(0.0, 0.0, 1.0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
// If you do want to switch the color of bitmaps rendered with glBitmap,
|
||||
// you will need to explicitly call glRasterPos (or its ilk) to lock
|
||||
// in a changed current color.
|
||||
|
||||
// If there is an active layout use it to render the font
|
||||
if (layouts[currentLayout])
|
||||
{
|
||||
layouts[currentLayout]->Render(myString);
|
||||
}
|
||||
else
|
||||
{
|
||||
fonts[current_font]->Render(myString);
|
||||
}
|
||||
|
||||
renderFontmetrics();
|
||||
renderFontInfo();
|
||||
}
|
||||
|
||||
|
||||
void display(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
SetCamera();
|
||||
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
case FTGL_PIXMAP:
|
||||
glRasterPos2i((long)(w_win / 2 + OX), (long)(h_win / 2 + OY));
|
||||
glTranslatef(w_win / 2 + OX, h_win / 2 + OY, 0.0);
|
||||
break;
|
||||
case FTGL_OUTLINE:
|
||||
case FTGL_POLYGON:
|
||||
case FTGL_EXTRUDE:
|
||||
case FTGL_TEXTURE:
|
||||
glTranslatef(OX, OY, 0);
|
||||
tbMatrix();
|
||||
break;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
do_display();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
void myinit(int numFontFiles)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.13, 0.17, 0.32, 0.0);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
glPolygonOffset(1.0, 1.0); // ????
|
||||
|
||||
SetCamera();
|
||||
|
||||
tbInit(GLUT_LEFT_BUTTON);
|
||||
tbAnimate(GL_FALSE);
|
||||
|
||||
setUpFonts(numFontFiles);
|
||||
|
||||
// Configure the SimpleLayout
|
||||
simpleLayout.SetLineLength(InitialLineLength);
|
||||
simpleLayout.SetFont(fonts[current_font]);
|
||||
}
|
||||
|
||||
|
||||
void parsekey(unsigned char key, int x, int y)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
case 13:
|
||||
if(mode == EDITING)
|
||||
{
|
||||
mode = INTERACTIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = EDITING;
|
||||
carat = 0;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
// If current layout is a SimpleLayout, change its alignment properties
|
||||
if(layouts[currentLayout]
|
||||
&& (dynamic_cast <FTSimpleLayout *>(layouts[currentLayout])))
|
||||
{
|
||||
FTSimpleLayout *l = (FTSimpleLayout *)layouts[currentLayout];
|
||||
// Decrement the layout
|
||||
switch (l->GetAlignment())
|
||||
{
|
||||
case FTGL::ALIGN_LEFT:
|
||||
l->SetAlignment(FTGL::ALIGN_RIGHT);
|
||||
break;
|
||||
case FTGL::ALIGN_RIGHT:
|
||||
l->SetAlignment(FTGL::ALIGN_CENTER);
|
||||
break;
|
||||
case FTGL::ALIGN_CENTER:
|
||||
l->SetAlignment(FTGL::ALIGN_JUSTIFY);
|
||||
break;
|
||||
case FTGL::ALIGN_JUSTIFY:
|
||||
l->SetAlignment(FTGL::ALIGN_LEFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(mode == INTERACTIVE)
|
||||
{
|
||||
myString[0] = key;
|
||||
myString[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
myString[carat] = key;
|
||||
myString[carat + 1] = 0;
|
||||
carat = carat > 2000 ? 2000 : carat + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
void parseSpecialKey(int key, int x, int y)
|
||||
{
|
||||
FTSimpleLayout *l = NULL;
|
||||
|
||||
// If the currentLayout is a SimpleLayout store a pointer in l
|
||||
if(layouts[currentLayout]
|
||||
&& (dynamic_cast <FTSimpleLayout *>(layouts[currentLayout])))
|
||||
{
|
||||
l = (FTSimpleLayout *)layouts[currentLayout];
|
||||
}
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case GLUT_KEY_UP:
|
||||
current_font = (GetFace()*NumStyles + (current_font + 1)%NumStyles)%totalFonts;
|
||||
break;
|
||||
case GLUT_KEY_DOWN:
|
||||
current_font = (GetFace()*NumStyles + (current_font + NumStyles - 1)%NumStyles)%totalFonts;
|
||||
break;
|
||||
case GLUT_KEY_LEFT:
|
||||
fonts[current_font]->FaceSize(fonts[current_font]->FaceSize() - 1);
|
||||
break;
|
||||
case GLUT_KEY_RIGHT:
|
||||
fonts[current_font]->FaceSize(fonts[current_font]->FaceSize() + 1);
|
||||
break;
|
||||
case GLUT_KEY_PAGE_UP:
|
||||
current_font = (current_font + NumStyles)%totalFonts;
|
||||
break;
|
||||
case GLUT_KEY_PAGE_DOWN:
|
||||
current_font = (current_font + totalFonts - NumStyles)%totalFonts;
|
||||
break;
|
||||
case GLUT_KEY_HOME:
|
||||
currentLayout = (currentLayout + 1)%NumLayouts;
|
||||
break;
|
||||
case GLUT_KEY_END:
|
||||
currentLayout = (currentLayout + NumLayouts - 1)%NumLayouts;
|
||||
break;
|
||||
case GLUT_KEY_F1:
|
||||
case GLUT_KEY_F10:
|
||||
// If the current layout is simple decrement its line length
|
||||
if (l) l->SetLineLength(l->GetLineLength() - 10.0f);
|
||||
break;
|
||||
case GLUT_KEY_F2:
|
||||
case GLUT_KEY_F11:
|
||||
// If the current layout is simple increment its line length
|
||||
if (l) l->SetLineLength(l->GetLineLength() + 10.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the current layout is a SimpleLayout, update its font.
|
||||
if(l)
|
||||
{
|
||||
l->SetFont(fonts[current_font]);
|
||||
}
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
void motion(int x, int y)
|
||||
{
|
||||
tbMotion(x, y);
|
||||
}
|
||||
|
||||
void mouse(int button, int state, int x, int y)
|
||||
{
|
||||
tbMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void myReshape(int w, int h)
|
||||
{
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glViewport (0, 0, w, h);
|
||||
glLoadIdentity();
|
||||
|
||||
w_win = w;
|
||||
h_win = h;
|
||||
SetCamera();
|
||||
|
||||
tbReshape(w_win, h_win);
|
||||
}
|
||||
|
||||
void SetCamera(void)
|
||||
{
|
||||
switch(GetStyle())
|
||||
{
|
||||
case FTGL_BITMAP:
|
||||
case FTGL_PIXMAP:
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, w_win, 0, h_win);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
break;
|
||||
case FTGL_OUTLINE:
|
||||
case FTGL_POLYGON:
|
||||
case FTGL_EXTRUDE:
|
||||
case FTGL_TEXTURE:
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
gluPerspective(90, (float)w_win / (float)h_win, 1, 1000);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(0.0, 0.0, (float)h_win / 2.0f, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int numFontFiles;
|
||||
|
||||
if((argc >= 2) && !IGNORE_ARGV)
|
||||
{
|
||||
fontfiles = (char const * const *)argv + 1;
|
||||
numFontFiles = argc - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fontfiles = defaultFonts;
|
||||
numFontFiles = NumDefaultFonts;
|
||||
}
|
||||
|
||||
if(!fontfiles[0])
|
||||
{
|
||||
fprintf(stderr, "At least one font file must be specified on the command line\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE);
|
||||
glutInitWindowPosition(50, 50);
|
||||
glutInitWindowSize(w_win, h_win);
|
||||
glutCreateWindow("FTGL TEST");
|
||||
glutDisplayFunc(display);
|
||||
glutKeyboardFunc(parsekey);
|
||||
glutSpecialFunc(parseSpecialKey);
|
||||
glutMouseFunc(mouse);
|
||||
glutMotionFunc(motion);
|
||||
glutReshapeFunc(myReshape);
|
||||
glutIdleFunc(display);
|
||||
|
||||
myinit(numFontFiles);
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
18
bazaar/FTGL_Demo/FTGL_Demo.upp
Normal file
18
bazaar/FTGL_Demo/FTGL_Demo.upp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
uses
|
||||
FTGL,
|
||||
CtrlLib,
|
||||
GLCtrl;
|
||||
|
||||
file
|
||||
trackball.c,
|
||||
trackball.h,
|
||||
TrackBall.h,
|
||||
TrackBall.cpp,
|
||||
FTGLCtrl.h,
|
||||
FTGLCtrl.cpp,
|
||||
FTGLDemo.h,
|
||||
FTGLDemo.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
98
bazaar/FTGL_Demo/TrackBall.cpp
Normal file
98
bazaar/FTGL_Demo/TrackBall.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#include "TrackBall.h"
|
||||
|
||||
#include "trackball.h"
|
||||
#include <GL/glut.h>
|
||||
|
||||
void TrackBall::_Animate(void)
|
||||
{
|
||||
add_quats(lastquat, curquat, curquat);
|
||||
owner->Refresh();
|
||||
owner->Sync();
|
||||
if(enableAnimCb)
|
||||
owner->SetTimeCallback(10, THISBACK(_Animate));
|
||||
}
|
||||
|
||||
void TrackBall::_StartMotion(int x, int y, Time time)
|
||||
{
|
||||
enableAnimCb = false;
|
||||
tracking = true;
|
||||
lastTime = time;
|
||||
beginx = x;
|
||||
beginy = y;
|
||||
}
|
||||
|
||||
void TrackBall::_StopMotion(Time time)
|
||||
{
|
||||
tracking = false;
|
||||
|
||||
if (time == lastTime && animate)
|
||||
{
|
||||
enableAnimCb = true;
|
||||
_Animate();
|
||||
}
|
||||
else
|
||||
if (animate)
|
||||
enableAnimCb = false;
|
||||
}
|
||||
|
||||
void TrackBall::Animate(bool a)
|
||||
{
|
||||
animate = a;
|
||||
}
|
||||
|
||||
void TrackBall::Matrix(void)
|
||||
{
|
||||
GLfloat m[4][4];
|
||||
|
||||
build_rotmatrix(m, curquat);
|
||||
glMultMatrixf(&m[0][0]);
|
||||
}
|
||||
|
||||
void TrackBall::Reshape(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
// mouse event handler
|
||||
Image TrackBall::MouseEvent(int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
// mouse up/down starts and stop motion
|
||||
if ((event & Ctrl::BUTTON) == button && (event & Ctrl::ACTION) == Ctrl::DOWN)
|
||||
_StartMotion(p.x, p.y, GetSysTime());
|
||||
else
|
||||
if ((event & Ctrl::BUTTON) == button && (event & Ctrl::ACTION) == Ctrl::UP)
|
||||
_StopMotion(GetSysTime());
|
||||
|
||||
// mouse move do the animation, if we're tracking
|
||||
else if((event & Ctrl::ACTION) == Ctrl::MOUSEMOVE)
|
||||
{
|
||||
if (tracking)
|
||||
{
|
||||
trackball(
|
||||
lastquat,
|
||||
(2.0 * beginx - width) / width,
|
||||
(height - 2.0 * beginy) / height,
|
||||
(2.0 * p.x - width) / width,
|
||||
(height - 2.0 * p.y) / height
|
||||
);
|
||||
beginx = p.x;
|
||||
beginy = p.y;
|
||||
animate = true;
|
||||
lastTime = GetSysTime();
|
||||
_Animate();
|
||||
}
|
||||
}
|
||||
|
||||
return Image();
|
||||
}
|
||||
|
||||
TrackBall::TrackBall(Ctrl *ow)
|
||||
{
|
||||
owner = ow;
|
||||
button = Ctrl::LEFT;
|
||||
tracking = false;
|
||||
animate = false;
|
||||
trackball(curquat, 0.0, 0.0, 0.0, 0.0);
|
||||
enableAnimCb = false;
|
||||
}
|
||||
50
bazaar/FTGL_Demo/TrackBall.h
Normal file
50
bazaar/FTGL_Demo/TrackBall.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef _FTGL_Demo_TrackBall_h_
|
||||
#define _FTGL_Demo_TrackBall_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
class TrackBall
|
||||
{
|
||||
private:
|
||||
|
||||
Ctrl *owner;
|
||||
|
||||
Time lastTime;
|
||||
|
||||
float curquat[4];
|
||||
float lastquat[4];
|
||||
int beginx, beginy;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
int button;
|
||||
bool tracking;
|
||||
bool animate;
|
||||
|
||||
void _Animate(void);
|
||||
void _StartMotion(int x, int y, Time time);
|
||||
void _StopMotion(Time time);
|
||||
|
||||
bool enableAnimCb;
|
||||
|
||||
protected:
|
||||
|
||||
public:
|
||||
|
||||
typedef TrackBall CLASSNAME;
|
||||
|
||||
void Matrix(void);
|
||||
void Reshape(int width, int height);
|
||||
void Animate(bool animate);
|
||||
|
||||
void SetButton(int but = Ctrl::LEFT) { button = but; }
|
||||
|
||||
virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags);
|
||||
|
||||
TrackBall(Ctrl *owner);
|
||||
};
|
||||
|
||||
#endif
|
||||
6
bazaar/FTGL_Demo/init
Normal file
6
bazaar/FTGL_Demo/init
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _FTGL_Demo_icpp_init_stub
|
||||
#define _FTGL_Demo_icpp_init_stub
|
||||
#include "FTGL/init"
|
||||
#include "CtrlLib/init"
|
||||
#include "GLCtrl/init"
|
||||
#endif
|
||||
131
bazaar/FTGL_Demo/tb.c
Normal file
131
bazaar/FTGL_Demo/tb.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Simple trackball-like motion adapted (ripped off) from projtex.c
|
||||
* (written by David Yu and David Blythe). See the SIGGRAPH '96
|
||||
* Advanced OpenGL course notes.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined HAVE_GL_GLUT_H
|
||||
# include <GL/glut.h>
|
||||
#elif defined HAVE_GLUT_GLUT_H
|
||||
# include <GLUT/glut.h>
|
||||
#else
|
||||
# error GLUT headers not present
|
||||
#endif
|
||||
|
||||
#include "tb.h"
|
||||
#include "trackball.h"
|
||||
|
||||
/* globals */
|
||||
static GLuint tb_lasttime;
|
||||
|
||||
float curquat[4];
|
||||
float lastquat[4];
|
||||
int beginx, beginy;
|
||||
|
||||
static GLuint tb_width;
|
||||
static GLuint tb_height;
|
||||
|
||||
static GLint tb_button = -1;
|
||||
static GLboolean tb_tracking = GL_FALSE;
|
||||
static GLboolean tb_animate = GL_TRUE;
|
||||
|
||||
static void
|
||||
_tbAnimate(void)
|
||||
{
|
||||
add_quats(lastquat, curquat, curquat);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void
|
||||
_tbStartMotion(int x, int y, int time)
|
||||
{
|
||||
assert(tb_button != -1);
|
||||
|
||||
glutIdleFunc(0);
|
||||
tb_tracking = GL_TRUE;
|
||||
tb_lasttime = time;
|
||||
beginx = x;
|
||||
beginy = y;
|
||||
}
|
||||
|
||||
static void
|
||||
_tbStopMotion(unsigned time)
|
||||
{
|
||||
assert(tb_button != -1);
|
||||
|
||||
tb_tracking = GL_FALSE;
|
||||
|
||||
if (time == tb_lasttime && tb_animate) {
|
||||
glutIdleFunc(_tbAnimate);
|
||||
} else {
|
||||
if (tb_animate) {
|
||||
glutIdleFunc(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tbAnimate(GLboolean animate)
|
||||
{
|
||||
tb_animate = animate;
|
||||
}
|
||||
|
||||
void
|
||||
tbInit(GLuint button)
|
||||
{
|
||||
tb_button = button;
|
||||
trackball(curquat, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
void
|
||||
tbMatrix(void)
|
||||
{
|
||||
GLfloat m[4][4];
|
||||
|
||||
assert(tb_button != -1);
|
||||
build_rotmatrix(m, curquat);
|
||||
glMultMatrixf(&m[0][0]);
|
||||
}
|
||||
|
||||
void
|
||||
tbReshape(int width, int height)
|
||||
{
|
||||
assert(tb_button != -1);
|
||||
|
||||
tb_width = width;
|
||||
tb_height = height;
|
||||
}
|
||||
|
||||
void
|
||||
tbMouse(int button, int state, int x, int y)
|
||||
{
|
||||
assert(tb_button != -1);
|
||||
|
||||
if (state == GLUT_DOWN && button == tb_button)
|
||||
_tbStartMotion(x, y, glutGet(GLUT_ELAPSED_TIME));
|
||||
else if (state == GLUT_UP && button == tb_button)
|
||||
_tbStopMotion(glutGet(GLUT_ELAPSED_TIME));
|
||||
}
|
||||
|
||||
void
|
||||
tbMotion(int x, int y)
|
||||
{
|
||||
if (tb_tracking) {
|
||||
trackball(lastquat,
|
||||
(2.0 * beginx - tb_width) / tb_width,
|
||||
(tb_height - 2.0 * beginy) / tb_height,
|
||||
(2.0 * x - tb_width) / tb_width,
|
||||
(tb_height - 2.0 * y) / tb_height
|
||||
);
|
||||
beginx = x;
|
||||
beginy = y;
|
||||
tb_animate = 1;
|
||||
tb_lasttime = glutGet(GLUT_ELAPSED_TIME);
|
||||
_tbAnimate();
|
||||
}
|
||||
}
|
||||
103
bazaar/FTGL_Demo/tb.h
Normal file
103
bazaar/FTGL_Demo/tb.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Simple trackball-like motion adapted (ripped off) from projtex.c
|
||||
* (written by David Yu and David Blythe). See the SIGGRAPH '96
|
||||
* Advanced OpenGL course notes.
|
||||
*
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* o call tbInit() in before any other tb call
|
||||
* o call tbReshape() from the reshape callback
|
||||
* o call tbMatrix() to get the trackball matrix rotation
|
||||
* o call tbStartMotion() to begin trackball movememt
|
||||
* o call tbStopMotion() to stop trackball movememt
|
||||
* o call tbMotion() from the motion callback
|
||||
* o call tbAnimate(GL_TRUE) if you want the trackball to continue
|
||||
* spinning after the mouse button has been released
|
||||
* o call tbAnimate(GL_FALSE) if you want the trackball to stop
|
||||
* spinning after the mouse button has been released
|
||||
*
|
||||
* Typical setup:
|
||||
*
|
||||
*
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
tbInit(GLUT_MIDDLE_BUTTON);
|
||||
tbAnimate(GL_TRUE);
|
||||
. . .
|
||||
}
|
||||
|
||||
void
|
||||
reshape(int width, int height)
|
||||
{
|
||||
tbReshape(width, height);
|
||||
. . .
|
||||
}
|
||||
|
||||
void
|
||||
display(void)
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
tbMatrix();
|
||||
. . . draw the scene . . .
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void
|
||||
mouse(int button, int state, int x, int y)
|
||||
{
|
||||
tbMouse(button, state, x, y);
|
||||
. . .
|
||||
}
|
||||
|
||||
void
|
||||
motion(int x, int y)
|
||||
{
|
||||
tbMotion(x, y);
|
||||
. . .
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
. . .
|
||||
init();
|
||||
glutReshapeFunc(reshape);
|
||||
glutDisplayFunc(display);
|
||||
glutMouseFunc(mouse);
|
||||
glutMotionFunc(motion);
|
||||
. . .
|
||||
}
|
||||
*
|
||||
* */
|
||||
|
||||
|
||||
/* functions */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
tbInit(GLuint button);
|
||||
|
||||
void
|
||||
tbMatrix(void);
|
||||
|
||||
void
|
||||
tbReshape(int width, int height);
|
||||
|
||||
void
|
||||
tbMouse(int button, int state, int x, int y);
|
||||
|
||||
void
|
||||
tbMotion(int x, int y);
|
||||
|
||||
void
|
||||
tbAnimate(GLboolean animate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
326
bazaar/FTGL_Demo/trackball.c
Normal file
326
bazaar/FTGL_Demo/trackball.c
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
|
||||
* ALL RIGHTS RESERVED
|
||||
* Permission to use, copy, modify, and distribute this software for
|
||||
* any purpose and without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies and that both the copyright notice
|
||||
* and this permission notice appear in supporting documentation, and that
|
||||
* the name of Silicon Graphics, Inc. not be used in advertising
|
||||
* or publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission.
|
||||
*
|
||||
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
|
||||
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
|
||||
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
|
||||
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
|
||||
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
|
||||
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
|
||||
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* US Government Users Restricted Rights
|
||||
* Use, duplication, or disclosure by the Government is subject to
|
||||
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
|
||||
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
|
||||
* clause at DFARS 252.227-7013 and/or in similar or successor
|
||||
* clauses in the FAR or the DOD or NASA FAR Supplement.
|
||||
* Unpublished-- rights reserved under the copyright laws of the
|
||||
* United States. Contractor/manufacturer is Silicon Graphics,
|
||||
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
|
||||
*
|
||||
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Trackball code:
|
||||
*
|
||||
* Implementation of a virtual trackball.
|
||||
* Implemented by Gavin Bell, lots of ideas from Thant Tessman and
|
||||
* the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
|
||||
*
|
||||
* Vector manip code:
|
||||
*
|
||||
* Original code from:
|
||||
* David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
|
||||
*
|
||||
* Much mucking with by:
|
||||
* Gavin Bell
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "trackball.h"
|
||||
|
||||
/*
|
||||
* This size should really be based on the distance from the center of
|
||||
* rotation to the point on the object underneath the mouse. That
|
||||
* point would then track the mouse as closely as possible. This is a
|
||||
* simple example, though, so that is left as an Exercise for the
|
||||
* Programmer.
|
||||
*/
|
||||
#define TRACKBALLSIZE (0.4f)
|
||||
|
||||
/*
|
||||
* Local function prototypes (not defined in trackball.h)
|
||||
*/
|
||||
static float tb_project_to_sphere(float, float, float);
|
||||
static void normalize_quat(float [4]);
|
||||
|
||||
static void
|
||||
vzero(float *v)
|
||||
{
|
||||
v[0] = 0.0;
|
||||
v[1] = 0.0;
|
||||
v[2] = 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
vset(float *v, float x, float y, float z)
|
||||
{
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
}
|
||||
|
||||
static void
|
||||
vsub(const float *src1, const float *src2, float *dst)
|
||||
{
|
||||
dst[0] = src1[0] - src2[0];
|
||||
dst[1] = src1[1] - src2[1];
|
||||
dst[2] = src1[2] - src2[2];
|
||||
}
|
||||
|
||||
static void
|
||||
vcopy(const float *v1, float *v2)
|
||||
{
|
||||
register int i;
|
||||
for (i = 0 ; i < 3 ; i++)
|
||||
v2[i] = v1[i];
|
||||
}
|
||||
|
||||
static void
|
||||
vcross(const float *v1, const float *v2, float *cross)
|
||||
{
|
||||
float temp[3];
|
||||
|
||||
temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
|
||||
temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
|
||||
temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
|
||||
vcopy(temp, cross);
|
||||
}
|
||||
|
||||
static float
|
||||
vlength(const float *v)
|
||||
{
|
||||
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
}
|
||||
|
||||
static void
|
||||
vscale(float *v, float div)
|
||||
{
|
||||
v[0] *= div;
|
||||
v[1] *= div;
|
||||
v[2] *= div;
|
||||
}
|
||||
|
||||
static void
|
||||
vnormal(float *v)
|
||||
{
|
||||
vscale(v,1.0f/vlength(v));
|
||||
}
|
||||
|
||||
static float
|
||||
vdot(const float *v1, const float *v2)
|
||||
{
|
||||
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||
}
|
||||
|
||||
static void
|
||||
vadd(const float *src1, const float *src2, float *dst)
|
||||
{
|
||||
dst[0] = src1[0] + src2[0];
|
||||
dst[1] = src1[1] + src2[1];
|
||||
dst[2] = src1[2] + src2[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, simulate a track-ball. Project the points onto the virtual
|
||||
* trackball, then figure out the axis of rotation, which is the cross
|
||||
* product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
|
||||
* Note: This is a deformed trackball-- is a trackball in the center,
|
||||
* but is deformed into a hyperbolic sheet of rotation away from the
|
||||
* center. This particular function was chosen after trying out
|
||||
* several variations.
|
||||
*
|
||||
* It is assumed that the arguments to this routine are in the range
|
||||
* (-1.0 ... 1.0)
|
||||
*/
|
||||
void
|
||||
trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
|
||||
{
|
||||
float a[3]; /* Axis of rotation */
|
||||
float phi; /* how much to rotate about axis */
|
||||
float p1[3], p2[3], d[3];
|
||||
float t;
|
||||
|
||||
if (p1x == p2x && p1y == p2y) {
|
||||
/* Zero rotation */
|
||||
vzero(q);
|
||||
q[3] = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, figure out z-coordinates for projection of P1 and P2 to
|
||||
* deformed sphere
|
||||
*/
|
||||
vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
|
||||
vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
|
||||
|
||||
/*
|
||||
* Now, we want the cross product of P1 and P2
|
||||
*/
|
||||
vcross(p2,p1,a);
|
||||
|
||||
/*
|
||||
* Figure out how much to rotate around that axis.
|
||||
*/
|
||||
vsub(p1,p2,d);
|
||||
t = vlength(d) / (2.0f*TRACKBALLSIZE);
|
||||
|
||||
/*
|
||||
* Avoid problems with out-of-control values...
|
||||
*/
|
||||
if (t > 1.0f) t = 1.0f;
|
||||
if (t < -1.0f) t = -1.0f;
|
||||
phi = 2.0f * asin(t);
|
||||
|
||||
axis_to_quat(a,phi,q);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an axis and angle, compute quaternion.
|
||||
*/
|
||||
void
|
||||
axis_to_quat(float a[3], float phi, float q[4])
|
||||
{
|
||||
vnormal(a);
|
||||
vcopy(a,q);
|
||||
vscale(q,sin(phi/2.0f));
|
||||
q[3] = cos(phi/2.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
|
||||
* if we are away from the center of the sphere.
|
||||
*/
|
||||
static float
|
||||
tb_project_to_sphere(float r, float x, float y)
|
||||
{
|
||||
float d, t, z;
|
||||
|
||||
d = sqrt(x*x + y*y);
|
||||
if (d < r * 0.70710678118654752440f) { /* Inside sphere */
|
||||
z = sqrt(r*r - d*d);
|
||||
} else { /* On hyperbola */
|
||||
t = r / 1.41421356237309504880f;
|
||||
z = t*t / d;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given two rotations, e1 and e2, expressed as quaternion rotations,
|
||||
* figure out the equivalent single rotation and stuff it into dest.
|
||||
*
|
||||
* This routine also normalizes the result every RENORMCOUNT times it is
|
||||
* called, to keep error from creeping in.
|
||||
*
|
||||
* NOTE: This routine is written so that q1 or q2 may be the same
|
||||
* as dest (or each other).
|
||||
*/
|
||||
|
||||
#define RENORMCOUNT 97
|
||||
|
||||
void
|
||||
add_quats(float q1[4], float q2[4], float dest[4])
|
||||
{
|
||||
static int count=0;
|
||||
float t1[4], t2[4], t3[4];
|
||||
float tf[4];
|
||||
|
||||
vcopy(q1,t1);
|
||||
vscale(t1,q2[3]);
|
||||
|
||||
vcopy(q2,t2);
|
||||
vscale(t2,q1[3]);
|
||||
|
||||
vcross(q2,q1,t3);
|
||||
vadd(t1,t2,tf);
|
||||
vadd(t3,tf,tf);
|
||||
tf[3] = q1[3] * q2[3] - vdot(q1,q2);
|
||||
|
||||
dest[0] = tf[0];
|
||||
dest[1] = tf[1];
|
||||
dest[2] = tf[2];
|
||||
dest[3] = tf[3];
|
||||
|
||||
if (++count > RENORMCOUNT) {
|
||||
count = 0;
|
||||
normalize_quat(dest);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
|
||||
* If they don't add up to 1.0, dividing by their magnitued will
|
||||
* renormalize them.
|
||||
*
|
||||
* Note: See the following for more information on quaternions:
|
||||
*
|
||||
* - Shoemake, K., Animating rotation with quaternion curves, Computer
|
||||
* Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
|
||||
* - Pletinckx, D., Quaternion calculus as a basic tool in computer
|
||||
* graphics, The Visual Computer 5, 2-13, 1989.
|
||||
*/
|
||||
static void
|
||||
normalize_quat(float q[4])
|
||||
{
|
||||
int i;
|
||||
float mag;
|
||||
|
||||
mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
|
||||
for (i = 0; i < 4; i++) q[i] /= mag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a rotation matrix, given a quaternion rotation.
|
||||
*
|
||||
*/
|
||||
void
|
||||
build_rotmatrix(float m[4][4], float q[4])
|
||||
{
|
||||
m[0][0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]);
|
||||
m[0][1] = 2.0f * (q[0] * q[1] - q[2] * q[3]);
|
||||
m[0][2] = 2.0f * (q[2] * q[0] + q[1] * q[3]);
|
||||
m[0][3] = 0.0f;
|
||||
|
||||
m[1][0] = 2.0f * (q[0] * q[1] + q[2] * q[3]);
|
||||
m[1][1]= 1.0f - 2.0f * (q[2] * q[2] + q[0] * q[0]);
|
||||
m[1][2] = 2.0f * (q[1] * q[2] - q[0] * q[3]);
|
||||
m[1][3] = 0.0f;
|
||||
|
||||
m[2][0] = 2.0f * (q[2] * q[0] - q[1] * q[3]);
|
||||
m[2][1] = 2.0f * (q[1] * q[2] + q[0] * q[3]);
|
||||
m[2][2] = 1.0f - 2.0f * (q[1] * q[1] + q[0] * q[0]);
|
||||
m[2][3] = 0.0f;
|
||||
|
||||
m[3][0] = 0.0f;
|
||||
m[3][1] = 0.0f;
|
||||
m[3][2] = 0.0f;
|
||||
m[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
85
bazaar/FTGL_Demo/trackball.h
Normal file
85
bazaar/FTGL_Demo/trackball.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
|
||||
* ALL RIGHTS RESERVED
|
||||
* Permission to use, copy, modify, and distribute this software for
|
||||
* any purpose and without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies and that both the copyright notice
|
||||
* and this permission notice appear in supporting documentation, and that
|
||||
* the name of Silicon Graphics, Inc. not be used in advertising
|
||||
* or publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission.
|
||||
*
|
||||
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
|
||||
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
|
||||
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
|
||||
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
|
||||
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
|
||||
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
|
||||
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* US Government Users Restricted Rights
|
||||
* Use, duplication, or disclosure by the Government is subject to
|
||||
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
|
||||
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
|
||||
* clause at DFARS 252.227-7013 and/or in similar or successor
|
||||
* clauses in the FAR or the DOD or NASA FAR Supplement.
|
||||
* Unpublished-- rights reserved under the copyright laws of the
|
||||
* United States. Contractor/manufacturer is Silicon Graphics,
|
||||
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
|
||||
*
|
||||
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
|
||||
*/
|
||||
/*
|
||||
* trackball.h
|
||||
* A virtual trackball implementation
|
||||
* Written by Gavin Bell for Silicon Graphics, November 1988.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pass the x and y coordinates of the last and current positions of
|
||||
* the mouse, scaled so they are from (-1.0 ... 1.0).
|
||||
*
|
||||
* The resulting rotation is returned as a quaternion rotation in the
|
||||
* first paramater.
|
||||
*/
|
||||
void
|
||||
trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
|
||||
|
||||
/*
|
||||
* Given two quaternions, add them together to get a third quaternion.
|
||||
* Adding quaternions to get a compound rotation is analagous to adding
|
||||
* translations to get a compound translation. When incrementally
|
||||
* adding rotations, the first argument here should be the new
|
||||
* rotation, the second and third the total rotation (which will be
|
||||
* over-written with the resulting new total rotation).
|
||||
*/
|
||||
void
|
||||
add_quats(float *q1, float *q2, float *dest);
|
||||
|
||||
/*
|
||||
* A useful function, builds a rotation matrix in Matrix based on
|
||||
* given quaternion.
|
||||
*/
|
||||
void
|
||||
build_rotmatrix(float m[4][4], float q[4]);
|
||||
|
||||
/*
|
||||
* This function computes a quaternion based on an axis (defined by
|
||||
* the given vector) and an angle about which to rotate. The angle is
|
||||
* expressed in radians. The result is put into the third argument.
|
||||
*/
|
||||
void
|
||||
axis_to_quat(float a[3], float phi, float q[4]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue