01-20-2014, 08:07 PM
Wondering if any of you who are graphics whizzes on the Prime know how to implement a spherical mesh generator?
I tried to make a PPL version of the classical icosahedron mesh but the depth of recursion appears to flummox the prime. Here's the original OpenGL/C version that can be found in the redbook and other places:
I'm assuming that the glNormal3fv calls can be converted to TRIANGLE calls on the Prime (although shading doesn't appear to be supported). But the program never gets that far -- it hangs somewhere in the drawtri recursion for values of "div" > 2 or 3.
Converted to PPL the equivalent of the above code would be
It seems likely that I've botched the TRIANGLE command since I've never used it but, again, things seem to go bad before that point. BTW, the above is only a fragment. If you want to try it you'll need to embed it in a more complete program like Han's Graph3D.
Suggestions welcome. Or is this just beyond what we can expect the Prime to do at this point?
I tried to make a PPL version of the classical icosahedron mesh but the depth of recursion appears to flummox the prime. Here's the original OpenGL/C version that can be found in the redbook and other places:
Code:
//
// sphereMesh.c
//
// draws a sphercial mesh
//
#include <stdio.h>
#include <math.h>
#if !defined(__GLU_H__)
#if defined(WIN32)
#include <windows.h>
#include <GL/glu.h>
#elif defined(__MACH__)
#include <OpenGL/glu.h>
#else
#include <GL/glu.h>
#endif
#endif // !__GL_H__
#define X .525731112119133606
#define Z .850650808352039932
static GLfloat vdata[12][3] = {
{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
{0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
{Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};
static GLuint tindices[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
void normalize(GLfloat *a) {
GLfloat d=sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
a[0]/=d; a[1]/=d; a[2]/=d;
}
void drawtri(GLfloat *a, GLfloat *b, GLfloat *c, int div, float r) {
if (div<=0) {
glNormal3fv(a); glVertex3f(a[0]*r, a[1]*r, a[2]*r);
glNormal3fv(b); glVertex3f(b[0]*r, b[1]*r, b[2]*r);
glNormal3fv(c); glVertex3f(c[0]*r, c[1]*r, c[2]*r);
} else {
GLfloat ab[3], ac[3], bc[3];
for (int i=0;i<3;i++) {
ab[i]=(a[i]+b[i])/2;
ac[i]=(a[i]+c[i])/2;
bc[i]=(b[i]+c[i])/2;
}
normalize(ab); normalize(ac); normalize(bc);
drawtri(a, ab, ac, div-1, r);
drawtri(b, bc, ab, div-1, r);
drawtri(c, ac, bc, div-1, r);
drawtri(ab, bc, ac, div-1, r); //<--Comment this line and sphere looks really cool!
}
}
void drawsphere(int ndiv, float radius) {
glBegin(GL_TRIANGLES);
for (int i=0;i<20;i++)
drawtri(vdata[tindices[i][0]], vdata[tindices[i][1]], vdata[tindices[i][2]], ndiv, radius);
glEnd();
}
I'm assuming that the glNormal3fv calls can be converted to TRIANGLE calls on the Prime (although shading doesn't appear to be supported). But the program never gets that far -- it hangs somewhere in the drawtri recursion for values of "div" > 2 or 3.
Converted to PPL the equivalent of the above code would be
Code:
XX=.525731112119133606;
ZZ=.850650808352039932;
vdata={
{-XX, 0.0, ZZ}, {XX, 0.0, ZZ}, {-XX, 0.0, -ZZ}, {XX, 0.0, -ZZ},
{0.0, ZZ, XX}, {0.0, ZZ, -XX}, {0.0, -ZZ, XX}, {0.0, -ZZ, -XX},
{ZZ, XX, 0.0}, {-ZZ, XX, 0.0}, {ZZ, -XX, 0.0}, {-ZZ, -XX, 0.0}
};
tindices = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
drawSphere()
begin
local i,radius=50,ndiv=12;
local white;
white:=rgb(255,255,255);
dimgrob_p(G1,320,240,white);
for i from 1 to 20 do
drawtri(vdata(tindices(i,1)+1),
vdata(tindices(i,2)+1),
vdata(tindices(i,3)+1),ndiv,radius);
end;
blit_p(G0,G1);
end;
normalize(aa)
begin
local dd;
dd:=sqrt(aa(1)*aa(1)+aa(2)*aa(2)+aa(3)*aa(3));
aa(1):=aa(1)/dd; aa(2):=aa(2)/dd; aa(3):=aa(3)/dd;
return aa;
end;
drawtri(aa,bb,cc,div,r)
begin
local ab={},ac={},bc={};
local grey,i;
grey:=rgb(25,25,25);
if div <= 0 then
triangle_p(G1,{aa(1),aa(2),grey,aa(3)},{bb(1),bb(2),grey,bb(3)},{cc(1),cc(2),grey,cc(3)});
else
for i from 1 to 3 do
ab(i):=(aa(i)+bb(i))/2;
ac(i):=(aa(i)+cc(i))/2;
bc(i):=(bb(i)+cc(i))/2;
end;
ab:=normalize(ab);
ac:=normalize(ac);
bc:=normalize(bc);
drawtri(aa,ab,ac,div-1,r);
drawtri(bb,bc,ab,div-1,r);
drawtri(cc,ac,bc,div-1,r);
drawtri(ab,bc,ac,div-1,r);
end;
end;
It seems likely that I've botched the TRIANGLE command since I've never used it but, again, things seem to go bad before that point. BTW, the above is only a fragment. If you want to try it you'll need to embed it in a more complete program like Han's Graph3D.
Suggestions welcome. Or is this just beyond what we can expect the Prime to do at this point?