I figure this is a tad more difficult than a beginners approach so I posted in the advanced section…
I am currently using glRotate shudders to try and place an object (more a billboard) of a tree on the surface of a sphere…I tried using the normals that I calculated and those didnt give accurate results…or I was going about it all wrong…Currently I am using something along these lines…
angleX1 = RADTODEG(double(j) * PI / (double(n)/2));
angleX2 = RADTODEG(double(j+1) * PI / (double(n)/2));
angleY1 = RADTODEG(double(i) * TWOPI / double(n))-90;
angleY2 = RADTODEG(double(i+1) * TWOPI / double(n))-90;
I split my array build up with two for loops i and j in the update and in the render output it obviously…The actual terrain, texturing and normals are all correct but the objects when placed offset one of the x, y or z planes start to lean dramatically the further away from each of these planes…I suppose glRotate is the problem and I should possibly build a vertex buffer of billboards instead of a single display list or static vertex buffer rotated each time?
The actual class in its entirety is as listed below:
</font><blockquote><font size=“1” face=“Verdana, Arial”>code:</font><hr /><pre style=“font-size:x-small; font-family: monospace;”>#include “sphere.h”
#include “stellartrader.h”
#include “gl_graph.h”
#include “perlin.h”
char debugText[255];
float obj_billboard_norm[12][3] = {0.7071, 0.0000, 0.7071,
0.7071, 0.0000, 0.7071,0.7071, 0.0000, 0.7071,
0.7071, 0.0000, 0.7071,0.7071, 0.0000, 0.7071,
0.7071, 0.0000, 0.7071,-0.7071, 0.0000, 0.7071,
-0.7071, 0.0000, 0.7071,-0.7071, 0.0000, 0.7071,
-0.7071, 0.0000, 0.7071,-0.7071, 0.0000, 0.7071,
-0.7071, 0.0000, 0.7071};
float obj_billboard_vert[12][3] = {-0.3536, 1.0000, 0.3536,
-0.3536, 0.0000, 0.3536,0.3536, 1.0000, -0.3536,
0.3536, 0.0000, -0.3536,0.3536, 1.0000, -0.3536,
-0.3536, 0.0000, 0.3536,-0.3536, 1.0000, -0.3536,
-0.3536, 0.0000, -0.3536,0.3536, 1.0000, 0.3536,
0.3536, 0.0000, 0.3536,0.3536, 1.0000, 0.3536,
-0.3536, 0.0000, -0.3536};
float obj_billboard_tex[12][3] = {0.9995, 0.9995,
0.9995, 0.0005,0.0005, 0.9995,
0.0005, 0.0005,0.0005, 0.9995,
0.9995, 0.0005,0.0000, 1.0000,
0.0000, 0.0000,1.0000, 1.0000,
1.0000, 0.0000,1.0000, 1.0000,
0.0000, 0.0000};
Sphere::Sphere(int n, int bwidth, int bheight) {
normals.reserve(n * n * 4);
texes.reserve(n * n * 4);
verts.reserve(n * n * 4);
colors.reserve(n * n * 4);
objnormals.reserve(n * n * 4);
objverts.reserve(n * n * 4);
buffer.reserve((bwidth+1) * (bheight+1) * 4);
l_buffer.reserve((bwidth+1) * (bheight+1) * 4);
bufferWidth = bwidth;
bufferHeight = bheight;
maxSlices = n;
numVerts = 0;
vertCount = 0;
hi = 0;
lo = 10000;
}
Sphere::~Sphere() {
}
void Sphere::assignBuffer(unsigned char b, unsigned char l, int bwidth, int bheight, double bump) {
for(int i=0;i<bufferWidthbufferHeight3;i++) {
buffer[i] = b[i];
l_buffer[i] = l[i];
}
bufferWidth = bwidth;
bufferHeight = bheight;
bumpHeight = bump;
}
Vec3d Sphere::CalculateNormals(Vec3d v1, Vec3d v2, Vec3d v3)
{
// Reduce each vert’s normal to unit
float length;
float u[3], v[3];
Vec3d unit;
// V2 - V3;
u[0] = v2.x - v3.x;
u[1] = v2.y - v3.y;
u[2] = v2.z - v3.z;
// V2 - V1;
v[0] = v2.x - v1.x;
v[1] = v2.y - v1.y;
v[2] = v2.z - v1.z;
unit.x = (u[1]*v[2] - u[2]*v[1]);
unit.y = (u[2]*v[0] - u[0]*v[2]);
unit.z = (u[0]*v[1] - u[1]*v[0]);
length = (double)sqrt((unit.x*unit.x) + (unit.y*unit.y) + (unit.z*unit.z));
if (length == 0.0f)
length = 1.0f;
unit.x /= length;
unit.y /= length;
unit.z /= length;
return unit;
}
void Sphere::setScale(double scale) {
scaleSet = scale;
}
double Sphere::getHi() {
return hi;
}
double Sphere::getLo() {
return lo;
}
Vec2f Sphere::getSphereEyeCoord(Vec3d pos, Vec3d cam) {
Vec2f coord;
double x,y,z;
coord.x = PI + (atan2(pos.z - cam.z,pos.x - cam.x));
x = pos.x - cam.x;
y = pos.y - cam.y;
z = pos.z - cam.z;
coord.y = -(PI * 0.5f - atan2(sqrt(x*x+z*z),y));
return coord;
}
void Sphere::Update(Vec3d pos, Vec3d cam, double r,int n, bool useClip, bool useArea, bool useHeight)
{
int i,j,index = 0;
double theta1,theta2,theta3;
double angleX1, angleX2, angleY1, angleY2;
double u, v, height;
double hu, hv;
double per;
double part;
float slice, restslice;
int objindex = 0, objinc = 0;
Vec3d e,p;
Vec2d lalpha;
// take horizontal camera - 90 degrees = center on closest vert;
if(n > maxSlices) n = maxSlices;
slices = n;
radius = r;
if (r < 0)
r = -r;
if (n < 0)
n = -n;
eyeSphere = getSphereEyeCoord(pos,cam);
for (j=0;j<n/2;j++) { // rotate X for objects
if(useArea)
part = FABS((j / (n/2)) - 0.5) * 0.1;
else
part = 0.1;
theta1 = double(j) * TWOPI / double(n) - PIDIV2; // vertical shift
theta2 = (double(j) + 1) * TWOPI / double(n) - PIDIV2;
slice = CLAMP(FABS(eyeSphere.y) * 0.25f * part * 10,0.1,1);
if(theta1 > eyeSphere.y - PI * part && theta1 < eyeSphere.y + PI * part