patch by Fredrik Modéen:

* extensive code cleanup
* small additional clean ups by myself


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22716 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2007-10-25 12:28:22 +00:00
parent 42b025bece
commit 450bb3e557
14 changed files with 992 additions and 820 deletions
-1
View File
@@ -9,7 +9,6 @@ class FPS {
public:
FPS();
~FPS();
static void drawCounter(GLfloat frameRate);
private:
+82 -81
View File
@@ -65,22 +65,22 @@ GLObject::GLObject(ObjectView *ov)
rotY(0),
spinX(2),
spinY(2),
lastRotX(0),
lastRotY(0),
x(0),
y(0),
z(-2.0),
color(4),
solidity(0),
lastRotX(0),
lastRotY(0),
color(4),
changed(false),
objView(ov)
fObjView(ov)
{
};
}
GLObject::~GLObject()
{
};
}
void
@@ -126,10 +126,10 @@ GLObject::MenuInvoked(BPoint point)
color = index+1;
} else if (index > 5) {
solidity = index-6;
};
}
changed = true;
setEvent(objView->drawEvent);
};
setEvent(fObjView->drawEvent);
}
bool
@@ -143,7 +143,7 @@ GLObject::SpinIt()
lastRotY = rotY;
return c;
};
}
void
@@ -156,21 +156,21 @@ GLObject::Draw(bool forID, float IDcolor[])
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)
fPoints(100,100),
fTriangles(100,100),
fQs(50,50)
{
float maxp = 0;
int numPt,numTri;
@@ -193,13 +193,14 @@ TriangleObject::TriangleObject(ObjectView *ov, char *filename)
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;
};
fPoints.add(p);
}
for (int i = 0; i < fPoints.num_items; i++) {
fPoints[i].x /= maxp;
fPoints[i].y /= maxp;
fPoints[i].z /= maxp;
}
fscanf(f,"%d",&numTri);
// printf("Triangles: %d\n",numTri);
@@ -210,25 +211,25 @@ TriangleObject::TriangleObject(ObjectView *ov, char *filename)
&t.p1,
&t.p2,
&t.p3);
triangles.add(t);
fTriangles.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;
q.pts[2] = fTriangles[0].p1;
q.pts[0] = fTriangles[0].p2;
q.pts[1] = fTriangles[0].p3;
q.pts[3] = fTriangles[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;
if ((fTriangles[i-1].p1 == fTriangles[i].p2) &&
(fTriangles[i-1].p3 == fTriangles[i].p3)) {
q.pts[q.numpts++] = fTriangles[i+1].p1;
q.pts[q.numpts++] = fTriangles[i+1].p3;
qpts+=2;
} else {
int *np = (int*)malloc(sizeof(int)*q.numpts);
@@ -236,34 +237,34 @@ TriangleObject::TriangleObject(ObjectView *ov, char *filename)
quadStrip nqs;
nqs.numpts = q.numpts;
nqs.pts = np;
qs.add(nqs);
fQs.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;
};
};
q.pts[2] = fTriangles[i].p1;
q.pts[0] = fTriangles[i].p2;
q.pts[1] = fTriangles[i].p3;
q.pts[3] = fTriangles[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);
fQs.add(nqs);
fclose(f);
};
}
TriangleObject::~TriangleObject()
{
for (int i=0;i<qs.num_items;i++) {
free(qs[i].pts);
};
};
for (int i = 0; i < fQs.num_items; i++) {
free(fQs[i].pts);
}
}
void
@@ -297,70 +298,70 @@ TriangleObject::DoDrawing(bool forID)
} 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++) {
for (int i = 0; i < fQs.num_items; i++) {
glBegin(GL_QUAD_STRIP);
for (int j=0;j<qs[i].numpts;j++) {
for (int j = 0; j < fQs[i].numpts; j++) {
glNormal3f(
points[qs[i].pts[j]].nx,
points[qs[i].pts[j]].ny,
points[qs[i].pts[j]].nz
fPoints[fQs[i].pts[j]].nx,
fPoints[fQs[i].pts[j]].ny,
fPoints[fQs[i].pts[j]].nz
);
glVertex3f(
points[qs[i].pts[j]].x,
points[qs[i].pts[j]].y,
points[qs[i].pts[j]].z
fPoints[fQs[i].pts[j]].x,
fPoints[fQs[i].pts[j]].y,
fPoints[fQs[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;
for (int i = 0; i < fTriangles.num_items; i++) {
int v3 = fTriangles[i].p1;
int v1 = fTriangles[i].p2;
int v2 = fTriangles[i].p3;
glNormal3f(
points[v1].nx,
points[v1].ny,
points[v1].nz
fPoints[v1].nx,
fPoints[v1].ny,
fPoints[v1].nz
);
glVertex3f(
points[v1].x,
points[v1].y,
points[v1].z
fPoints[v1].x,
fPoints[v1].y,
fPoints[v1].z
);
glNormal3f(
points[v2].nx,
points[v2].ny,
points[v2].nz
fPoints[v2].nx,
fPoints[v2].ny,
fPoints[v2].nz
);
glVertex3f(
points[v2].x,
points[v2].y,
points[v2].z
fPoints[v2].x,
fPoints[v2].y,
fPoints[v2].z
);
glNormal3f(
points[v3].nx,
points[v3].ny,
points[v3].nz
fPoints[v3].nx,
fPoints[v3].ny,
fPoints[v3].nz
);
glVertex3f(
points[v3].x,
points[v3].y,
points[v3].z
fPoints[v3].x,
fPoints[v3].y,
fPoints[v3].z
);
};
}
glEnd();
#endif
};
}
+12 -8
View File
@@ -28,30 +28,34 @@ class GLObject {
public:
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) {};
float rotX,rotY,spinX,spinY,lastRotX,lastRotY;
float rotX, rotY, spinX, spinY;
float x, y, z;
int color;
int solidity;
protected:
float lastRotX, lastRotY;
int color;
bool changed;
ObjectView * objView;
private:
ObjectView* fObjView;
};
class TriangleObject : public GLObject {
public:
TriangleObject(ObjectView* ov, char* filename);
virtual ~TriangleObject();
virtual void DoDrawing(bool forID);
BufferArray<point> points;
BufferArray<tri> triangles;
BufferArray<quadStrip> qs;
private:
BufferArray<point> fPoints;
BufferArray<tri> fTriangles;
BufferArray<quadStrip> fQs;
};
#endif // GL_OBJECT_H
+2 -1
View File
@@ -7,7 +7,8 @@ Application GLTeapot :
GLObject.cpp
ObjectView.cpp
error.cpp
teapot_main.cpp
TeapotWindow.cpp
TeapotApp.cpp
: be GL game
: GLTeapot.rdef
;
+241 -190
View File
@@ -54,6 +54,7 @@ light lights[] = {
};
long
signalEvent(sem_id event)
{
@@ -63,7 +64,7 @@ signalEvent(sem_id event)
release_sem_etc(event,-c,0);
return 0;
};
}
long
@@ -75,7 +76,7 @@ setEvent(sem_id event)
release_sem_etc(event,-c,0);
return 0;
};
}
long
@@ -89,12 +90,14 @@ waitEvent(sem_id event)
acquire_sem_etc(event,c,0,0);
return 0;
};
}
long
simonThread(ObjectView *ov)
static int32
simonThread(void* cookie)
{
ObjectView* ov = (ObjectView*)cookie;
int noPause = 0;
while (acquire_sem_etc(ov->quittingSem,1,B_TIMEOUT,0) == B_NO_ERROR) {
if (ov->SpinIt()) {
@@ -105,48 +108,55 @@ simonThread(ObjectView *ov)
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)
: BGLView(r,name,resizingMode,0,options),
fHistEntries(0),
fOldestEntry(0),
fFps(true),
fLastGouraud(true),
fGouraud(true),
fLastZbuf(true),
fZbuf(true),
fLastCulling(true),
fCulling(true),
fLastLighting(true),
fLighting(true),
fLastFilled(true),
fFilled(true),
fLastPersp(false),
fPersp(false),
fLastTextured(false),
fTextured(false),
fLastFog(false),
fFog(false),
fForceRedraw(false),
fLastYXRatio(1),
fYxRatio(1)
{
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;
fLastObjectDistance = fObjectDistance = depthOfView/8;
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);
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();
};
fObjListLock.Lock();
fObjects.AddItem(new TriangleObject(this, teapotPath));
fObjListLock.Unlock();
}
ObjectView::~ObjectView()
{
delete_sem(quittingSem);
delete_sem(drawEvent);
};
}
void
@@ -211,12 +221,12 @@ ObjectView::AttachedToWindow()
UnlockGL();
drawThread = spawn_thread((thread_entry)simonThread,
"Simon",B_NORMAL_PRIORITY,(void*)this);
resume_thread(drawThread);
forceRedraw = true;
fDrawThread = spawn_thread(simonThread,
"Simon", B_NORMAL_PRIORITY, this);
resume_thread(fDrawThread);
fForceRedraw = true;
setEvent(drawEvent);
};
}
void
@@ -230,15 +240,16 @@ ObjectView::DetachedFromWindow()
while (Window()->IsLocked()) {
locks++;
Window()->Unlock();
};
}
acquire_sem(quittingSem);
release_sem(drawEvent);
wait_for_thread(drawThread,&dummy);
wait_for_thread(fDrawThread, &dummy);
release_sem(quittingSem);
while (locks--) Window()->Lock();
};
while (locks--)
Window()->Lock();
}
void
@@ -251,29 +262,30 @@ ObjectView::Pulse()
b.OffsetTo(0,0);
if (b != p) {
ResizeTo(p.right - p.left, p.bottom - p.top);
};
}
Window()->Unlock();
};
}
void
ObjectView::MessageReceived(BMessage* msg)
{
// msg->PrintToStream();
BMenuItem* i;
bool* b;
switch (msg->what) {
case bmsgFPS:
fps = (fps)?false:true;
fFps = (fFps) ? false : true;
msg->FindPointer("source", (void**)&i);
i->SetMarked(fps);
forceRedraw = true;
i->SetMarked(fFps);
fForceRedraw = true;
setEvent(drawEvent);
break;
case bmsgAddModel:
objListLock.Lock();
objects.AddItem(new TriangleObject(this,teapotPath));
objListLock.Unlock();
fObjListLock.Lock();
fObjects.AddItem(new TriangleObject(this, teapotPath));
fObjListLock.Unlock();
setEvent(drawEvent);
break;
case bmsgLights:
@@ -287,58 +299,65 @@ ObjectView::MessageReceived(BMessage *msg)
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);
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;
fForceRedraw = true;
setEvent(drawEvent);
break;
}
case bmsgGouraud:
b = &gouraud;
b = &fGouraud;
goto stateChange;
case bmsgZBuffer:
b = &zbuf;
b = &fZbuf;
goto stateChange;
case bmsgCulling:
b = &culling;
b = &fCulling;
goto stateChange;
case bmsgLighting:
b = &lighting;
b = &fLighting;
goto stateChange;
case bmsgFilled:
b = &filled;
b = &fFilled;
goto stateChange;
case bmsgPerspective:
b = &persp;
b = &fPersp;
goto stateChange;
case bmsgFog:
b = &fog;
b = &fFog;
goto stateChange;
stateChange:
msg->FindPointer("source",(void **)&i);
if (!i) return;
if (msg->FindPointer("source", (void**)&i) < B_OK)
i = NULL;
if (!i)
return;
if (*b) {
i->SetMarked(*b = false);
} else {
i->SetMarked(*b = true);
};
}
setEvent(drawEvent);
break;
default:
BGLView::MessageReceived(msg);
};
};
}
}
int
@@ -349,17 +368,18 @@ ObjectView::ObjectAtPoint(BPoint p)
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));
glClear(GL_COLOR_BUFFER_BIT | (fZbuf ? GL_DEPTH_BUFFER_BIT : 0));
float f[3];
f[1] = f[2] = 0;
for (int i=0;i<objects.CountItems();i++) {
for (int i = 0; i < fObjects.CountItems(); i++) {
f[0] = (255 - i) / 255.0;
((GLObject*)objects.ItemAt(i))->Draw(true, f);
};
((GLObject*)fObjects.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);
glReadPixels((GLint)p.x, (GLint)(Bounds().bottom - p.y), 1, 1,
GL_RGB, GL_UNSIGNED_BYTE, pixel);
int objNum = pixel[0];
objNum = 255 - objNum;
@@ -367,7 +387,7 @@ ObjectView::ObjectAtPoint(BPoint p)
UnlockGL();
return objNum;
};
}
void
@@ -381,29 +401,31 @@ ObjectView::MouseDown(BPoint p)
BMessage *m = Window()->CurrentMessage();
uint32 buttons = m->FindInt32("buttons");
o = ((GLObject*)objects.ItemAt(ObjectAtPoint(p)));
o = ((GLObject*)fObjects.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));
if (fPersp) {
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)
@@ -411,20 +433,21 @@ ObjectView::MouseDown(BPoint p)
else
o->y += yinc;
op = np;
forceRedraw = true;
fForceRedraw = 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;
@@ -433,22 +456,23 @@ ObjectView::MouseDown(BPoint p)
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;
@@ -456,14 +480,14 @@ ObjectView::MouseDown(BPoint p)
ConvertToScreen(&point);
Window()->Unlock();
o->MenuInvoked(point);
};
};
}
}
while (locks--)
Window()->Lock();
setEvent(drawEvent);
};
}
void
@@ -476,7 +500,7 @@ ObjectView::FrameResized(float w, float h)
BRect b = Bounds();
w = b.Width();
h = b.Height();
yxRatio = h/w;
fYxRatio = h / w;
glViewport(0, 0, (GLint)w + 1, (GLint)h + 1);
// To prevent weird buffer contents
@@ -485,25 +509,26 @@ ObjectView::FrameResized(float w, float h)
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;
if (fPersp) {
gluPerspective(60, 1.0 / fYxRatio, 0.15, 120);
} else {
if (fYxRatio < 1) {
glOrtho(-scale / fYxRatio, scale / fYxRatio, -scale, scale, -1.0,
depthOfView * 4);
} else {
glOrtho(-scale, scale, -scale * fYxRatio, scale * fYxRatio, -1.0,
depthOfView * 4);
}
}
fLastYXRatio = fYxRatio;
glMatrixMode(GL_MODELVIEW);
UnlockGL();
forceRedraw = true;
fForceRedraw = true;
setEvent(drawEvent);
}
@@ -511,53 +536,67 @@ ObjectView::FrameResized(float w, float h)
bool
ObjectView::RepositionView()
{
if (!(persp != lastPersp) &&
!(lastObjectDistance != objectDistance) &&
!(lastYXRatio != yxRatio)) {
if (!(fPersp != fLastPersp) &&
!(fLastObjectDistance != fObjectDistance) &&
!(fLastYXRatio != fYxRatio)) {
return false;
};
}
LockGL();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float scale = displayScale;
if (persp) {
gluPerspective(60,1.0/yxRatio,0.15,120);
if (fPersp) {
gluPerspective(60, 1.0 / fYxRatio, 0.15, 120);
} else {
if (yxRatio < 1) {
glOrtho(-scale/yxRatio, scale/yxRatio, -scale, scale,
-1.0, depthOfView*4);
if (fYxRatio < 1) {
glOrtho(-scale / fYxRatio, scale / fYxRatio, -scale, scale, -1.0,
depthOfView * 4);
} else {
glOrtho(-scale, scale, -scale*yxRatio, scale*yxRatio,
-1.0, depthOfView*4);
};
};
glOrtho(-scale, scale, -scale * fYxRatio, scale * fYxRatio, -1.0,
depthOfView * 4);
}
}
glMatrixMode(GL_MODELVIEW);
UnlockGL();
lastObjectDistance = objectDistance;
lastPersp = persp;
lastYXRatio = yxRatio;
fLastObjectDistance = fObjectDistance;
fLastPersp = fPersp;
fLastYXRatio = fYxRatio;
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) {
glShadeModel(fGouraud ? GL_SMOOTH : GL_FLAT);
if (fZbuf)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
if (fCulling)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
if (fLighting)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
if (fFilled) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
};
if (fog) {
}
if (fFog) {
glFogf(GL_FOG_START, 10.0);
glFogf(GL_FOG_DENSITY, 0.2);
glFogf(GL_FOG_END, depthOfView);
@@ -569,8 +608,8 @@ ObjectView::EnforceState()
glDisable(GL_FOG);
bgColor = black;
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0);
};
};
}
}
bool
@@ -578,47 +617,61 @@ ObjectView::SpinIt()
{
bool changed = false;
if (gouraud != lastGouraud) {
if (fGouraud != fLastGouraud) {
LockGL();
glShadeModel(gouraud?GL_SMOOTH:GL_FLAT);
glShadeModel(fGouraud ? GL_SMOOTH : GL_FLAT);
UnlockGL();
lastGouraud = gouraud;
fLastGouraud = fGouraud;
changed = true;
};
if (zbuf != lastZbuf) {
}
if (fZbuf != fLastZbuf) {
LockGL();
if (zbuf) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
if (fZbuf)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
UnlockGL();
lastZbuf = zbuf;
fLastZbuf = fZbuf;
changed = true;
};
if (culling != lastCulling) {
}
if (fCulling != fLastCulling) {
LockGL();
if (culling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
if (fCulling)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
UnlockGL();
lastCulling = culling;
fLastCulling = fCulling;
changed = true;
};
if (lighting != lastLighting) {
}
if (fLighting != fLastLighting) {
LockGL();
if (lighting) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);
if (fLighting)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
UnlockGL();
lastLighting = lighting;
fLastLighting = fLighting;
changed = true;
};
if (filled != lastFilled) {
}
if (fFilled != fLastFilled) {
LockGL();
if (filled) {
if (fFilled) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
};
}
UnlockGL();
lastFilled = filled;
fLastFilled = fFilled;
changed = true;
};
if (fog != lastFog) {
if (fog) {
}
if (fFog != fLastFog) {
if (fFog) {
glFogf(GL_FOG_START, 1.0);
glFogf(GL_FOG_DENSITY, 0.2);
glFogf(GL_FOG_END, depthOfView);
@@ -630,69 +683,68 @@ ObjectView::SpinIt()
glDisable(GL_FOG);
bgColor = black;
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0);
};
lastFog = fog;
}
fLastFog = fFog;
changed = true;
};
}
changed = changed || RepositionView();
changed = changed || forceRedraw;
forceRedraw = false;
changed = changed || fForceRedraw;
fForceRedraw = false;
for (int i=0;i<objects.CountItems();i++) {
bool hack = ((GLObject*)objects.ItemAt(i))->SpinIt();
for (int i = 0; i < fObjects.CountItems(); i++) {
bool hack = ((GLObject*)fObjects.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));
glClear(GL_COLOR_BUFFER_BIT | (fZbuf ? GL_DEPTH_BUFFER_BIT : 0));
objListLock.Lock();
for (int i=0;i<objects.CountItems();i++) {
GLObject *o = ((GLObject*)objects.ItemAt(i));
fObjListLock.Lock();
for (int i = 0; i < fObjects.CountItems(); i++) {
GLObject *o = ((GLObject*)fObjects.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));
for (int i = 0; i < fObjects.CountItems(); i++) {
GLObject *o = ((GLObject*)fObjects.ItemAt(i));
if (o->solidity != 0)
o->Draw(false, NULL);
};
objListLock.Unlock();
}
fObjListLock.Unlock();
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
if (noPause) {
uint64 now = system_time();
float f = 1.0/((now - lastFrame)/1000000.0);
lastFrame = now;
float f = 1.0 / ((now - fLastFrame) / 1000000.0);
fLastFrame = now;
int e;
if (histEntries < HISTSIZE) {
e = (oldestEntry + histEntries)%HISTSIZE;
histEntries++;
if (fHistEntries < HISTSIZE) {
e = (fOldestEntry + fHistEntries) % HISTSIZE;
fHistEntries++;
} else {
e = oldestEntry;
oldestEntry = (oldestEntry+1)%HISTSIZE;
};
e = fOldestEntry;
fOldestEntry = (fOldestEntry + 1) % HISTSIZE;
}
fpsHistory[e] = f;
fFpsHistory[e] = f;
if (histEntries > 5) {
if (fHistEntries > 5) {
f = 0;
for (int i=0;i<histEntries;i++)
f += fpsHistory[(oldestEntry+i)%HISTSIZE];
f = f/histEntries;
if (fps) {
for (int i = 0; i < fHistEntries; i++)
f += fFpsHistory[(fOldestEntry + i) % HISTSIZE];
f = f/fHistEntries;
if (fFps) {
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT);
glPushMatrix();
glLoadIdentity();
@@ -702,7 +754,6 @@ ObjectView::DrawFrame(bool noPause)
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glColor3f(1.0, 1.0, 0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -715,12 +766,12 @@ ObjectView::DrawFrame(bool noPause)
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
};
};
}
}
} else {
histEntries = 0;
oldestEntry = 0;
};
fHistEntries = 0;
fOldestEntry = 0;
}
SwapBuffers();
UnlockGL();
};
}
+16 -23
View File
@@ -36,8 +36,8 @@ class ResScroll;
class ObjectView : public BGLView {
public:
ObjectView(BRect r, char *name,
ulong resizingMode, ulong options);
ObjectView(BRect r, char* name, ulong resizingMode,
ulong options);
~ObjectView();
virtual void MouseDown(BPoint p);
@@ -54,28 +54,21 @@ class ObjectView : public BGLView {
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;
private:
thread_id fDrawThread;
ResScroll* fResScroll;
BList fObjects;
BLocker fObjListLock;
uint64 fLastFrame;
int32 fHistEntries,fOldestEntry;
bool fFps, fLastGouraud, fGouraud;
bool fLastZbuf, fZbuf, fLastCulling, fCulling;
bool fLastLighting, fLighting, fLastFilled, fFilled;
bool fLastPersp, fPersp, fLastTextured, fTextured;
bool fLastFog, fFog, fForceRedraw;
float fLastYXRatio, fYxRatio, fFpsHistory[HISTSIZE];
float fObjectDistance,fLastObjectDistance;
};
#endif // OBJECT_VIEW_H
+6 -4
View File
@@ -6,17 +6,19 @@
#ifndef RESSCROLL_H
#define RESSCROLL_H
#include <interface/ScrollBar.h>
#include <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);
private:
ObjectView* fObjectView;
};
#endif
#endif // RESSCROLL_H
+35
View File
@@ -0,0 +1,35 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#include "TeapotApp.h"
int
main(int argc, char** argv)
{
TeapotApp* app = new TeapotApp("application/x-vnd.Haiku-GLTeapot");
app->Run();
delete app;
return 0;
}
TeapotApp::TeapotApp(const char* sign)
: BApplication(sign)
{
fTeapotWindow = new TeapotWindow(BRect(5, 25, 300, 315), "GLTeapot", B_TITLED_WINDOW, 0);
fTeapotWindow->Show();
}
void
TeapotApp::MessageReceived(BMessage* msg)
{
// msg->PrintToStream();
switch (msg->what) {
default:
BApplication::MessageReceived(msg);
}
}
+20
View File
@@ -0,0 +1,20 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#ifndef _TEAPOT_APP_
#define _TEAPOT_APP_
#include <Application.h>
#include "TeapotWindow.h"
class TeapotApp : public BApplication {
public:
TeapotApp(const char* sign);
virtual void MessageReceived(BMessage* msg);
// void AboutRequested();
private:
TeapotWindow* fTeapotWindow;
};
#endif
+193
View File
@@ -0,0 +1,193 @@
/*
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 <InterfaceKit.h>
#include <Rect.h>
#include <Point.h>
#include "TeapotWindow.h"
TeapotWindow::TeapotWindow(BRect rect, char* name, window_type wt, ulong something)
: BDirectWindow(rect,name,wt,something)
{
GLenum type = BGL_RGB | BGL_DEPTH | BGL_DOUBLE;
BRect r = rect;
r.OffsetTo(BPoint(100,100));
Lock();
r = Bounds();
r.bottom = r.top + 14;
BMenuBar* mb = new BMenuBar(r,"main menu");
BMenu* m;
BMessage msg (bmsgAddModel);
mb->AddItem(m = new BMenu("File"));
AddChild(mb);
mb->ResizeToPreferred();
r = Bounds();
r.top = mb->Bounds().bottom+1;
BView *sv = new BView(r,"subview",B_FOLLOW_ALL,0);
AddChild(sv);
r = sv->Bounds();
fObjectView = new ObjectView(r,"objectView", B_FOLLOW_ALL_SIDES,type);
sv->AddChild(fObjectView);
fObjectView = fObjectView;
BMenuItem* item;
msg.AddInt32("num",256);
m->AddItem(item = new BMenuItem("Add a teapot",new BMessage(msg), 'N'));
item->SetTarget(fObjectView);
m->AddSeparatorItem();
m->AddItem(item = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
item->SetTarget(be_app);
msg.RemoveName("num");
mb->AddItem(m = new BMenu("Options"));
m->AddItem(item = new BMenuItem("Perspective",new BMessage(bmsgPerspective)));
item->SetTarget(fObjectView);
item->SetMarked(false);
m->AddItem(item = new BMenuItem("FPS Display",new BMessage(bmsgFPS)));
item->SetTarget(fObjectView);
item->SetMarked(true);
m->AddItem(item = new BMenuItem("Filled polygons",new BMessage(bmsgFilled)));
item->SetTarget(fObjectView);
item->SetMarked(true);
m->AddItem(item = new BMenuItem("Lighting",new BMessage(bmsgLighting)));
item->SetTarget(fObjectView);
item->SetMarked(true);
m->AddItem(item = new BMenuItem("Backface culling",new BMessage(bmsgCulling)));
item->SetTarget(fObjectView);
item->SetMarked(true);
m->AddItem(item = new BMenuItem("Z-buffered",new BMessage(bmsgZBuffer)));
item->SetTarget(fObjectView);
item->SetMarked(true);
m->AddItem(item = new BMenuItem("Gouraud shading",new BMessage(bmsgGouraud)));
item->SetTarget(fObjectView);
item->SetMarked(true);
// m->AddItem(item = new BMenuItem("Texture mapped",new BMessage(bmsgTextured)));
// item->SetTarget(fObjectView);
m->AddItem(item = new BMenuItem("Fog",new BMessage(bmsgFog)));
item->SetTarget(fObjectView);
BMenu *sm;
mb->AddItem(m = new BMenu("Lights"));
msg.what = bmsgLights;
msg.AddInt32("num",1);
m->AddItem(item = new BMenuItem(sm = new BMenu("Upper center"),NULL));
item->SetTarget(fObjectView);
msg.AddInt32("color",lightNone);
sm->AddItem(item = new BMenuItem("Off",new BMessage(msg)));
item->SetTarget(fObjectView);
sm->AddSeparatorItem();
msg.ReplaceInt32("color",lightWhite);
sm->AddItem(item = new BMenuItem("White",new BMessage(msg)));
item->SetTarget(fObjectView);
item->SetMarked(true);
msg.ReplaceInt32("color",lightYellow);
sm->AddItem(item = new BMenuItem("Yellow",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightBlue);
sm->AddItem(item = new BMenuItem("Blue",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightRed);
sm->AddItem(item = new BMenuItem("Red",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightGreen);
sm->AddItem(item = new BMenuItem("Green",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.RemoveName("color");
msg.ReplaceInt32("num",2);
m->AddItem(item = new BMenuItem(sm = new BMenu("Lower left"),NULL));
item->SetTarget(fObjectView);
msg.AddInt32("color",lightNone);
sm->AddItem(item = new BMenuItem("Off",new BMessage(msg)));
item->SetTarget(fObjectView);
sm->AddSeparatorItem();
msg.ReplaceInt32("color",lightWhite);
sm->AddItem(item = new BMenuItem("White",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightYellow);
sm->AddItem(item = new BMenuItem("Yellow",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightBlue);
sm->AddItem(item = new BMenuItem("Blue",new BMessage(msg)));
item->SetTarget(fObjectView);
item->SetMarked(true);
msg.ReplaceInt32("color",lightRed);
sm->AddItem(item = new BMenuItem("Red",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightGreen);
sm->AddItem(item = new BMenuItem("Green",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.RemoveName("color");
msg.ReplaceInt32("num",3);
m->AddItem(item = new BMenuItem(sm = new BMenu("Right"),NULL));
item->SetTarget(fObjectView);
msg.AddInt32("color",lightNone);
sm->AddItem(item = new BMenuItem("Off",new BMessage(msg)));
item->SetTarget(fObjectView);
item->SetMarked(true);
sm->AddSeparatorItem();
msg.ReplaceInt32("color",lightWhite);
sm->AddItem(item = new BMenuItem("White",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightYellow);
sm->AddItem(item = new BMenuItem("Yellow",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightBlue);
sm->AddItem(item = new BMenuItem("Blue",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightRed);
sm->AddItem(item = new BMenuItem("Red",new BMessage(msg)));
item->SetTarget(fObjectView);
msg.ReplaceInt32("color",lightGreen);
sm->AddItem(item = new BMenuItem("Green",new BMessage(msg)));
item->SetTarget(fObjectView);
float f = mb->Bounds().IntegerHeight()+1;
SetSizeLimits(32,1024,32+f,1024+f);
Unlock();
}
bool
TeapotWindow::QuitRequested()
{
// printf("closing \n");
fObjectView->EnableDirectMode( false );
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
void
TeapotWindow::DirectConnected(direct_buffer_info* info)
{
if (fObjectView)
fObjectView->DirectConnected( info );
fObjectView->EnableDirectMode( true );
}
void
TeapotWindow::MessageReceived(BMessage* msg)
{
// msg->PrintToStream();
switch (msg->what) {
default:
BDirectWindow::MessageReceived(msg);
}
}
+24
View File
@@ -0,0 +1,24 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#ifndef _TEAPOT_WINDOW_
#define _TEAPOT_WINDOW_
#include <DirectWindow.h>
#include "ObjectView.h"
class TeapotWindow : public BDirectWindow {
public:
TeapotWindow(BRect r, char* name, window_type wt, ulong something);
virtual bool QuitRequested();
virtual void DirectConnected( direct_buffer_info* info );
virtual void MessageReceived(BMessage* msg);
private:
ObjectView* fObjectView;
};
#endif
+1 -1
View File
@@ -9,4 +9,4 @@ void
fatalerror(char *s)
{
printf("FATAL ERROR: %s\n",s);
};
}
-212
View File
@@ -1,212 +0,0 @@
/*
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 <InterfaceKit.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.Haiku-GLTeapot");
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;
}
+98 -37
View File
@@ -25,7 +25,6 @@ struct LispNode {
/* 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; }
};
@@ -33,7 +32,6 @@ template <class contents>
struct LispList {
LispNode<contents> *first;
/* -------- List creation --------------- */
/* Create an empty list */
inline LispList()
@@ -41,24 +39,28 @@ struct 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)
{
@@ -68,6 +70,7 @@ struct LispList {
return 0;
}
/* Returns the length of the list */
inline int count()
{
@@ -77,6 +80,7 @@ struct LispList {
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)
@@ -85,12 +89,14 @@ struct LispList {
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;
@@ -100,36 +106,52 @@ struct LispList {
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); }
{
add_head_new(new_element);
}
inline void add(contents* new_element)
{ add_new(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. */
@@ -138,61 +160,67 @@ struct LispList {
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)
{
if (n) {
first = first->cdr;
}
return n;
}
/* Remove and return any node on the list. */
inline LispNode<contents>* remove ()
{ return( rem_head() ); }
{
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)
{
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)
{
while (*pp) {
if ((*pp)->car == element) {
LispNode<contents> *o = *pp;
*pp = o->cdr;
delete o;
}
else
} else
pp = &(*pp)->cdr;
}
}
/* Remove and delete all nodes on the list. */
inline void rem_del_all()
{
while (first)
{
while (first) {
LispNode<contents>* old = first;
first = first->cdr;
delete old;
@@ -201,22 +229,30 @@ struct LispList {
/* -------- 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.
/* 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 ); }
{
add_tail( c );
}
/* Put something at beginning of list */
inline void put_head( contents* c )
{ add_head( c ); }
{
add_head( c );
}
/* Put something at end of the list */
inline void put_tail( contents* c )
{ add_tail( c ); }
{
add_tail( c );
}
#if 0 /* leaks memory */
/* Take a specific thing off the list */
@@ -247,12 +283,14 @@ struct LispList {
return c;
}
/* Take something off the list */
inline contents* get()
{
return(get_head());
}
/* XXX inline contents *get_tail() { } */
/* -------- Stack simulation (by j.h.) ------------ */
@@ -262,6 +300,7 @@ struct LispList {
put_head(c);
}
/* Remove a thing from the head of the list */
inline contents* pop()
{
@@ -276,18 +315,22 @@ struct LispList {
/* ----------- 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)
@@ -300,18 +343,25 @@ struct LispList {
template <class thetype>
struct DoubleLinkedNode
{
thetype *next,*prev;
thetype* next;
thetype* prev;
DoubleLinkedNode()
{
next = prev = NULL;
}
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)
{
@@ -319,16 +369,19 @@ struct DoubleLinkedNode
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>
@@ -338,13 +391,15 @@ struct DoubleLinkedList : public DoubleLinkedNode<thetype>
void insert(thetype* n)
{
insert_after(n);
};
}
void add(thetype* n)
{
insert_after(n);
}
};
};
template <class T>
struct BufferArray {
@@ -357,27 +412,32 @@ struct BufferArray {
{
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)
{
@@ -386,12 +446,13 @@ struct BufferArray {
assert(slot_inc > 0);
num_items = 0;
items = (T*)malloc(sizeof(T)*num_slots);
};
}
~BufferArray()
{
free(items);
};
}
};
#endif // UTIL_H