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:
@@ -8,8 +8,7 @@
|
||||
class FPS {
|
||||
public:
|
||||
FPS();
|
||||
~FPS();
|
||||
|
||||
~FPS();
|
||||
static void drawCounter(GLfloat frameRate);
|
||||
|
||||
private:
|
||||
|
||||
+110
-109
@@ -59,35 +59,35 @@ material materials[] = {
|
||||
extern long setEvent(sem_id event);
|
||||
|
||||
|
||||
GLObject::GLObject(ObjectView *ov)
|
||||
GLObject::GLObject(ObjectView* ov)
|
||||
:
|
||||
rotX(0),
|
||||
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
|
||||
GLObject::MenuInvoked(BPoint point)
|
||||
{
|
||||
BPopUpMenu *m = new BPopUpMenu("Object",false,false);
|
||||
BMenuItem *i;
|
||||
BPopUpMenu* m = new BPopUpMenu("Object",false,false);
|
||||
BMenuItem* i;
|
||||
|
||||
int c = 1;
|
||||
m->AddItem(i = new BMenuItem("White",NULL));
|
||||
@@ -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,29 +156,29 @@ GLObject::Draw(bool forID, float IDcolor[])
|
||||
|
||||
if (forID) {
|
||||
glColor3fv(IDcolor);
|
||||
};
|
||||
}
|
||||
|
||||
DoDrawing(forID);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
changed = false;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
TriangleObject::TriangleObject(ObjectView *ov, char *filename)
|
||||
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;
|
||||
float maxp = 0;
|
||||
int numPt,numTri;
|
||||
|
||||
FILE *f = fopen(filename,"r");
|
||||
FILE* f = fopen(filename,"r");
|
||||
fscanf(f,"%d",&numPt);
|
||||
// printf("Points: %d\n",numPt);
|
||||
for (int i=0;i<numPt;i++) {
|
||||
for (int i = 0; i < numPt; i++) {
|
||||
point p;
|
||||
fscanf(f,"%f %f %f %f %f %f",
|
||||
&p.x,
|
||||
@@ -193,42 +193,43 @@ 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);
|
||||
int tpts=0;
|
||||
for (int i=0;i<numTri;i++) {
|
||||
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;
|
||||
};
|
||||
fTriangles.add(t);
|
||||
tpts += 3;
|
||||
}
|
||||
|
||||
int qpts=4;
|
||||
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;
|
||||
for (int i = 2; i < numTri; i += 2) {
|
||||
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;
|
||||
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);
|
||||
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++) {
|
||||
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
|
||||
for (int i = 0; i < fQs.num_items; i++) {
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (int j = 0; j < fQs[i].numpts; j++) {
|
||||
glNormal3f(
|
||||
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
|
||||
glVertex3f(
|
||||
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;
|
||||
glNormal3f(
|
||||
points[v1].nx,
|
||||
points[v1].ny,
|
||||
points[v1].nz
|
||||
glBegin(GL_TRIANGLES);
|
||||
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(
|
||||
fPoints[v1].nx,
|
||||
fPoints[v1].ny,
|
||||
fPoints[v1].nz
|
||||
);
|
||||
glVertex3f(
|
||||
fPoints[v1].x,
|
||||
fPoints[v1].y,
|
||||
fPoints[v1].z
|
||||
);
|
||||
glNormal3f(
|
||||
fPoints[v2].nx,
|
||||
fPoints[v2].ny,
|
||||
fPoints[v2].nz
|
||||
);
|
||||
glVertex3f(
|
||||
fPoints[v2].x,
|
||||
fPoints[v2].y,
|
||||
fPoints[v2].z
|
||||
);
|
||||
glNormal3f(
|
||||
fPoints[v3].nx,
|
||||
fPoints[v3].ny,
|
||||
fPoints[v3].nz
|
||||
);
|
||||
glVertex3f(
|
||||
points[v1].x,
|
||||
points[v1].y,
|
||||
points[v1].z
|
||||
fPoints[v3].x,
|
||||
fPoints[v3].y,
|
||||
fPoints[v3].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
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -26,32 +26,36 @@ struct quadStrip {
|
||||
|
||||
class GLObject {
|
||||
public:
|
||||
GLObject(ObjectView *ov);
|
||||
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 x,y,z;
|
||||
int color;
|
||||
float rotX, rotY, spinX, spinY;
|
||||
float x, y, z;
|
||||
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();
|
||||
|
||||
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
|
||||
|
||||
@@ -7,7 +7,8 @@ Application GLTeapot :
|
||||
GLObject.cpp
|
||||
ObjectView.cpp
|
||||
error.cpp
|
||||
teapot_main.cpp
|
||||
TeapotWindow.cpp
|
||||
TeapotApp.cpp
|
||||
: be GL game
|
||||
: GLTeapot.rdef
|
||||
;
|
||||
|
||||
+368
-317
@@ -34,7 +34,7 @@ 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;
|
||||
float* bgColor = black;
|
||||
|
||||
|
||||
struct light {
|
||||
@@ -54,16 +54,17 @@ light lights[] = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
long
|
||||
signalEvent(sem_id event)
|
||||
{
|
||||
long c;
|
||||
get_sem_count(event,&c);
|
||||
if (c<0)
|
||||
if (c < 0)
|
||||
release_sem_etc(event,-c,0);
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
@@ -71,11 +72,11 @@ setEvent(sem_id event)
|
||||
{
|
||||
long c;
|
||||
get_sem_count(event,&c);
|
||||
if (c<0)
|
||||
if (c < 0)
|
||||
release_sem_etc(event,-c,0);
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
@@ -85,17 +86,19 @@ waitEvent(sem_id event)
|
||||
|
||||
long c;
|
||||
get_sem_count(event,&c);
|
||||
if (c>0)
|
||||
if (c > 0)
|
||||
acquire_sem_etc(event,c,0,0);
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
simonThread(ObjectView *ov)
|
||||
static int32
|
||||
simonThread(void* cookie)
|
||||
{
|
||||
int noPause=0;
|
||||
ObjectView* ov = (ObjectView*)cookie;
|
||||
|
||||
int noPause = 0;
|
||||
while (acquire_sem_etc(ov->quittingSem,1,B_TIMEOUT,0) == B_NO_ERROR) {
|
||||
if (ov->SpinIt()) {
|
||||
ov->DrawFrame(noPause);
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
: 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)
|
||||
{
|
||||
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);
|
||||
sprintf(teapotPath,"%s/%s",findDir,teapotData);
|
||||
objListLock.Lock();
|
||||
objects.AddItem(new TriangleObject(this,teapotPath));
|
||||
objListLock.Unlock();
|
||||
};
|
||||
find_directory(B_BEOS_ETC_DIRECTORY, -1, true, findDir, PATH_MAX);
|
||||
sprintf(teapotPath, "%s/%s", findDir, teapotData);
|
||||
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
|
||||
@@ -225,120 +235,129 @@ ObjectView::DetachedFromWindow()
|
||||
BGLView::DetachedFromWindow();
|
||||
|
||||
long dummy;
|
||||
long locks=0;
|
||||
long locks = 0;
|
||||
|
||||
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
|
||||
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();
|
||||
};
|
||||
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)
|
||||
ObjectView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
BMenuItem *i;
|
||||
bool *b;
|
||||
// msg->PrintToStream();
|
||||
BMenuItem* i;
|
||||
bool* b;
|
||||
|
||||
switch (msg->what) {
|
||||
case bmsgFPS:
|
||||
fps = (fps)?false:true;
|
||||
msg->FindPointer("source", (void **)&i);
|
||||
i->SetMarked(fps);
|
||||
forceRedraw = true;
|
||||
fFps = (fFps) ? false : true;
|
||||
msg->FindPointer("source", (void**)&i);
|
||||
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:
|
||||
{
|
||||
msg->FindPointer("source",(void **)&i);
|
||||
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++) {
|
||||
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);
|
||||
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);
|
||||
};
|
||||
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
|
||||
@@ -348,107 +367,112 @@ ObjectView::ObjectAtPoint(BPoint p)
|
||||
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));
|
||||
glClearColor(black[0], black[1], black[2], 1.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++) {
|
||||
f[0] = (255-i)/255.0;
|
||||
((GLObject*)objects.ItemAt(i))->Draw(true, f);
|
||||
};
|
||||
for (int i = 0; i < fObjects.CountItems(); i++) {
|
||||
f[0] = (255 - i) / 255.0;
|
||||
((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;
|
||||
|
||||
objNum = 255 - objNum;
|
||||
|
||||
EnforceState();
|
||||
UnlockGL();
|
||||
|
||||
return objNum;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ObjectView::MouseDown(BPoint p)
|
||||
{
|
||||
BPoint op=p,np=p;
|
||||
BPoint op = p, np = p;
|
||||
BRect bounds = Bounds();
|
||||
float lastDx=0,lastDy=0;
|
||||
GLObject *o = NULL;
|
||||
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)));
|
||||
o = ((GLObject*)fObjects.ItemAt(ObjectAtPoint(p)));
|
||||
|
||||
long locks=0;
|
||||
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();
|
||||
};
|
||||
};
|
||||
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 (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)
|
||||
o->z += zinc;
|
||||
else
|
||||
o->y += yinc;
|
||||
op = np;
|
||||
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;
|
||||
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;
|
||||
};
|
||||
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;
|
||||
@@ -456,14 +480,14 @@ ObjectView::MouseDown(BPoint p)
|
||||
ConvertToScreen(&point);
|
||||
Window()->Unlock();
|
||||
o->MenuInvoked(point);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
while (locks--)
|
||||
Window()->Lock();
|
||||
|
||||
setEvent(drawEvent);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
@@ -471,39 +495,40 @@ ObjectView::FrameResized(float w, float h)
|
||||
{
|
||||
LockGL();
|
||||
|
||||
BGLView::FrameResized(w,h);
|
||||
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);
|
||||
fYxRatio = 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);
|
||||
};
|
||||
};
|
||||
float scale = displayScale;
|
||||
|
||||
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,66 +536,80 @@ 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);
|
||||
float scale = displayScale;
|
||||
|
||||
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);
|
||||
} else {
|
||||
glOrtho(-scale, scale, -scale*yxRatio, scale*yxRatio,
|
||||
-1.0, depthOfView*4);
|
||||
};
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
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) {
|
||||
glFogf(GL_FOG_START,10.0);
|
||||
glFogf(GL_FOG_DENSITY,0.2);
|
||||
glFogf(GL_FOG_END,depthOfView);
|
||||
glFogfv(GL_FOG_COLOR,foggy);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
}
|
||||
|
||||
if (fFog) {
|
||||
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);
|
||||
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0);
|
||||
} else {
|
||||
glDisable(GL_FOG);
|
||||
bgColor = black;
|
||||
glClearColor(bgColor[0],bgColor[1],bgColor[2], 1.0);
|
||||
};
|
||||
};
|
||||
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
@@ -578,149 +617,161 @@ 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) {
|
||||
LockGL();
|
||||
if (lighting) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
if (fLighting != fLastLighting) {
|
||||
LockGL();
|
||||
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) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
if (fFilled) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
} else {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
};
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
}
|
||||
UnlockGL();
|
||||
lastFilled = filled;
|
||||
fLastFilled = fFilled;
|
||||
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);
|
||||
}
|
||||
|
||||
if (fFog != fLastFog) {
|
||||
if (fFog) {
|
||||
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);
|
||||
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;
|
||||
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0);
|
||||
}
|
||||
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));
|
||||
if (o->solidity==0)
|
||||
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));
|
||||
if (o->solidity!=0)
|
||||
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;
|
||||
int e;
|
||||
if (histEntries < HISTSIZE) {
|
||||
e = (oldestEntry + histEntries)%HISTSIZE;
|
||||
histEntries++;
|
||||
} else {
|
||||
e = oldestEntry;
|
||||
oldestEntry = (oldestEntry+1)%HISTSIZE;
|
||||
};
|
||||
uint64 now = system_time();
|
||||
float f = 1.0 / ((now - fLastFrame) / 1000000.0);
|
||||
fLastFrame = now;
|
||||
int e;
|
||||
if (fHistEntries < HISTSIZE) {
|
||||
e = (fOldestEntry + fHistEntries) % HISTSIZE;
|
||||
fHistEntries++;
|
||||
} else {
|
||||
e = fOldestEntry;
|
||||
fOldestEntry = (fOldestEntry + 1) % HISTSIZE;
|
||||
}
|
||||
|
||||
fpsHistory[e] = f;
|
||||
fFpsHistory[e] = f;
|
||||
|
||||
if (histEntries > 5) {
|
||||
f = 0;
|
||||
for (int i=0;i<histEntries;i++)
|
||||
f += fpsHistory[(oldestEntry+i)%HISTSIZE];
|
||||
f = f/histEntries;
|
||||
if (fps) {
|
||||
if (fHistEntries > 5) {
|
||||
f = 0;
|
||||
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();
|
||||
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);
|
||||
|
||||
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();
|
||||
};
|
||||
};
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
histEntries = 0;
|
||||
oldestEntry = 0;
|
||||
};
|
||||
fHistEntries = 0;
|
||||
fOldestEntry = 0;
|
||||
}
|
||||
SwapBuffers();
|
||||
UnlockGL();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,12 +36,12 @@ 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);
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void FrameResized(float width, float height);
|
||||
@@ -51,31 +51,24 @@ class ObjectView : public BGLView {
|
||||
virtual void Pulse();
|
||||
void EnforceState();
|
||||
bool RepositionView();
|
||||
|
||||
|
||||
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,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);
|
||||
public:
|
||||
ResScroll(BRect r, const char* name,
|
||||
ObjectView* target, orientation posture);
|
||||
|
||||
virtual void ValueChanged(float value);
|
||||
|
||||
private:
|
||||
ObjectView* fObjectView;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // RESSCROLL_H
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -8,5 +8,5 @@
|
||||
void
|
||||
fatalerror(char *s)
|
||||
{
|
||||
printf("FATAL ERROR: %s\n",s);
|
||||
};
|
||||
printf("FATAL ERROR: %s\n",s);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+193
-132
@@ -11,21 +11,20 @@
|
||||
|
||||
template <class contents>
|
||||
struct LispNode {
|
||||
contents *car;
|
||||
LispNode *cdr;
|
||||
contents* car;
|
||||
LispNode* cdr;
|
||||
|
||||
/* Create a node with no next */
|
||||
inline LispNode(contents *value)
|
||||
: car(value), cdr(0) { }
|
||||
/* 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; }
|
||||
/* 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; }
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +32,6 @@ template <class contents>
|
||||
struct LispList {
|
||||
LispNode<contents> *first;
|
||||
|
||||
|
||||
/* -------- List creation --------------- */
|
||||
/* Create an empty list */
|
||||
inline LispList()
|
||||
@@ -41,57 +39,65 @@ struct LispList {
|
||||
first = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a list pointing to the specified node */
|
||||
inline LispList(LispNode<contents> *_first)
|
||||
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)
|
||||
inline int is_present(contents* element)
|
||||
{
|
||||
for (LispNode<contents> *node = first; node; node = node->cdr)
|
||||
for (LispNode<contents>* node = first; node; node = node->cdr)
|
||||
if (node->car == element)
|
||||
return 1;
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
inline void add(LispNode<contents>* new_element)
|
||||
{
|
||||
add_head (new_element);
|
||||
}
|
||||
|
||||
inline void add_tail(LispNode<contents> *new_element)
|
||||
|
||||
inline void add_tail(LispNode<contents>* new_element)
|
||||
{
|
||||
LispNode<contents>** pred = &first;
|
||||
while(*pred)
|
||||
@@ -100,123 +106,153 @@ 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)
|
||||
inline void add_head_new(contents* new_element)
|
||||
{
|
||||
first = new LispNode<contents>(new_element, first);
|
||||
}
|
||||
inline void add_head(contents *new_element)
|
||||
|
||||
|
||||
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)
|
||||
inline void add_tail_new(contents* new_element)
|
||||
{
|
||||
LispNode< contents > **pred = &first;
|
||||
LispNode< contents >** pred = &first;
|
||||
while (*pred)
|
||||
pred = &(*pred)->cdr;
|
||||
|
||||
*pred = new LispNode< contents >(new_element);
|
||||
}
|
||||
inline void add_tail(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);
|
||||
}
|
||||
/* Create new node pointing to thing, & add anywhere on list */
|
||||
inline void add_new(contents* new_element)
|
||||
{
|
||||
add_head_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() ); }
|
||||
inline void add(contents* new_element)
|
||||
{
|
||||
add_new(new_element);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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 & delete all nodes pointing to a particular element. */
|
||||
inline void rem_del (contents *element)
|
||||
{
|
||||
LispNode<contents> **pp = &first;
|
||||
while (*pp)
|
||||
{
|
||||
if ((*pp)->car == element)
|
||||
{
|
||||
|
||||
/* 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
|
||||
} 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 ); }
|
||||
/* Remove and delete all nodes on the list. */
|
||||
inline void rem_del_all()
|
||||
{
|
||||
while (first) {
|
||||
LispNode<contents>* old = first;
|
||||
first = first->cdr;
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 ); }
|
||||
/* -------- 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 */
|
||||
@@ -237,7 +273,7 @@ struct LispList {
|
||||
#endif
|
||||
|
||||
/* Take the first thing off the list */
|
||||
inline contents *get_head()
|
||||
inline contents* get_head()
|
||||
{
|
||||
contents *c = 0;
|
||||
if(first) {
|
||||
@@ -247,23 +283,26 @@ struct LispList {
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* Take something off the list */
|
||||
inline contents *get()
|
||||
inline contents* get()
|
||||
{
|
||||
return(get_head());
|
||||
}
|
||||
|
||||
|
||||
/* XXX inline contents *get_tail() { } */
|
||||
|
||||
/* -------- Stack simulation (by j.h.) ------------ */
|
||||
/* -------- Stack simulation (by j.h.) ------------ */
|
||||
/* Put a thing onto the head of the list */
|
||||
inline void push(contents *c)
|
||||
inline void push(contents* c)
|
||||
{
|
||||
put_head(c);
|
||||
}
|
||||
|
||||
|
||||
/* Remove a thing from the head of the list */
|
||||
inline contents *pop()
|
||||
inline contents* pop()
|
||||
{
|
||||
return(get_head());
|
||||
}
|
||||
@@ -275,24 +314,28 @@ struct LispList {
|
||||
}
|
||||
|
||||
|
||||
/* ----------- list/list manipulations ------------ */
|
||||
/* ----------- 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)
|
||||
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)
|
||||
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)
|
||||
for (LispNode<contents>* n = other.first; n; n = n->cdr)
|
||||
rem_del(n->car);
|
||||
}
|
||||
};
|
||||
@@ -300,52 +343,64 @@ struct LispList {
|
||||
template <class thetype>
|
||||
struct DoubleLinkedNode
|
||||
{
|
||||
thetype *next,*prev;
|
||||
thetype* next;
|
||||
thetype* prev;
|
||||
|
||||
DoubleLinkedNode() { next = prev = NULL; };
|
||||
|
||||
void insert_after(thetype *n)
|
||||
DoubleLinkedNode()
|
||||
{
|
||||
next = prev = NULL;
|
||||
}
|
||||
|
||||
|
||||
void insert_after(thetype* n)
|
||||
{
|
||||
if (next != NULL)
|
||||
next->prev = n;
|
||||
next->prev = n;
|
||||
|
||||
n->next = next;
|
||||
n->prev = (thetype*)this;
|
||||
next = n;
|
||||
};
|
||||
}
|
||||
|
||||
void insert_before(thetype *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;
|
||||
};
|
||||
next->prev = prev;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class thetype>
|
||||
struct DoubleLinkedList : public DoubleLinkedNode<thetype>
|
||||
{
|
||||
DoubleLinkedList() : DoubleLinkedNode<thetype>() {};
|
||||
|
||||
void insert(thetype *n)
|
||||
void insert(thetype* n)
|
||||
{
|
||||
insert_after(n);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void add(thetype *n)
|
||||
void add(thetype* n)
|
||||
{
|
||||
insert_after(n);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct BufferArray {
|
||||
T * items;
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user