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:
Jérôme Duval 2005-06-10 09:07:17 +00:00
parent f1496739a3
commit c8c44fa029
19 changed files with 4576 additions and 0 deletions

View File

@ -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
View 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
View 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 );
};

View 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
};

View 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);
};

View 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
View 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
View 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.

View 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();
};

View 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

View 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

View 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

View 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
View 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
View 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];

File diff suppressed because it is too large Load Diff

View 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);

View 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
View 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