added GLTeapot sample app
we still need opengl headers and libGL.so git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13041 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f1496739a3
commit
c8c44fa029
@ -7,6 +7,7 @@ SubInclude OBOS_TOP src apps codycam ;
|
||||
SubInclude OBOS_TOP src apps deskbar ;
|
||||
SubInclude OBOS_TOP src apps diskprobe ;
|
||||
SubInclude OBOS_TOP src apps expander ;
|
||||
SubInclude OBOS_TOP src apps glteapot ;
|
||||
SubInclude OBOS_TOP src apps magnify ;
|
||||
#SubInclude OBOS_TOP src apps mediaplayer ;
|
||||
SubInclude OBOS_TOP src apps midiplayer ;
|
||||
|
135
src/apps/glteapot/FPS.cpp
Normal file
135
src/apps/glteapot/FPS.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
|
||||
#include "FPS.h"
|
||||
|
||||
|
||||
FPS::FPS()
|
||||
{
|
||||
}
|
||||
|
||||
FPS::~FPS()
|
||||
{
|
||||
}
|
||||
|
||||
void FPS::drawChar( GLfloat x, GLfloat y, GLint number )
|
||||
{
|
||||
static bool numbers[13][7] = {
|
||||
{true,true,true,true,true,true,false}, /* 0 */
|
||||
{false,true,true,false,false,false,false}, /* 1 */
|
||||
{true,true,false,true,true,false,true}, /* 2 */
|
||||
{true,true,true,true,false,false,true}, /* 3 */
|
||||
{false,true,true,false,false,true,true}, /* 4 */
|
||||
{true,false,true,true,false,true,true}, /* 5 */
|
||||
{true,false,true,true,true,true,true}, /* 6 */
|
||||
{true,true,true,false,false,false,false}, /* 7 */
|
||||
{true,true,true,true,true,true,true}, /* 8 */
|
||||
{true,true,true,false,false,true,true}, /* 9 */
|
||||
|
||||
{true,false,false,false,true,true,true}, /* F */
|
||||
{true,true,false,false,true,true,true}, /* P */
|
||||
{true,false,true,true,false,true,true}, /* S */
|
||||
|
||||
};
|
||||
|
||||
static GLfloat gap = 0.03;
|
||||
static GLfloat size = 1.0;
|
||||
|
||||
static GLfloat x0 = -size / 4;
|
||||
static GLfloat x1 = -size / 4 + gap;
|
||||
static GLfloat x2 = -x1;
|
||||
static GLfloat x3 = -x0;
|
||||
|
||||
static GLfloat y0 = size / 2;
|
||||
static GLfloat y1 = size / 2 - gap;
|
||||
static GLfloat y2 = 0 + gap;
|
||||
static GLfloat y3 = 0;
|
||||
static GLfloat y4 = -y2;
|
||||
static GLfloat y5 = -y1;
|
||||
static GLfloat y6 = -y0;
|
||||
|
||||
glBegin( GL_LINES );
|
||||
if( numbers[number][0] )
|
||||
{
|
||||
glVertex2f( x1 + x, y0 + y );
|
||||
glVertex2f( x2 + x, y0 + y );
|
||||
}
|
||||
if( numbers[number][1] )
|
||||
{
|
||||
glVertex2f( x3 + x, y1 + y );
|
||||
glVertex2f( x3 + x, y2 + y );
|
||||
}
|
||||
if( numbers[number][2] )
|
||||
{
|
||||
glVertex2f( x3 + x, y4 + y );
|
||||
glVertex2f( x3 + x, y5 + y );
|
||||
}
|
||||
if( numbers[number][3] )
|
||||
{
|
||||
glVertex2f( x1 + x, y6 + y );
|
||||
glVertex2f( x2 + x, y6 + y );
|
||||
}
|
||||
if( numbers[number][4] )
|
||||
{
|
||||
glVertex2f( x0 + x, y5 + y );
|
||||
glVertex2f( x0 + x, y4 + y );
|
||||
}
|
||||
if( numbers[number][5] )
|
||||
{
|
||||
glVertex2f( x0 + x, y2 + y );
|
||||
glVertex2f( x0 + x, y1 + y );
|
||||
}
|
||||
if( numbers[number][6] )
|
||||
{
|
||||
glVertex2f( x1 + x, y3 + y );
|
||||
glVertex2f( x2 + x, y3 + y );
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
void FPS::drawCounter( GLfloat frameRate )
|
||||
{
|
||||
GLfloat pos = 0;
|
||||
int ifps = (int) (frameRate * 10 +0.5);
|
||||
int c100,c10,c1,c_1;
|
||||
|
||||
c100 = ifps / 1000;
|
||||
c10 = (ifps / 100) % 10;
|
||||
c1 = (ifps / 10) % 10;
|
||||
c_1 = ifps % 10;
|
||||
|
||||
if( c100 )
|
||||
{
|
||||
drawChar( pos, 0, c100 );
|
||||
pos += 1;
|
||||
}
|
||||
if( c100 || c10 )
|
||||
{
|
||||
drawChar( pos, 0, c10 );
|
||||
pos += 1;
|
||||
}
|
||||
drawChar( pos, 0, c1 );
|
||||
pos += 0.5;
|
||||
|
||||
glBegin( GL_POINTS );
|
||||
glVertex2f( pos, -0.5 );
|
||||
glEnd();
|
||||
pos += 0.5;
|
||||
|
||||
drawChar( pos, 0, c_1 );
|
||||
pos += 1.5;
|
||||
|
||||
|
||||
drawChar( pos, 0, 10 );
|
||||
pos += 1;
|
||||
drawChar( pos, 0, 11 );
|
||||
pos += 1;
|
||||
drawChar( pos, 0, 12 );
|
||||
pos += 1;
|
||||
|
||||
}
|
||||
|
19
src/apps/glteapot/FPS.h
Normal file
19
src/apps/glteapot/FPS.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
class FPS
|
||||
{
|
||||
public:
|
||||
FPS();
|
||||
~FPS();
|
||||
|
||||
static void drawCounter( GLfloat frameRate );
|
||||
|
||||
private:
|
||||
static void drawChar( GLfloat x, GLfloat y, GLint number );
|
||||
|
||||
};
|
353
src/apps/glteapot/GLObject.cpp
Normal file
353
src/apps/glteapot/GLObject.cpp
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include <InterfaceKit.h>
|
||||
|
||||
#include "GLObject.h"
|
||||
#include "glob.h"
|
||||
|
||||
struct material {
|
||||
float ambient[3],diffuse[3],specular[3];
|
||||
};
|
||||
|
||||
float *colors[] =
|
||||
{
|
||||
NULL,white,yellow,blue,red,green
|
||||
};
|
||||
|
||||
material materials[] = {
|
||||
// Null
|
||||
{
|
||||
{0.1745, 0.03175, 0.03175},
|
||||
{0.61424, 0.10136, 0.10136},
|
||||
{0.727811, 0.626959, 0.626959}
|
||||
},
|
||||
// White
|
||||
{
|
||||
{0.1745, 0.1745, 0.1745},
|
||||
{0.61424, 0.61424, 0.61424},
|
||||
{0.727811, 0.727811, 0.727811}
|
||||
},
|
||||
// Yellow
|
||||
{
|
||||
{0.1745, 0.1745, 0.03175},
|
||||
{0.61424, 0.61424, 0.10136},
|
||||
{0.727811, 0.727811, 0.626959}
|
||||
},
|
||||
// Blue
|
||||
{
|
||||
{0.03175, 0.03175, 0.1745},
|
||||
{0.10136, 0.10136, 0.61424},
|
||||
{0.626959, 0.626959, 0.727811}
|
||||
},
|
||||
// Red
|
||||
{
|
||||
{0.1745, 0.03175, 0.03175},
|
||||
{0.61424, 0.10136, 0.10136},
|
||||
{0.727811, 0.626959, 0.626959}
|
||||
},
|
||||
// Green
|
||||
{
|
||||
{0.03175, 0.1745, 0.03175},
|
||||
{0.10136, 0.61424, 0.10136},
|
||||
{0.626959, 0.727811, 0.626959}
|
||||
},
|
||||
};
|
||||
|
||||
#define USE_QUAD_STRIPS 1
|
||||
|
||||
extern long setEvent(sem_id event);
|
||||
|
||||
GLObject::GLObject(ObjectView *ov)
|
||||
{
|
||||
rotX = rotY = lastRotX = lastRotY = 0;
|
||||
spinX = spinY = 2;
|
||||
x = y = 0;
|
||||
z = -2.0;
|
||||
color = 4;
|
||||
solidity = 0;
|
||||
changed = false;
|
||||
objView = ov;
|
||||
};
|
||||
|
||||
GLObject::~GLObject()
|
||||
{
|
||||
};
|
||||
|
||||
void GLObject::MenuInvoked(BPoint point)
|
||||
{
|
||||
BPopUpMenu *m = new BPopUpMenu("Object",false,false);
|
||||
BMenuItem *i;
|
||||
|
||||
int c = 1;
|
||||
m->AddItem(i = new BMenuItem("White",NULL));
|
||||
if (color == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Yellow",NULL));
|
||||
if (color == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Blue",NULL));
|
||||
if (color == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Red",NULL));
|
||||
if (color == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Green",NULL));
|
||||
if (color == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddSeparatorItem();
|
||||
|
||||
c = 0;
|
||||
m->AddItem(i = new BMenuItem("Solid",NULL));
|
||||
if (solidity == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Translucent",NULL));
|
||||
if (solidity == c++)
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Transparent",NULL));
|
||||
if (solidity == c++)
|
||||
i->SetMarked(true);
|
||||
|
||||
i = m->Go(point);
|
||||
int32 index = m->IndexOf(i);
|
||||
delete m;
|
||||
|
||||
if (index < 5) {
|
||||
color = index+1;
|
||||
} else if (index > 5) {
|
||||
solidity = index-6;
|
||||
};
|
||||
changed = true;
|
||||
setEvent(objView->drawEvent);
|
||||
};
|
||||
|
||||
bool GLObject::SpinIt()
|
||||
{
|
||||
rotX += spinX;
|
||||
rotY += spinY;
|
||||
bool c = changed;
|
||||
c = c || ((rotX != lastRotX) || (rotY != lastRotY));
|
||||
lastRotX = rotX;
|
||||
lastRotY = rotY;
|
||||
|
||||
return c;
|
||||
};
|
||||
|
||||
void GLObject::Draw(bool forID, float IDcolor[])
|
||||
{
|
||||
glPushMatrix();
|
||||
glTranslatef(x, y, z);
|
||||
glRotatef(rotY, 0.0,1.0,0.0);
|
||||
glRotatef(rotX, 1.0,0.0,0.0);
|
||||
|
||||
if (forID) {
|
||||
glColor3fv(IDcolor);
|
||||
};
|
||||
|
||||
DoDrawing(forID);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
changed = false;
|
||||
};
|
||||
|
||||
TriangleObject::TriangleObject(ObjectView *ov, char *filename)
|
||||
: GLObject(ov),
|
||||
points(100,100),
|
||||
triangles(100,100),
|
||||
qs(50,50)
|
||||
{
|
||||
float maxp=0;
|
||||
int numPt,numTri;
|
||||
|
||||
FILE *f = fopen(filename,"r");
|
||||
fscanf(f,"%d",&numPt);
|
||||
// printf("Points: %d\n",numPt);
|
||||
for (int i=0;i<numPt;i++) {
|
||||
point p;
|
||||
fscanf(f,"%f %f %f %f %f %f",
|
||||
&p.x,
|
||||
&p.y,
|
||||
&p.z,
|
||||
&p.nx,
|
||||
&p.ny,
|
||||
&p.nz);
|
||||
if (fabs(p.x) > maxp)
|
||||
maxp = fabs(p.x);
|
||||
if (fabs(p.y) > maxp)
|
||||
maxp = fabs(p.y);
|
||||
if (fabs(p.z) > maxp)
|
||||
maxp = fabs(p.z);
|
||||
points.add(p);
|
||||
};
|
||||
for (int i=0;i<points.num_items;i++) {
|
||||
points[i].x /= maxp;
|
||||
points[i].y /= maxp;
|
||||
points[i].z /= maxp;
|
||||
};
|
||||
|
||||
fscanf(f,"%d",&numTri);
|
||||
// printf("Triangles: %d\n",numTri);
|
||||
int tpts=0;
|
||||
for (int i=0;i<numTri;i++) {
|
||||
tri t;
|
||||
fscanf(f,"%d %d %d",
|
||||
&t.p1,
|
||||
&t.p2,
|
||||
&t.p3);
|
||||
triangles.add(t);
|
||||
tpts+=3;
|
||||
};
|
||||
|
||||
int qpts=4;
|
||||
int qp[1024];
|
||||
quadStrip q;
|
||||
q.pts = qp;
|
||||
q.numpts = 4;
|
||||
q.pts[2] = triangles[0].p1;
|
||||
q.pts[0] = triangles[0].p2;
|
||||
q.pts[1] = triangles[0].p3;
|
||||
q.pts[3] = triangles[1].p3;
|
||||
|
||||
for (int i=2;i<numTri;i+=2) {
|
||||
if ((triangles[i-1].p1 == triangles[i].p2) &&
|
||||
(triangles[i-1].p3 == triangles[i].p3)) {
|
||||
q.pts[q.numpts++] = triangles[i+1].p1;
|
||||
q.pts[q.numpts++] = triangles[i+1].p3;
|
||||
qpts+=2;
|
||||
} else {
|
||||
int *np = (int*)malloc(sizeof(int)*q.numpts);
|
||||
memcpy(np,qp,q.numpts*sizeof(int));
|
||||
quadStrip nqs;
|
||||
nqs.numpts = q.numpts;
|
||||
nqs.pts = np;
|
||||
qs.add(nqs);
|
||||
|
||||
qpts+=4;
|
||||
q.numpts = 4;
|
||||
q.pts[2] = triangles[i].p1;
|
||||
q.pts[0] = triangles[i].p2;
|
||||
q.pts[1] = triangles[i].p3;
|
||||
q.pts[3] = triangles[i+1].p3;
|
||||
};
|
||||
};
|
||||
|
||||
int *np = (int*)malloc(sizeof(int)*q.numpts);
|
||||
memcpy(np,qp,q.numpts*sizeof(int));
|
||||
quadStrip nqs;
|
||||
nqs.numpts = q.numpts;
|
||||
nqs.pts = np;
|
||||
qs.add(nqs);
|
||||
|
||||
fclose(f);
|
||||
};
|
||||
|
||||
TriangleObject::~TriangleObject()
|
||||
{
|
||||
for (int i=0;i<qs.num_items;i++) {
|
||||
free(qs[i].pts);
|
||||
};
|
||||
};
|
||||
|
||||
void TriangleObject::DoDrawing(bool forID)
|
||||
{
|
||||
if (!forID) {
|
||||
float c[3][4];
|
||||
c[0][0] = materials[color].ambient[0];
|
||||
c[0][1] = materials[color].ambient[1];
|
||||
c[0][2] = materials[color].ambient[2];
|
||||
c[1][0] = materials[color].diffuse[0];
|
||||
c[1][1] = materials[color].diffuse[1];
|
||||
c[1][2] = materials[color].diffuse[2];
|
||||
c[2][0] = materials[color].specular[0];
|
||||
c[2][1] = materials[color].specular[1];
|
||||
c[2][2] = materials[color].specular[2];
|
||||
|
||||
float alpha = 1;
|
||||
if (solidity == 0)
|
||||
alpha = 1.0;
|
||||
else if (solidity == 1)
|
||||
alpha = 0.95;
|
||||
else if (solidity == 2)
|
||||
alpha = 0.6;
|
||||
c[0][3] = c[1][3] = c[2][3] = alpha;
|
||||
if (solidity != 0) {
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
glEnable(GL_BLEND);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
};
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, c[0]);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, c[1]);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, c[2]);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
};
|
||||
|
||||
#if USE_QUAD_STRIPS
|
||||
for (int i=0;i<qs.num_items;i++) {
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (int j=0;j<qs[i].numpts;j++) {
|
||||
glNormal3f(
|
||||
points[qs[i].pts[j]].nx,
|
||||
points[qs[i].pts[j]].ny,
|
||||
points[qs[i].pts[j]].nz
|
||||
);
|
||||
glVertex3f(
|
||||
points[qs[i].pts[j]].x,
|
||||
points[qs[i].pts[j]].y,
|
||||
points[qs[i].pts[j]].z
|
||||
);
|
||||
};
|
||||
glEnd();
|
||||
};
|
||||
#else
|
||||
glBegin(GL_TRIANGLES);
|
||||
for (int i=0;i<triangles.num_items;i++) {
|
||||
int v3 = triangles[i].p1;
|
||||
int v1 = triangles[i].p2;
|
||||
int v2 = triangles[i].p3;
|
||||
glNormal3f(
|
||||
points[v1].nx,
|
||||
points[v1].ny,
|
||||
points[v1].nz
|
||||
);
|
||||
glVertex3f(
|
||||
points[v1].x,
|
||||
points[v1].y,
|
||||
points[v1].z
|
||||
);
|
||||
glNormal3f(
|
||||
points[v2].nx,
|
||||
points[v2].ny,
|
||||
points[v2].nz
|
||||
);
|
||||
glVertex3f(
|
||||
points[v2].x,
|
||||
points[v2].y,
|
||||
points[v2].z
|
||||
);
|
||||
glNormal3f(
|
||||
points[v3].nx,
|
||||
points[v3].ny,
|
||||
points[v3].nz
|
||||
);
|
||||
glVertex3f(
|
||||
points[v3].x,
|
||||
points[v3].y,
|
||||
points[v3].z
|
||||
);
|
||||
};
|
||||
glEnd();
|
||||
#endif
|
||||
};
|
||||
|
54
src/apps/glteapot/GLObject.h
Normal file
54
src/apps/glteapot/GLObject.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include "ObjectView.h"
|
||||
|
||||
struct point {
|
||||
float x,y,z;
|
||||
float nx,ny,nz;
|
||||
float tu,tv;
|
||||
};
|
||||
|
||||
struct tri {
|
||||
int p1,p2,p3;
|
||||
};
|
||||
|
||||
struct quadStrip {
|
||||
int numpts;
|
||||
int *pts;
|
||||
};
|
||||
|
||||
#include "util.h"
|
||||
|
||||
class GLObject {
|
||||
public:
|
||||
float rotX,rotY,spinX,spinY,lastRotX,lastRotY;
|
||||
float x,y,z;
|
||||
int color;
|
||||
int solidity;
|
||||
bool changed;
|
||||
ObjectView * objView;
|
||||
|
||||
GLObject(ObjectView *ov);
|
||||
virtual ~GLObject();
|
||||
|
||||
virtual void Draw(bool forID, float IDcolor[]);
|
||||
virtual bool SpinIt();
|
||||
virtual void MenuInvoked(BPoint point);
|
||||
|
||||
virtual void DoDrawing(bool forID) {};
|
||||
};
|
||||
|
||||
class TriangleObject : public GLObject {
|
||||
public:
|
||||
BufferArray<point> points;
|
||||
BufferArray<tri> triangles;
|
||||
BufferArray<quadStrip> qs;
|
||||
|
||||
TriangleObject(ObjectView *ov, char *filename);
|
||||
virtual ~TriangleObject();
|
||||
|
||||
virtual void DoDrawing(bool forID);
|
||||
};
|
67
src/apps/glteapot/GLTeapot.rdef
Normal file
67
src/apps/glteapot/GLTeapot.rdef
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
resource app_signature "application/x-vnd.Haiku-teapot";
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH;
|
||||
|
||||
resource app_version
|
||||
{
|
||||
short_info = "GLTeapot",
|
||||
long_info = "Haiku GLTeapot"
|
||||
};
|
||||
|
||||
|
||||
resource large_icon array
|
||||
{
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF002B5AEB00FFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFF002B5AEBEBEB00FF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFF00002B2A2B2B2A2B2F0000002B9CEBEB00EB00FF"
|
||||
$"FFFFFFFFFFFFFFFFFFFF00002B2A9C9C9C9C9C9C2B2BEB309CEBEB0000EB00FF"
|
||||
$"FFFFFFFFFFFFFFFFFF002F2B9C9C313131F131315ADA2BEB300000FF00EB00FF"
|
||||
$"FFFFFFFFFFFFFFFF002F2B9C313131F1313131F13131DA2B2F2F00FF00EB00FF"
|
||||
$"FFFFFFFFFFFFFF002F2B9C313131F1302F2F302F302FDA2BEB302F0000EB00FF"
|
||||
$"FFFFFFFFFFFFFF002F2B9C3131312F2F30EB2F2FEB30DA2B2EEB3000002E00FF"
|
||||
$"FFFFFFFFFFFF002F2B2A9C31312F2F2F2FEB2F2FEB30DA2BEBEB2F2F00EB00FF"
|
||||
$"FFFFFFFFFFFF00302A2B9C31312F2F2F2FEB302F30DA2B2E2E2EEB30002E00FF"
|
||||
$"FFFFFFFFFF002F2B2A2B2A5ADA302F302F2F9CDADA2C2C2D2DEBEB2F2F000F0F"
|
||||
$"FFFFFFFFFF002F2B2A2B2A2B2BDADADADADA5A2B2C2C2D2D2E2EEB2F2F000F0F"
|
||||
$"FFFFFFFFFF000000002B2A2B2B2A2B2B2B2C2B2B2B2C2C2E2DEBEB2F2F000E0F"
|
||||
$"FF000000002B2C2B2B00002A2B2B2B2B2B2B2C2C2C2C2D2D2E2EEB2F2F000EFF"
|
||||
$"002B305A5A5A5A5A5A2B2A002B2A2C2B3F2B2C2B2C2C2D2D2F2D2F2F2F000EFF"
|
||||
$"002B305A2B2C2E2C2B302F00302B2B2B2C2C2B2C2C2D2D2DEBEB2F2F2F000F0E"
|
||||
$"002B5A302F2F302F302F2F01302C2C2C2B2C2C2C2C2D2D2F2D2F302F2F000E0F"
|
||||
$"FF00000000000000000000302F2B2C2C2C2C2C2D2D2D2E2E2E2EEB30000F0F0F"
|
||||
$"FFFFFFFFFFFF00302F2F302F2F2D2C2D2C2D2D2C2D2D2D2E2FEB302F000E0F0F"
|
||||
$"FFFFFFFFFFFFFF00302F2F2D2C2D2D2D2D2D2D2D2DEB2FEBEB2F30000F0E0F0F"
|
||||
$"FFFFFFFFFFFFFF0030EB2FEB2D2D2D2D2E2D2DEBEBEB2F2FEB2F2F000E0F0FFF"
|
||||
$"FFFFFFFFFFFFFFFF00302FEBEB2F2D2F2D2F2D2E2E2FEB2F2F30000F0F0F0FFF"
|
||||
$"FFFFFFFFFFFFFFFFFF002F2F2F2FEB2F2FEBEB2F2E2F2F2F30000F0F0F0FFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFF0000302F2FEB302F2FEB302F3000000F0F0F0FFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFF0000302F2F302F2F3000000E0F0F0F0FFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000E0F0F0FFFFFFFFFFFFFFF"
|
||||
};
|
||||
|
||||
resource mini_icon array
|
||||
{
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF"
|
||||
$"FFFFFFFFFFFF000000000000002B2E00"
|
||||
$"FFFFFFFF00002B9C9C9C9C30002E2E00"
|
||||
$"FFFFFF00302A9C313131F15A30002E00"
|
||||
$"FFFFFF002B9C313131F1315A2F2F0000"
|
||||
$"FFFF00302A2B5A3131315A2D2E2F0000"
|
||||
$"FFFF0000002B2A5A5A5A2D2D2EEB000F"
|
||||
$"0000005A5A002B2B2B2B2D2D2E2F000F"
|
||||
$"00305A2B2C002F2B3F2C2D2D2F2F00FF"
|
||||
$"000000000000302C2D2C2E2D2F2F000E"
|
||||
$"FFFFFF00302F2D2E2D2D2D2F30000F0F"
|
||||
$"FFFFFFFF0030EB2F2FEB302F2F000E0F"
|
||||
$"FFFFFFFFFF0000302F2F3000000F0FFF"
|
||||
$"FFFFFFFFFFFFFF000000000E0F0FFFFF"
|
||||
};
|
15
src/apps/glteapot/Jamfile
Normal file
15
src/apps/glteapot/Jamfile
Normal file
@ -0,0 +1,15 @@
|
||||
SubDir OBOS_TOP src apps glteapot ;
|
||||
|
||||
#TODO we should have our own opengl headers
|
||||
SubDirHdrs [ FDirName / boot develop headers be opengl ] ;
|
||||
|
||||
#TODO we should have our own libGL.so
|
||||
App GLTeapot :
|
||||
FPS.cpp
|
||||
GLObject.cpp
|
||||
ObjectView.cpp
|
||||
error.cpp
|
||||
teapot_main.cpp
|
||||
: libbe.so GL libgame.so
|
||||
: GLTeapot.rdef
|
||||
;
|
31
src/apps/glteapot/LICENSE
Normal file
31
src/apps/glteapot/LICENSE
Normal file
@ -0,0 +1,31 @@
|
||||
----------------------
|
||||
Be Sample Code License
|
||||
----------------------
|
||||
|
||||
Copyright 1991-1999, Be Incorporated.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
692
src/apps/glteapot/ObjectView.cpp
Normal file
692
src/apps/glteapot/ObjectView.cpp
Normal file
@ -0,0 +1,692 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <InterfaceKit.h>
|
||||
#include <FindDirectory.h>
|
||||
|
||||
#include "ObjectView.h"
|
||||
#include "ResScroll.h"
|
||||
#include "GLObject.h"
|
||||
#include "FPS.h"
|
||||
|
||||
#define teapotData "teapot.data"
|
||||
char teapotPath[PATH_MAX];
|
||||
|
||||
float displayScale = 1.0;
|
||||
float depthOfView = 30.0;
|
||||
float zRatio = 10.0;
|
||||
|
||||
float white[3] = {1.0,1.0,1.0};
|
||||
float dimWhite[3] = {0.25,0.25,0.25};
|
||||
float black[3] = {0.0,0.0,0.0};
|
||||
float foggy[3] = {0.4,0.4,0.4};
|
||||
float blue[3] = {0.0,0.0,1.0};
|
||||
float dimBlue[3] = {0.0,0.0,0.5};
|
||||
float yellow[3] = {1.0,1.0,0.0};
|
||||
float dimYellow[3] = {0.5,0.5,0.0};
|
||||
float green[3] = {0.0,1.0,0.0};
|
||||
float dimGreen[3] = {0.0,0.5,0.0};
|
||||
float red[3] = {1.0,0.0,0.0};
|
||||
|
||||
float *bgColor = black;
|
||||
|
||||
struct light {
|
||||
float *ambient;
|
||||
float *diffuse;
|
||||
float *specular;
|
||||
};
|
||||
|
||||
light lights[] = {
|
||||
{NULL,NULL,NULL},
|
||||
{dimWhite,white,white},
|
||||
{dimWhite,yellow,yellow},
|
||||
{dimWhite,red,red},
|
||||
{dimWhite,blue,blue},
|
||||
{dimWhite,green,green}
|
||||
};
|
||||
|
||||
long signalEvent(sem_id event)
|
||||
{
|
||||
long c;
|
||||
get_sem_count(event,&c);
|
||||
if (c<0)
|
||||
release_sem_etc(event,-c,0);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
long setEvent(sem_id event)
|
||||
{
|
||||
long c;
|
||||
get_sem_count(event,&c);
|
||||
if (c<0)
|
||||
release_sem_etc(event,-c,0);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
long waitEvent(sem_id event)
|
||||
{
|
||||
acquire_sem(event);
|
||||
|
||||
long c;
|
||||
get_sem_count(event,&c);
|
||||
if (c>0)
|
||||
acquire_sem_etc(event,c,0,0);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
long simonThread(ObjectView *ov)
|
||||
{
|
||||
int noPause=0;
|
||||
while (acquire_sem_etc(ov->quittingSem,1,B_TIMEOUT,0) == B_NO_ERROR) {
|
||||
if (ov->SpinIt()) {
|
||||
ov->DrawFrame(noPause);
|
||||
release_sem(ov->quittingSem);
|
||||
noPause = 1;
|
||||
} else {
|
||||
release_sem(ov->quittingSem);
|
||||
noPause = 0;
|
||||
waitEvent(ov->drawEvent);
|
||||
};
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
ObjectView::ObjectView(BRect r, char *name, ulong resizingMode, ulong options)
|
||||
: BGLView(r,name,resizingMode,0,options)
|
||||
{
|
||||
histEntries = 0;
|
||||
oldestEntry = 0;
|
||||
lastGouraud = gouraud = true;
|
||||
lastZbuf = zbuf = true;
|
||||
lastCulling = culling = true;
|
||||
lastLighting = lighting = true;
|
||||
lastFilled = filled = true;
|
||||
lastPersp = persp = false;
|
||||
lastFog = fog = false;
|
||||
lastTextured = textured = false;
|
||||
lastObjectDistance = objectDistance = depthOfView/8;
|
||||
fps = true;
|
||||
forceRedraw = false;
|
||||
lastYXRatio = yxRatio = 1;
|
||||
|
||||
quittingSem = create_sem(1,"quitting sem");
|
||||
drawEvent = create_sem(0,"draw event");
|
||||
|
||||
char findDir[PATH_MAX];
|
||||
find_directory(B_BEOS_ETC_DIRECTORY,-1, TRUE,findDir,PATH_MAX);
|
||||
sprintf(teapotPath,"%s/%s",findDir,teapotData);
|
||||
objListLock.Lock();
|
||||
objects.AddItem(new TriangleObject(this,teapotPath));
|
||||
objListLock.Unlock();
|
||||
};
|
||||
|
||||
ObjectView::~ObjectView()
|
||||
{
|
||||
delete_sem(quittingSem);
|
||||
delete_sem(drawEvent);
|
||||
};
|
||||
|
||||
void ObjectView::AttachedToWindow()
|
||||
{
|
||||
float position[] = {0.0, 3.0, 3.0, 0.0};
|
||||
float position1[] = {-3.0, -3.0, 3.0, 0.0};
|
||||
float position2[] = {3.0, 0.0, 0.0, 0.0};
|
||||
float local_view[] = {0.0,0.0};
|
||||
// float ambient[] = {0.1745, 0.03175, 0.03175};
|
||||
// float diffuse[] = {0.61424, 0.10136, 0.10136};
|
||||
// float specular[] = {0.727811, 0.626959, 0.626959};
|
||||
// rgb_color black = {0,0,0,255};
|
||||
BRect r = Bounds();
|
||||
|
||||
BGLView::AttachedToWindow();
|
||||
Window()->SetPulseRate(100000);
|
||||
|
||||
LockGL();
|
||||
|
||||
glEnable(GL_DITHER);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, position);
|
||||
glLightfv(GL_LIGHT0+1, GL_POSITION, position1);
|
||||
glLightfv(GL_LIGHT0+2, GL_POSITION, position2);
|
||||
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
|
||||
|
||||
glEnable(GL_LIGHT0);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, lights[lightWhite].specular);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE,lights[lightWhite].diffuse);
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT,lights[lightWhite].ambient);
|
||||
glEnable(GL_LIGHT1);
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, lights[lightBlue].specular);
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE,lights[lightBlue].diffuse);
|
||||
glLightfv(GL_LIGHT1, GL_AMBIENT,lights[lightBlue].ambient);
|
||||
|
||||
glFrontFace(GL_CW);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_AUTO_NORMAL);
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, 0.6*128.0);
|
||||
|
||||
glClearColor(bgColor[0],bgColor[1],bgColor[2], 1.0);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
glViewport(0, 0, (GLint)r.IntegerWidth()+1, (GLint)r.IntegerHeight()+1);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float scale=displayScale;
|
||||
// glOrtho (0.0, 16.0, 0, 16.0*(GLfloat)300/(GLfloat)300,
|
||||
// -10.0, 10.0);
|
||||
glOrtho(-scale, scale, -scale, scale, -scale*depthOfView,
|
||||
scale*depthOfView);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
UnlockGL();
|
||||
|
||||
drawThread = spawn_thread((thread_entry)simonThread,
|
||||
"Simon",B_NORMAL_PRIORITY,(void*)this);
|
||||
resume_thread(drawThread);
|
||||
forceRedraw = true;
|
||||
setEvent(drawEvent);
|
||||
};
|
||||
|
||||
void ObjectView::DetachedFromWindow()
|
||||
{
|
||||
BGLView::DetachedFromWindow();
|
||||
|
||||
long dummy;
|
||||
long locks=0;
|
||||
|
||||
while (Window()->IsLocked()) {
|
||||
locks++;
|
||||
Window()->Unlock();
|
||||
};
|
||||
|
||||
acquire_sem(quittingSem);
|
||||
release_sem(drawEvent);
|
||||
wait_for_thread(drawThread,&dummy);
|
||||
release_sem(quittingSem);
|
||||
|
||||
while (locks--) Window()->Lock();
|
||||
};
|
||||
|
||||
void ObjectView::Pulse()
|
||||
{
|
||||
Window()->Lock();
|
||||
BRect p = Parent()->Bounds();
|
||||
BRect b = Bounds();
|
||||
p.OffsetTo(0,0);
|
||||
b.OffsetTo(0,0);
|
||||
if (b != p) {
|
||||
ResizeTo(p.right-p.left,p.bottom-p.top);
|
||||
};
|
||||
Window()->Unlock();
|
||||
};
|
||||
|
||||
void ObjectView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
BMenuItem *i;
|
||||
bool *b;
|
||||
|
||||
switch (msg->what) {
|
||||
case bmsgFPS:
|
||||
fps = (fps)?false:true;
|
||||
msg->FindPointer("source", (void **)&i);
|
||||
i->SetMarked(fps);
|
||||
forceRedraw = true;
|
||||
setEvent(drawEvent);
|
||||
break;
|
||||
case bmsgAddModel:
|
||||
objListLock.Lock();
|
||||
objects.AddItem(new TriangleObject(this,teapotPath));
|
||||
objListLock.Unlock();
|
||||
setEvent(drawEvent);
|
||||
break;
|
||||
case bmsgLights:
|
||||
{
|
||||
msg->FindPointer("source",(void **)&i);
|
||||
long lightNum = msg->FindInt32("num");
|
||||
long color = msg->FindInt32("color");
|
||||
BMenu *m = i->Menu();
|
||||
long index = m->IndexOf(i);
|
||||
m->ItemAt(index)->SetMarked(true);
|
||||
for (int i=0;i<m->CountItems();i++) {
|
||||
if (i != index)
|
||||
m->ItemAt(i)->SetMarked(false);
|
||||
};
|
||||
|
||||
LockGL();
|
||||
if (color != lightNone) {
|
||||
glEnable(GL_LIGHT0+lightNum-1);
|
||||
glLightfv(GL_LIGHT0+lightNum-1, GL_SPECULAR, lights[color].specular);
|
||||
glLightfv(GL_LIGHT0+lightNum-1, GL_DIFFUSE,lights[color].diffuse);
|
||||
glLightfv(GL_LIGHT0+lightNum-1, GL_AMBIENT,lights[color].ambient);
|
||||
} else {
|
||||
glDisable(GL_LIGHT0+lightNum-1);
|
||||
};
|
||||
UnlockGL();
|
||||
forceRedraw = true;
|
||||
setEvent(drawEvent);
|
||||
break;
|
||||
}
|
||||
case bmsgGouraud:
|
||||
b = &gouraud;
|
||||
goto stateChange;
|
||||
case bmsgZBuffer:
|
||||
b = &zbuf;
|
||||
goto stateChange;
|
||||
case bmsgCulling:
|
||||
b = &culling;
|
||||
goto stateChange;
|
||||
case bmsgLighting:
|
||||
b = &lighting;
|
||||
goto stateChange;
|
||||
case bmsgFilled:
|
||||
b = &filled;
|
||||
goto stateChange;
|
||||
case bmsgPerspective:
|
||||
b = &persp;
|
||||
goto stateChange;
|
||||
case bmsgFog:
|
||||
b = &fog;
|
||||
goto stateChange;
|
||||
stateChange:
|
||||
msg->FindPointer("source",(void **)&i);
|
||||
if (!i) return;
|
||||
|
||||
if (*b) {
|
||||
i->SetMarked(*b = false);
|
||||
} else {
|
||||
i->SetMarked(*b = true);
|
||||
};
|
||||
setEvent(drawEvent);
|
||||
break;
|
||||
default:
|
||||
BGLView::MessageReceived(msg);
|
||||
};
|
||||
};
|
||||
|
||||
int ObjectView::ObjectAtPoint(BPoint p)
|
||||
{
|
||||
LockGL();
|
||||
glShadeModel(GL_FLAT);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_FOG);
|
||||
glClearColor(black[0],black[1],black[2],1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT|(zbuf?GL_DEPTH_BUFFER_BIT:0));
|
||||
|
||||
float f[3];
|
||||
f[1] = f[2] = 0;
|
||||
for (int i=0;i<objects.CountItems();i++) {
|
||||
f[0] = (255-i)/255.0;
|
||||
((GLObject*)objects.ItemAt(i))->Draw(true, f);
|
||||
};
|
||||
glReadBuffer(GL_BACK);
|
||||
uchar pixel[256];
|
||||
glReadPixels((GLint)p.x,(GLint)(Bounds().bottom-p.y),1,1,GL_RGB,GL_UNSIGNED_BYTE,pixel);
|
||||
int objNum = pixel[0];
|
||||
objNum = 255-objNum;
|
||||
|
||||
EnforceState();
|
||||
UnlockGL();
|
||||
|
||||
return objNum;
|
||||
};
|
||||
|
||||
void ObjectView::MouseDown(BPoint p)
|
||||
{
|
||||
BPoint op=p,np=p;
|
||||
BRect bounds = Bounds();
|
||||
float lastDx=0,lastDy=0;
|
||||
GLObject *o = NULL;
|
||||
uint32 mods;
|
||||
|
||||
BMessage *m = Window()->CurrentMessage();
|
||||
uint32 buttons = m->FindInt32("buttons");
|
||||
o = ((GLObject*)objects.ItemAt(ObjectAtPoint(p)));
|
||||
|
||||
long locks=0;
|
||||
|
||||
while (Window()->IsLocked()) {
|
||||
locks++;
|
||||
Window()->Unlock();
|
||||
};
|
||||
|
||||
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||
if (o) {
|
||||
while (buttons) {
|
||||
lastDx = np.x-op.x;
|
||||
lastDy = np.y-op.y;
|
||||
if (lastDx || lastDy) {
|
||||
float xinc = (lastDx*2*displayScale/bounds.Width());
|
||||
float yinc = (-lastDy*2*displayScale/bounds.Height());
|
||||
float zinc = 0;
|
||||
if (persp) {
|
||||
zinc = yinc*(o->z/(displayScale));
|
||||
xinc *= -(o->z*4/zRatio);
|
||||
yinc *= -(o->z*4/zRatio);
|
||||
};
|
||||
o->x += xinc;
|
||||
mods = modifiers();
|
||||
if (mods & B_SHIFT_KEY)
|
||||
o->z += zinc;
|
||||
else
|
||||
o->y += yinc;
|
||||
op = np;
|
||||
forceRedraw = true;
|
||||
setEvent(drawEvent);
|
||||
};
|
||||
|
||||
snooze(25000);
|
||||
|
||||
Window()->Lock();
|
||||
GetMouse(&np, &buttons, true);
|
||||
Window()->Unlock();
|
||||
};
|
||||
};
|
||||
} else if (buttons == B_PRIMARY_MOUSE_BUTTON) {
|
||||
float llx=0,lly=0;
|
||||
lastDx = lastDy = 0;
|
||||
if (o) {
|
||||
o->spinX = 0;
|
||||
o->spinY = 0;
|
||||
while (buttons) {
|
||||
llx = lastDx;
|
||||
lly = lastDy;
|
||||
lastDx = np.x-op.x;
|
||||
lastDy = np.y-op.y;
|
||||
if (lastDx || lastDy) {
|
||||
o->rotY += lastDx;
|
||||
o->rotX += lastDy;
|
||||
op = np;
|
||||
setEvent(drawEvent);
|
||||
};
|
||||
|
||||
snooze(25000);
|
||||
|
||||
Window()->Lock();
|
||||
GetMouse(&np, &buttons, true);
|
||||
Window()->Unlock();
|
||||
};
|
||||
o->spinY = lastDx+llx;
|
||||
o->spinX = lastDy+lly;
|
||||
};
|
||||
} else {
|
||||
if (o) {
|
||||
BPoint point = p;
|
||||
Window()->Lock();
|
||||
ConvertToScreen(&point);
|
||||
Window()->Unlock();
|
||||
o->MenuInvoked(point);
|
||||
};
|
||||
};
|
||||
|
||||
while (locks--)
|
||||
Window()->Lock();
|
||||
|
||||
setEvent(drawEvent);
|
||||
};
|
||||
|
||||
void ObjectView::FrameResized(float w, float h)
|
||||
{
|
||||
LockGL();
|
||||
|
||||
BGLView::FrameResized(w,h);
|
||||
|
||||
BRect b = Bounds();
|
||||
w = b.Width();
|
||||
h = b.Height();
|
||||
yxRatio = h/w;
|
||||
glViewport(0, 0, (GLint)w+1, (GLint)h+1);
|
||||
|
||||
// To prevent weird buffer contents
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float scale=displayScale;
|
||||
if (persp) {
|
||||
gluPerspective(60,1.0/yxRatio,0.15,120);
|
||||
} else {
|
||||
if (yxRatio < 1) {
|
||||
glOrtho(-scale/yxRatio, scale/yxRatio, -scale, scale,
|
||||
-1.0, depthOfView*4);
|
||||
} else {
|
||||
glOrtho(-scale, scale, -scale*yxRatio, scale*yxRatio,
|
||||
-1.0, depthOfView*4);
|
||||
};
|
||||
};
|
||||
|
||||
lastYXRatio = yxRatio;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
UnlockGL();
|
||||
|
||||
forceRedraw = true;
|
||||
setEvent(drawEvent);
|
||||
}
|
||||
|
||||
bool ObjectView::RepositionView()
|
||||
{
|
||||
if (!(persp != lastPersp) &&
|
||||
!(lastObjectDistance != objectDistance) &&
|
||||
!(lastYXRatio != yxRatio)) {
|
||||
return false;
|
||||
};
|
||||
|
||||
LockGL();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float scale=displayScale;
|
||||
if (persp) {
|
||||
gluPerspective(60,1.0/yxRatio,0.15,120);
|
||||
} else {
|
||||
if (yxRatio < 1) {
|
||||
glOrtho(-scale/yxRatio, scale/yxRatio, -scale, scale,
|
||||
-1.0, depthOfView*4);
|
||||
} else {
|
||||
glOrtho(-scale, scale, -scale*yxRatio, scale*yxRatio,
|
||||
-1.0, depthOfView*4);
|
||||
};
|
||||
};
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
UnlockGL();
|
||||
|
||||
lastObjectDistance = objectDistance;
|
||||
lastPersp = persp;
|
||||
lastYXRatio = yxRatio;
|
||||
return true;
|
||||
};
|
||||
|
||||
void ObjectView::EnforceState()
|
||||
{
|
||||
glShadeModel(gouraud?GL_SMOOTH:GL_FLAT);
|
||||
if (zbuf) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||
if (culling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||
if (lighting) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);
|
||||
if (filled) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
} else {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
};
|
||||
if (fog) {
|
||||
glFogf(GL_FOG_START,10.0);
|
||||
glFogf(GL_FOG_DENSITY,0.2);
|
||||
glFogf(GL_FOG_END,depthOfView);
|
||||
glFogfv(GL_FOG_COLOR,foggy);
|
||||
glEnable(GL_FOG);
|
||||
bgColor = foggy;
|
||||
glClearColor(bgColor[0],bgColor[1],bgColor[2], 1.0);
|
||||
} else {
|
||||
glDisable(GL_FOG);
|
||||
bgColor = black;
|
||||
glClearColor(bgColor[0],bgColor[1],bgColor[2], 1.0);
|
||||
};
|
||||
};
|
||||
|
||||
bool ObjectView::SpinIt()
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (gouraud != lastGouraud) {
|
||||
LockGL();
|
||||
glShadeModel(gouraud?GL_SMOOTH:GL_FLAT);
|
||||
UnlockGL();
|
||||
lastGouraud = gouraud;
|
||||
changed = true;
|
||||
};
|
||||
if (zbuf != lastZbuf) {
|
||||
LockGL();
|
||||
if (zbuf) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||
UnlockGL();
|
||||
lastZbuf = zbuf;
|
||||
changed = true;
|
||||
};
|
||||
if (culling != lastCulling) {
|
||||
LockGL();
|
||||
if (culling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||
UnlockGL();
|
||||
lastCulling = culling;
|
||||
changed = true;
|
||||
};
|
||||
if (lighting != lastLighting) {
|
||||
LockGL();
|
||||
if (lighting) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);
|
||||
UnlockGL();
|
||||
lastLighting = lighting;
|
||||
changed = true;
|
||||
};
|
||||
if (filled != lastFilled) {
|
||||
LockGL();
|
||||
if (filled) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
} else {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
};
|
||||
UnlockGL();
|
||||
lastFilled = filled;
|
||||
changed = true;
|
||||
};
|
||||
if (fog != lastFog) {
|
||||
if (fog) {
|
||||
glFogf(GL_FOG_START,1.0);
|
||||
glFogf(GL_FOG_DENSITY,0.2);
|
||||
glFogf(GL_FOG_END,depthOfView);
|
||||
glFogfv(GL_FOG_COLOR,foggy);
|
||||
glEnable(GL_FOG);
|
||||
bgColor = foggy;
|
||||
glClearColor(bgColor[0],bgColor[1],bgColor[2], 1.0);
|
||||
} else {
|
||||
glDisable(GL_FOG);
|
||||
bgColor = black;
|
||||
glClearColor(bgColor[0],bgColor[1],bgColor[2], 1.0);
|
||||
};
|
||||
lastFog = fog;
|
||||
changed = true;
|
||||
};
|
||||
|
||||
changed = changed || RepositionView();
|
||||
changed = changed || forceRedraw;
|
||||
forceRedraw = false;
|
||||
|
||||
for (int i=0;i<objects.CountItems();i++) {
|
||||
bool hack = ((GLObject*)objects.ItemAt(i))->SpinIt();
|
||||
changed = changed || hack;
|
||||
};
|
||||
|
||||
return changed;
|
||||
};
|
||||
|
||||
void ObjectView::DrawFrame(bool noPause)
|
||||
{
|
||||
LockGL();
|
||||
glClear(GL_COLOR_BUFFER_BIT|(zbuf?GL_DEPTH_BUFFER_BIT:0));
|
||||
|
||||
objListLock.Lock();
|
||||
for (int i=0;i<objects.CountItems();i++) {
|
||||
GLObject *o = ((GLObject*)objects.ItemAt(i));
|
||||
if (o->solidity==0)
|
||||
o->Draw(false, NULL);
|
||||
};
|
||||
EnforceState();
|
||||
for (int i=0;i<objects.CountItems();i++) {
|
||||
GLObject *o = ((GLObject*)objects.ItemAt(i));
|
||||
if (o->solidity!=0)
|
||||
o->Draw(false, NULL);
|
||||
};
|
||||
objListLock.Unlock();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (noPause) {
|
||||
uint64 now = system_time();
|
||||
float f = 1.0/((now - lastFrame)/1000000.0);
|
||||
lastFrame = now;
|
||||
int e;
|
||||
if (histEntries < HISTSIZE) {
|
||||
e = (oldestEntry + histEntries)%HISTSIZE;
|
||||
histEntries++;
|
||||
} else {
|
||||
e = oldestEntry;
|
||||
oldestEntry = (oldestEntry+1)%HISTSIZE;
|
||||
};
|
||||
|
||||
fpsHistory[e] = f;
|
||||
|
||||
if (histEntries > 5) {
|
||||
f = 0;
|
||||
for (int i=0;i<histEntries;i++)
|
||||
f += fpsHistory[(oldestEntry+i)%HISTSIZE];
|
||||
f = f/histEntries;
|
||||
if (fps) {
|
||||
|
||||
glPushAttrib( GL_ENABLE_BIT | GL_LIGHTING_BIT );
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glTranslatef( -0.9, -0.9, 0 );
|
||||
glScalef( 0.10, 0.10, 0.10 );
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_BLEND );
|
||||
glColor3f( 1.0, 1.0, 0 );
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
|
||||
FPS::drawCounter( f );
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
};
|
||||
};
|
||||
} else {
|
||||
histEntries = 0;
|
||||
oldestEntry = 0;
|
||||
};
|
||||
SwapBuffers();
|
||||
UnlockGL();
|
||||
};
|
79
src/apps/glteapot/ObjectView.h
Normal file
79
src/apps/glteapot/ObjectView.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef ObjectView_h
|
||||
#define ObjectView_h
|
||||
|
||||
#include <GL/glu.h>
|
||||
#include <GLView.h>
|
||||
|
||||
#define bmsgFPS 'fps '
|
||||
#define bmsgAddModel 'addm'
|
||||
#define bmsgGouraud 'gour'
|
||||
#define bmsgZBuffer 'zbuf'
|
||||
#define bmsgCulling 'cull'
|
||||
#define bmsgTextured 'txtr'
|
||||
#define bmsgFog 'fog '
|
||||
#define bmsgLighting 'lite'
|
||||
#define bmsgLights 'lits'
|
||||
#define bmsgFilled 'fill'
|
||||
#define bmsgPerspective 'prsp'
|
||||
|
||||
enum lights {
|
||||
lightNone = 0,
|
||||
lightWhite,
|
||||
lightYellow,
|
||||
lightRed,
|
||||
lightBlue,
|
||||
lightGreen
|
||||
};
|
||||
|
||||
#define HISTSIZE 10
|
||||
|
||||
class ResScroll;
|
||||
class ObjectView : public BGLView {
|
||||
public:
|
||||
sem_id drawEvent;
|
||||
sem_id quittingSem;
|
||||
thread_id drawThread;
|
||||
ResScroll * resScroll;
|
||||
|
||||
BList objects;
|
||||
BLocker objListLock;
|
||||
|
||||
float yxRatio,lastYXRatio;
|
||||
uint64 lastFrame;
|
||||
float fpsHistory[HISTSIZE];
|
||||
int32 histEntries,oldestEntry;
|
||||
bool fps;
|
||||
bool gouraud, lastGouraud;
|
||||
bool zbuf,lastZbuf;
|
||||
bool culling,lastCulling;
|
||||
bool lighting,lastLighting;
|
||||
bool filled,lastFilled;
|
||||
bool persp,lastPersp;
|
||||
bool lastTextured,textured;
|
||||
bool lastFog,fog;
|
||||
bool forceRedraw;
|
||||
float objectDistance,lastObjectDistance;
|
||||
|
||||
ObjectView(BRect r, char *name,
|
||||
ulong resizingMode, ulong options);
|
||||
~ObjectView();
|
||||
|
||||
virtual void MouseDown(BPoint p);
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void FrameResized(float width, float height);
|
||||
bool SpinIt();
|
||||
int ObjectAtPoint(BPoint p);
|
||||
virtual void DrawFrame(bool noPause);
|
||||
virtual void Pulse();
|
||||
void EnforceState();
|
||||
bool RepositionView();
|
||||
};
|
||||
|
||||
#endif
|
28
src/apps/glteapot/README.GLTeapot
Normal file
28
src/apps/glteapot/README.GLTeapot
Normal file
@ -0,0 +1,28 @@
|
||||
GLTeapot Project README
|
||||
=======================
|
||||
|
||||
This is a sample application using Be's OpenGL implementation. It uses a
|
||||
generic object viewer class, ObjectView, to view OpenGL objects created
|
||||
using a generic OpenGL object class, GLObject.
|
||||
|
||||
Files
|
||||
=====
|
||||
|
||||
The archive should contain the following files:
|
||||
|
||||
README.GLTeapot -- This file
|
||||
GLTeapot.proj -- Metrowerks project file
|
||||
teapot.data -- Teapot vertex data file
|
||||
Teapot.rsrc -- Application resource file
|
||||
|
||||
GLObject.cpp -- Source files
|
||||
GLObject.h
|
||||
ObjectView.cpp
|
||||
ObjectView.h
|
||||
ResScroll.h
|
||||
error.cpp
|
||||
error..h
|
||||
glob.h
|
||||
teapot_main.cpp
|
||||
util.h
|
||||
|
23
src/apps/glteapot/ResScroll.h
Normal file
23
src/apps/glteapot/ResScroll.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef ResScroll_h
|
||||
#define ResScroll_h
|
||||
|
||||
#include <interface/ScrollBar.h>
|
||||
|
||||
class ObjectView;
|
||||
|
||||
class ResScroll : public BScrollBar {
|
||||
public:
|
||||
ObjectView * objectView;
|
||||
|
||||
ResScroll(BRect r, const char *name,
|
||||
ObjectView *target, orientation posture);
|
||||
virtual void ValueChanged(float value);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
11
src/apps/glteapot/error.cpp
Normal file
11
src/apps/glteapot/error.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include "error.h"
|
||||
|
||||
void fatalerror(char *s)
|
||||
{
|
||||
printf("FATAL ERROR: %s\n",s);
|
||||
};
|
31
src/apps/glteapot/error.h
Normal file
31
src/apps/glteapot/error.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef error_h
|
||||
#define error_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern void fatalerror(char *);
|
||||
|
||||
#define DEBUGGING 1
|
||||
|
||||
#ifdef DEBUGGING
|
||||
|
||||
#define assert(a) if (!(a)) { \
|
||||
printf("%s:%d: Failed assertion `"#a"'\n",__FILE__,__LINE__); \
|
||||
fatalerror("Failed assertion!"); };
|
||||
|
||||
#define checkpoint printf("%s:%d: Checkpoint...\n",__FILE__,__LINE__);\
|
||||
fflush(stdout);
|
||||
|
||||
#else //DEBUGGING
|
||||
|
||||
#define assert(a)
|
||||
#define checkpoint
|
||||
|
||||
#endif //DEBUGGING
|
||||
|
||||
#endif
|
16
src/apps/glteapot/glob.h
Normal file
16
src/apps/glteapot/glob.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
extern float white[3];
|
||||
extern float dimWhite[3];
|
||||
extern float black[3];
|
||||
extern float foggy[3];
|
||||
extern float blue[3];
|
||||
extern float dimBlue[3];
|
||||
extern float yellow[3];
|
||||
extern float dimYellow[3];
|
||||
extern float green[3];
|
||||
extern float dimGreen[3];
|
||||
extern float red[3];
|
2425
src/apps/glteapot/teapot.data
Normal file
2425
src/apps/glteapot/teapot.data
Normal file
File diff suppressed because it is too large
Load Diff
9
src/apps/glteapot/teapot.h
Normal file
9
src/apps/glteapot/teapot.h
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include "GL/gl.h"
|
||||
|
||||
void auxSolidTeapot(GLdouble scale);
|
||||
void auxWireTeapot(GLdouble scale);
|
206
src/apps/glteapot/teapot_main.cpp
Normal file
206
src/apps/glteapot/teapot_main.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include <InterfaceKit.h>
|
||||
#include <stdio.h>
|
||||
#include "ObjectView.h"
|
||||
|
||||
class QuitWindow : public BDirectWindow
|
||||
{
|
||||
public:
|
||||
QuitWindow(BRect r, char *name, window_type wt, ulong something);
|
||||
|
||||
virtual bool QuitRequested();
|
||||
virtual void DirectConnected( direct_buffer_info *info );
|
||||
ObjectView *bgl;
|
||||
|
||||
};
|
||||
|
||||
QuitWindow::QuitWindow(BRect r, char *name, window_type wt, ulong something)
|
||||
: BDirectWindow(r,name,wt,something)
|
||||
{
|
||||
}
|
||||
|
||||
bool QuitWindow::QuitRequested()
|
||||
{
|
||||
printf( "closing \n" );
|
||||
bgl->EnableDirectMode( false );
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
};
|
||||
|
||||
void QuitWindow::DirectConnected( direct_buffer_info *info )
|
||||
{
|
||||
if( bgl )
|
||||
bgl->DirectConnected( info );
|
||||
bgl->EnableDirectMode( true );
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GLenum type = BGL_RGB | BGL_DEPTH | BGL_DOUBLE;
|
||||
//GLenum type = BGL_RGB | BGL_DEPTH | BGL_SINGLE;
|
||||
BRect r(0,0,300,315);
|
||||
|
||||
BApplication *app = new BApplication("application/x-vnd.Be-tpot");
|
||||
|
||||
r.OffsetTo(BPoint(100,100));
|
||||
QuitWindow *win = new QuitWindow(r,"GLTeapot",B_TITLED_WINDOW,0);
|
||||
|
||||
win->Lock();
|
||||
r = win->Bounds();
|
||||
r.bottom = r.top + 14;
|
||||
BMenuBar *mb = new BMenuBar(r,"main menu");
|
||||
|
||||
BMenu *m;
|
||||
BMenuItem *i;
|
||||
BMessage msg (bmsgAddModel);
|
||||
|
||||
mb->AddItem(m = new BMenu("File"));
|
||||
win->AddChild(mb);
|
||||
mb->ResizeToPreferred();
|
||||
|
||||
r = win->Bounds();
|
||||
r.top = mb->Bounds().bottom+1;
|
||||
BView *sv = new BView(r,"subview",B_FOLLOW_ALL,0);
|
||||
win->AddChild(sv);
|
||||
r = sv->Bounds();
|
||||
ObjectView *bgl = new ObjectView(r,"objectView",B_FOLLOW_NONE,type);
|
||||
sv->AddChild(bgl);
|
||||
win->bgl = bgl;
|
||||
|
||||
msg.AddInt32("num",256);
|
||||
m->AddItem(i = new BMenuItem("Add a teapot",new BMessage(msg), 'N'));
|
||||
i->SetTarget(bgl);
|
||||
m->AddSeparatorItem();
|
||||
m->AddItem(i = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
|
||||
i->SetTarget(be_app);
|
||||
msg.RemoveName("num");
|
||||
mb->AddItem(m = new BMenu("Options"));
|
||||
m->AddItem(i = new BMenuItem("Perspective",new BMessage(bmsgPerspective)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(false);
|
||||
m->AddItem(i = new BMenuItem("FPS Display",new BMessage(bmsgFPS)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Filled polygons",new BMessage(bmsgFilled)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Lighting",new BMessage(bmsgLighting)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Backface culling",new BMessage(bmsgCulling)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Z-buffered",new BMessage(bmsgZBuffer)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
m->AddItem(i = new BMenuItem("Gouraud shading",new BMessage(bmsgGouraud)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
// m->AddItem(i = new BMenuItem("Texture mapped",new BMessage(bmsgTextured)));
|
||||
// i->SetTarget(bgl);
|
||||
m->AddItem(i = new BMenuItem("Fog",new BMessage(bmsgFog)));
|
||||
i->SetTarget(bgl);
|
||||
|
||||
BMenu *sm;
|
||||
mb->AddItem(m = new BMenu("Lights"));
|
||||
msg.what = bmsgLights;
|
||||
|
||||
msg.AddInt32("num",1);
|
||||
m->AddItem(i = new BMenuItem(sm = new BMenu("Upper center"),NULL));
|
||||
i->SetTarget(bgl);
|
||||
msg.AddInt32("color",lightNone);
|
||||
sm->AddItem(i = new BMenuItem("Off",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
sm->AddSeparatorItem();
|
||||
msg.ReplaceInt32("color",lightWhite);
|
||||
sm->AddItem(i = new BMenuItem("White",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
msg.ReplaceInt32("color",lightYellow);
|
||||
sm->AddItem(i = new BMenuItem("Yellow",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightBlue);
|
||||
sm->AddItem(i = new BMenuItem("Blue",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightRed);
|
||||
sm->AddItem(i = new BMenuItem("Red",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightGreen);
|
||||
sm->AddItem(i = new BMenuItem("Green",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
|
||||
msg.RemoveName("color");
|
||||
|
||||
msg.ReplaceInt32("num",2);
|
||||
m->AddItem(i = new BMenuItem(sm = new BMenu("Lower left"),NULL));
|
||||
i->SetTarget(bgl);
|
||||
msg.AddInt32("color",lightNone);
|
||||
sm->AddItem(i = new BMenuItem("Off",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
sm->AddSeparatorItem();
|
||||
msg.ReplaceInt32("color",lightWhite);
|
||||
sm->AddItem(i = new BMenuItem("White",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightYellow);
|
||||
sm->AddItem(i = new BMenuItem("Yellow",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightBlue);
|
||||
sm->AddItem(i = new BMenuItem("Blue",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
msg.ReplaceInt32("color",lightRed);
|
||||
sm->AddItem(i = new BMenuItem("Red",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightGreen);
|
||||
sm->AddItem(i = new BMenuItem("Green",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
|
||||
msg.RemoveName("color");
|
||||
|
||||
msg.ReplaceInt32("num",3);
|
||||
m->AddItem(i = new BMenuItem(sm = new BMenu("Right"),NULL));
|
||||
i->SetTarget(bgl);
|
||||
msg.AddInt32("color",lightNone);
|
||||
sm->AddItem(i = new BMenuItem("Off",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
i->SetMarked(true);
|
||||
sm->AddSeparatorItem();
|
||||
msg.ReplaceInt32("color",lightWhite);
|
||||
sm->AddItem(i = new BMenuItem("White",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightYellow);
|
||||
sm->AddItem(i = new BMenuItem("Yellow",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightBlue);
|
||||
sm->AddItem(i = new BMenuItem("Blue",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightRed);
|
||||
sm->AddItem(i = new BMenuItem("Red",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
msg.ReplaceInt32("color",lightGreen);
|
||||
sm->AddItem(i = new BMenuItem("Green",new BMessage(msg)));
|
||||
i->SetTarget(bgl);
|
||||
|
||||
float f = mb->Bounds().IntegerHeight()+1;
|
||||
win->SetSizeLimits(32,1024,32+f,1024+f);
|
||||
|
||||
/*
|
||||
r = win->Bounds();
|
||||
r.top = mb->Bounds().bottom+1;
|
||||
sv->MoveTo(r.left,r.top);
|
||||
sv->ResizeTo(r.right-r.left+1,r.bottom-r.top+1);
|
||||
bgl->ResizeTo(r.right-r.left+1,r.bottom-r.top+1);
|
||||
*/
|
||||
|
||||
win->Unlock();
|
||||
win->Show();
|
||||
|
||||
app->Run();
|
||||
delete app;
|
||||
|
||||
return 0;
|
||||
}
|
381
src/apps/glteapot/util.h
Normal file
381
src/apps/glteapot/util.h
Normal file
@ -0,0 +1,381 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef list_h
|
||||
#define list_h
|
||||
|
||||
#include <memory.h>
|
||||
#include "error.h"
|
||||
|
||||
template <class contents>
|
||||
struct LispNode
|
||||
{
|
||||
contents *car;
|
||||
LispNode *cdr;
|
||||
|
||||
/* Create a node with no next */
|
||||
inline LispNode(contents *value)
|
||||
: car(value), cdr(0) { }
|
||||
|
||||
/* Create a node with specified next */
|
||||
inline LispNode(contents *value, LispNode *next)
|
||||
: car (value), cdr(next) { }
|
||||
|
||||
/* Create a node and insert it in a list right after `prev' */
|
||||
inline LispNode(LispNode *prev, contents *value)
|
||||
: car(value), cdr(prev->cdr) { prev->cdr = this; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class contents>
|
||||
struct LispList
|
||||
{
|
||||
LispNode<contents> *first;
|
||||
|
||||
|
||||
/* -------- List creation --------------- */
|
||||
/* Create an empty list */
|
||||
inline LispList()
|
||||
{ first = 0; }
|
||||
|
||||
/* Create a list pointing to the specified node */
|
||||
inline LispList(LispNode<contents> *_first)
|
||||
{ first = _first; }
|
||||
|
||||
/* ?? */
|
||||
inline LispList(LispList &init)
|
||||
{ first = init.first; }
|
||||
|
||||
/* ---------- List queries ------------- */
|
||||
inline int is_empty()
|
||||
{ return first == 0; }
|
||||
|
||||
/* Determines if a thing is on the list */
|
||||
inline int is_present(contents *element)
|
||||
{
|
||||
for (LispNode<contents> *node = first; node; node = node->cdr)
|
||||
if (node->car == element)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the length of the list */
|
||||
inline int count()
|
||||
{
|
||||
int n = 0;
|
||||
for (LispNode<contents> *node = first; node; node = node->cdr)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* ----------- Adding "nodes" to the list ------------ */
|
||||
/* Add a specified node to the head of the list. */
|
||||
inline void add_head(LispNode<contents> *new_element)
|
||||
{
|
||||
new_element->cdr = first;
|
||||
first = new_element;
|
||||
}
|
||||
|
||||
/* Add a specified node anywhere on the list */
|
||||
inline void add(LispNode<contents> *new_element)
|
||||
{
|
||||
add_head (new_element);
|
||||
}
|
||||
|
||||
inline void add_tail(LispNode<contents> *new_element)
|
||||
{
|
||||
LispNode<contents>** pred = &first;
|
||||
while( *pred )
|
||||
pred = &(*pred)->cdr;
|
||||
*pred = new_element;
|
||||
new_element->cdr = 0;
|
||||
}
|
||||
|
||||
/* ----------- Adding "contents" to the list ------------ */
|
||||
/* ----- (Which in my opinion is far more useful) ------ */
|
||||
/* Create new node pointing to thing, & add to head of list. */
|
||||
inline void add_head_new(contents *new_element)
|
||||
{
|
||||
first = new LispNode<contents>(new_element, first);
|
||||
}
|
||||
inline void add_head(contents *new_element)
|
||||
{ add_head_new(new_element); }
|
||||
|
||||
/* Create new node pointing to thing, & add to end of list. */
|
||||
inline void add_tail_new(contents *new_element)
|
||||
{
|
||||
LispNode< contents > **pred = &first;
|
||||
while (*pred)
|
||||
pred = &(*pred)->cdr;
|
||||
*pred = new LispNode< contents >(new_element);
|
||||
}
|
||||
inline void add_tail(contents *new_element)
|
||||
{ add_tail_new(new_element); }
|
||||
|
||||
/* Create new node pointing to thing, & add anywhere on list */
|
||||
inline void add_new(contents *new_element)
|
||||
{ add_head_new(new_element); }
|
||||
inline void add(contents *new_element)
|
||||
{ add_new(new_element); }
|
||||
|
||||
/* Create and add a new node for a specified element,
|
||||
but only if it's not already on the list. */
|
||||
inline void add_new_once(contents *new_element)
|
||||
{
|
||||
if (!is_present(new_element))
|
||||
add_head_new(new_element);
|
||||
}
|
||||
inline void add_tail_once(contents *new_element)
|
||||
{
|
||||
if (!is_present(new_element))
|
||||
add_tail_new(new_element);
|
||||
}
|
||||
|
||||
/* ------- Removing things from the list ------------ */
|
||||
/* Remove and return the first node on the list j.h. */
|
||||
inline LispNode<contents> *rem_head ()
|
||||
{
|
||||
LispNode<contents> *n = first;
|
||||
if (n)
|
||||
{
|
||||
first = first->cdr;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Remove and return any node on the list. */
|
||||
inline LispNode<contents> *remove ()
|
||||
{ return( rem_head() ); }
|
||||
|
||||
/* Remove a specified node from the list. */
|
||||
inline void remove (LispNode<contents> *node)
|
||||
{
|
||||
for (LispNode<contents> **pp = &first; *pp; pp = &(*pp)->cdr)
|
||||
if (*pp == node)
|
||||
{
|
||||
*pp = (*pp)->cdr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove & delete all nodes pointing to a particular element. */
|
||||
inline void rem_del (contents *element)
|
||||
{
|
||||
LispNode<contents> **pp = &first;
|
||||
while (*pp)
|
||||
{
|
||||
if ((*pp)->car == element)
|
||||
{
|
||||
LispNode<contents> *o = *pp;
|
||||
*pp = o->cdr;
|
||||
delete o;
|
||||
}
|
||||
else
|
||||
pp = &(*pp)->cdr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove and delete all nodes on the list. */
|
||||
inline void rem_del_all()
|
||||
{
|
||||
while (first)
|
||||
{
|
||||
LispNode<contents> *old = first;
|
||||
first = first->cdr;
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------- Simple list storage (by j.h.) ------------ */
|
||||
/* When you just want to hold a bunch of stuff on a list and
|
||||
then pull them off later. Note that these calls do NOT check
|
||||
for to see if a thing is already on the list. Use is_present()
|
||||
before adding.
|
||||
*/
|
||||
/* Put something anywhere on the list */
|
||||
inline void put( contents *c )
|
||||
{ add_tail( c ); }
|
||||
|
||||
/* Put something at beginning of list */
|
||||
inline void put_head( contents *c )
|
||||
{ add_head( c ); }
|
||||
|
||||
/* Put something at end of the list */
|
||||
inline void put_tail( contents *c )
|
||||
{ add_tail( c ); }
|
||||
|
||||
#if 0 /* leaks memory */
|
||||
/* Take a specific thing off the list */
|
||||
inline contents *get(contents *element)
|
||||
{
|
||||
contents *c = 0;
|
||||
for (LispNode<contents> *node = first; node; node = node->cdr)
|
||||
{
|
||||
if (node->car == element)
|
||||
{
|
||||
c = node->car;
|
||||
remove(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Take the first thing off the list */
|
||||
inline contents *get_head()
|
||||
{
|
||||
contents *c = 0;
|
||||
if(first)
|
||||
{
|
||||
c = first->car;
|
||||
delete rem_head();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Take something off the list */
|
||||
inline contents *get()
|
||||
{ return(get_head()); }
|
||||
|
||||
/* XXX inline contents *get_tail() { } */
|
||||
|
||||
/* -------- Stack simulation (by j.h.) ------------ */
|
||||
/* Put a thing onto the head of the list */
|
||||
inline void push( contents *c )
|
||||
{ put_head( c ); }
|
||||
|
||||
/* Remove a thing from the head of the list */
|
||||
inline contents *pop()
|
||||
{ return(get_head()); }
|
||||
|
||||
/* Pop everything off the stack. Empty the stack/list. */
|
||||
inline void pop_all()
|
||||
{ rem_del_all(); }
|
||||
|
||||
|
||||
/* ----------- list/list manipulations ------------ */
|
||||
/* Add all elements present on another list to this list also. */
|
||||
inline void add_new(LispList other)
|
||||
{
|
||||
for (LispNode<contents> *n = other.first; n; n = n->cdr)
|
||||
add_new(n->car);
|
||||
}
|
||||
inline void add_new_once(LispList other)
|
||||
{
|
||||
for (LispNode<contents> *n = other.first; n; n = n->cdr)
|
||||
add_new_once(n->car);
|
||||
}
|
||||
|
||||
/* Remove and delete all nodes whose contents are also present
|
||||
in a different list (set disjunction). */
|
||||
inline void rem_del(LispList other)
|
||||
{
|
||||
for (LispNode<contents> *n = other.first; n; n = n->cdr)
|
||||
rem_del(n->car);
|
||||
}
|
||||
};
|
||||
|
||||
template <class thetype>
|
||||
struct DoubleLinkedNode
|
||||
{
|
||||
thetype *next,*prev;
|
||||
|
||||
DoubleLinkedNode() { next = prev = NULL; };
|
||||
|
||||
void insert_after(thetype *n)
|
||||
{
|
||||
if (next != NULL)
|
||||
next->prev = n;
|
||||
n->next = next;
|
||||
n->prev = (thetype*)this;
|
||||
next = n;
|
||||
};
|
||||
|
||||
void insert_before(thetype *n)
|
||||
{
|
||||
prev->next = n;
|
||||
n->next = (thetype*)this;
|
||||
n->prev = prev;
|
||||
prev = n;
|
||||
};
|
||||
|
||||
void remove()
|
||||
{
|
||||
assert(prev != NULL);
|
||||
prev->next = next;
|
||||
if (next != NULL)
|
||||
next->prev = prev;
|
||||
};
|
||||
};
|
||||
|
||||
template <class thetype>
|
||||
struct DoubleLinkedList : public DoubleLinkedNode<thetype>
|
||||
{
|
||||
DoubleLinkedList() : DoubleLinkedNode<thetype>() {};
|
||||
|
||||
void insert(thetype *n)
|
||||
{
|
||||
insert_after(n);
|
||||
};
|
||||
|
||||
void add(thetype *n)
|
||||
{
|
||||
insert_after(n);
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct BufferArray
|
||||
{
|
||||
T * items;
|
||||
int num_items;
|
||||
int num_slots;
|
||||
int slot_inc;
|
||||
|
||||
void resize(int i)
|
||||
{
|
||||
items = (T*)realloc(items,sizeof(T)*i);
|
||||
num_slots = i;
|
||||
};
|
||||
|
||||
T & operator [](int index)
|
||||
{
|
||||
assert(index < num_items);
|
||||
return items[index];
|
||||
};
|
||||
|
||||
T & get(int index)
|
||||
{
|
||||
assert(index < num_items);
|
||||
return items[index];
|
||||
};
|
||||
|
||||
void add(T &item)
|
||||
{
|
||||
if (num_items == num_slots)
|
||||
resize(num_slots+slot_inc);
|
||||
memcpy(items+num_items,&item,sizeof(item));
|
||||
num_items++;
|
||||
};
|
||||
|
||||
BufferArray(int start_slots, int _slot_inc)
|
||||
{
|
||||
num_slots = start_slots;
|
||||
slot_inc = _slot_inc;
|
||||
assert(slot_inc > 0);
|
||||
num_items = 0;
|
||||
items = (T*)malloc(sizeof(T)*num_slots);
|
||||
};
|
||||
|
||||
~BufferArray()
|
||||
{
|
||||
free(items);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user