I'd like to create a circular rotation for the rays around the sun.
to make it look like this
How I draw curves on the canvas.
GLfloat ctrlpoints[4][3];
void drawCurves(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4) {
ctrlpoints[0][0]=x1;
ctrlpoints[0][1]=y1;
ctrlpoints[0][2]=50.0f;
ctrlpoints[1][0]=x2;
ctrlpoints[1][1]=y2;
ctrlpoints[1][2]=50.0f;
ctrlpoints[2][0]=x3;
ctrlpoints[2][1]=y3;
ctrlpoints[2][2]=50.0f;
ctrlpoints[3][0]=x4;
ctrlpoints[3][1]=y4;
ctrlpoints[3][2]=50.0f;
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
int i;
glLineWidth(3.0f);
//glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
}
How Rays are made.
void Ray (float x, float y, float s){
glColor3f(1, 1, 0);
drawCurves(x, y, x+4*s, y-7*s, x-6*s, y-27*s, x-3*s, y-30*s);
glColor3f(1, 1, 0);
drawCurves(x, y, x+7*s, y-7*s, x+1*s, y-27*s, x+4*s, y-30*s);
}
How I design the sun motive.
void Rays(float x, float y, float radius, int num_segments){
float i;
double twicePi = 2.0 * 3.142;
for (i = 0; i <= num_segments; i++) {
Ray((x+ (radius * cos((i * twicePi / num_segments))))
,(y + (radius * sin((i * twicePi / num_segments))))
,0.3);
}
}
Tried glRotation but it rotates the whole flag, I just want to rotate the rays.
You have to caluclate the direction of the ray and you have to set up the points of the curves in the direction of the ray. In computer graphics rotations are commonly calculated by matrices. But since this is a simple 2D graphic, and you have already written most of the code, the computation can be done without matrices.
You have to calculate the direction of the ray and the counterclockwise rotated orthonormal direction. This 2 directions ar the local x-axis and local y-axis of the geometry of single ray. The coordinates of the curves of a ray must be plotted along this axis.
void Rays(float x, float y, float radius, int num_segments)
{
const float twicePi = 2.0f * 3.141593f;
for (int i = 0; i <= num_segments; ++i)
{
float angle = (float)i * twicePi / num_segments;
float dir_x = sin( angle );
float dir_y = cos( angle );
Ray( dir_x, dir_y, radius, 0.3 );
}
}
float dot( float a[], float b[2] )
{
return a[0]*b[0] + a[1]*b[1];
}
void Ray ( float xx, float xy, float r, float l)
{
float yx = -xy, yy = xx; // (xx, xy) counterclockwise rotated = (-xy, xx)
float xc[]{ xx, yx };
float yc[]{ xy, yy };
float p0[]{ xx * r, xy * r };
float p1[]{ -7.0f * s, 4.0f * s };
float p2[]{ -27.0f * s, -6.0f * s };
float p3[]{ -30.0f * s, -3.0f * s };
float p4[]{ -7.0f * s, 7.0f * s };
float p5[]{ -27.0f * s, 1.0f * s };
float p6[]{ -30.0f * s, 4.0f * s };
glColor3f(1, 1, 0);
drawCurves(
p0[0], p0[1],
p0[0] + dot(xc, p1[0]), p0[1] + dot(yc, p1[1]),
p0[0] + dot(xc, p2[0]), p0[1] + dot(yc, p2[1]),
p0[0] + dot(xc, p3[0]), p0[1] + dot(yc, p3[1]) );
drawCurves(
p0[0], p0[1],
p0[0] + dot(xc, p4[0]), p0[1] + dot(yc, p4[1]),
p0[0] + dot(xc, p5[0]), p0[1] + dot(yc, p5[1]),
p0[0] + dot(xc, p6[0]), p0[1] + dot(yc, p6[1]) );
}
Related
I want to rotate a point in OpenGL around an arbitrary axis. I want to utilize that to rotate a sphere.
This is what I got so far:
float degreeBetweenTwoVec(glm::vec3 &a, glm::vec3 b)
{
float prod = b.x * a.x + b.y * a.y + b.z * a.z;
float mag_axis = sqrt((b.x * b.x) + (b.y * b.y) + (b.z * b.z));
float mag_vec = sqrt((a.x * a.x) + (a.y * a.y) + (a.z * a.z));
float degree = prod / (mag_axis * mag_vec);
return acos(degree) * 180.0 / PI;;
}
void rotAroundZ(glm::vec3 &point, float degree)
{
glm::vec3 n_point;
n_point.x = (point.x * cos(degree * PI / 180.0)) - (point.y * sin(degree * PI / 180.0));
n_point.y = (point.x * sin(degree * PI / 180.0)) + (point.y * cos(degree * PI / 180.0));
n_point.z = point.z;
point.x = n_point.x;
point.y = n_point.y;
point.z = n_point.z;
}
void rotAroundY(glm::vec3& point, float degree)
{
glm::vec3 n_point;
n_point.x = (point.x * cos(degree * PI / 180.0)) + (point.z * sin(degree * PI / 180.0));
n_point.y = point.y;
n_point.z = ((point.x * -1.0f) * sin(degree * PI / 180.0)) + (point.z * cos(degree * PI / 180.0));;
point.x = n_point.x;
point.y = n_point.y;
point.z = n_point.z;
}
void rotAroundA(glm::vec3& point, glm::vec3 &axis, float zdegree)
{
float xdegree = degreeBetweenTwoVec(axis, glm::vec3{ 1.0f, 0.0f, 0.0f });
float ydegree = degreeBetweenTwoVec(axis, glm::vec3{ 0.0f, 1.0f, 0.0f });
rotAroundZ(point, xdegree);
rotAroundY(point, ydegree);
rotAroundZ(point, zdegree);
rotAroundY(point, -ydegree);
rotAroundZ(point, -xdegree);
}
void rotAObject(Object& obj, glm::vec3 &axis, float degree)
{
axis = glm::normalize(axis);
translate(axis, glm::vec3{ axis.x, axis.y, axis.z });
for (int i = 0; i < obj.vertices.size(); i++)
{
rotAroundA(obj.vertices[i], axis, degree);
}
rotAroundA(obj.mp, axis, degree);
translate(axis, glm::vec3{ axis.x * -1.0f, axis.y * -1.0f, axis.z * -1.0f });
}
This works just fine if the given axis happens to be on one of the global axis. However, if it isn't and the given axis is basiclly rotating around something else. There is some kind of axis it is rotating around but as soon as change the given axis, for example rotating it around the z axis it rotates around a completlly different axis than before. It looks like for every position the given axis can take there is some other axis the object is actually rotating around.
Any help is appreciated!
I recommend to use a rotation matrix. Use glm::rotate(), to set a rotation matrix by axis and angle.
Convert the point to glm::vec4 and transform it by the rotation matrix:
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
glm::mat4 rot_mat = glm::rotate(glm::mat4(1.0f), glm::radians(degree), axis);
glm::vec3 n_point = glm::vec3(glm::vec4(point, 1.0f) * rot_mat);
I am facing problems trying to make 3d objects clickable by mouse. For intersection checking I use ray casting. Code I found, ported for my solution:
Exactly picking
bool RaySphereIntersect(Vector3, Vector3, float);
bool TestIntersection(Matrix projectionMatrix, Matrix viewMatrix, Matrix worldMatrix, Vector3 origin, float radius, int m_screenWidth, int m_screenHeight, int mouseX, int mouseY)
{
float pointX, pointY;
Matrix inverseViewMatrix, translateMatrix, inverseWorldMatrix;
Vector3 direction, rayOrigin, rayDirection;
bool intersect, result;
// Move the mouse cursor coordinates into the -1 to +1 range.
pointX = ((2.0f * (float)mouseX) / (float)m_screenWidth) - 1.0f;
pointY = (((2.0f * (float)mouseY) / (float)m_screenHeight) - 1.0f) * -1.0f;
// Adjust the points using the projection matrix to account for the aspect ratio of the viewport.
pointX = pointX / projectionMatrix._11;
pointY = pointY / projectionMatrix._22;
// Get the inverse of the view matrix.
inverseViewMatrix=XMMatrixInverse(NULL, viewMatrix);
// Calculate the direction of the picking ray in view space.
direction.x = (pointX * inverseViewMatrix._11) + (pointY * inverseViewMatrix._21) + inverseViewMatrix._31;
direction.y = (pointX * inverseViewMatrix._12) + (pointY * inverseViewMatrix._22) + inverseViewMatrix._32;
direction.z = (pointX * inverseViewMatrix._13) + (pointY * inverseViewMatrix._23) + inverseViewMatrix._33;
// Get the origin of the picking ray which is the position of the camera.
// Get the world matrix and translate to the location of the sphere.
// Now get the inverse of the translated world matrix.
inverseWorldMatrix= XMMatrixInverse(NULL, worldMatrix);
// Now transform the ray origin and the ray direction from view space to world space.
rayOrigin=XMVector3TransformCoord(origin, inverseWorldMatrix);
rayDirection=XMVector3TransformNormal(direction, inverseWorldMatrix);
// Normalize the ray direction.
rayDirection=XMVector3Normalize(rayDirection);
// Now perform the ray-sphere intersection test.
intersect = RaySphereIntersect(rayOrigin, rayDirection, radius);
if (intersect == true)
return true;
else
return false;
}
bool RaySphereIntersect(Vector3 rayOrigin, Vector3 rayDirection, float radius)
{
float a, b, c, discriminant;
// Calculate the a, b, and c coefficients.
a = (rayDirection.x * rayDirection.x) + (rayDirection.y * rayDirection.y) + (rayDirection.z * rayDirection.z);
b = ((rayDirection.x * rayOrigin.x) + (rayDirection.y * rayOrigin.y) + (rayDirection.z * rayOrigin.z)) * 2.0f;
c = ((rayOrigin.x * rayOrigin.x) + (rayOrigin.y * rayOrigin.y) + (rayOrigin.z * rayOrigin.z)) - (radius * radius);
// Find the discriminant.
discriminant = (b * b) - (4 * a * c);
// if discriminant is negative the picking ray missed the sphere, otherwise it intersected the sphere.
if (discriminant < 0.0f)
return false;
else
return true;
}
How do I create sphere
D3DSphere(float x, float y, float z, float radius, float r, float g, float b, float a)
{
this->x = x;
this->y = y;
this->z = z;
this->radius = radius;
this->shape = GeometricPrimitive::CreateSphere(radius*2.0f);
this->world = Matrix::Identity;
this->world = XMMatrixMultiply(this->world, Matrix::CreateTranslation(x, y, z));
this->index = vsphere;
d3dsphere[vsphere] = this;
vsphere++;
}
How do I call raycaster
void Game::LButtonUp(int x, int y)
{
Vector3 eye(camx, camy, camz);
Vector3 at(Vector3::Zero);
m_view = Matrix::CreateLookAt(eye, at, Vector3::UnitY);
for (int i = 0; i < vsphere; i++)
{
if (TestIntersection(m_projection, m_view, d3dsphere[i]->world, eye, d3dsphere[i]->radius, 800, 600, x, y))
{
MessageBoxW(NULL, L"LOL", L"It works", MB_OK);
break;
}
}
}
Nothing happens by clicking, but if I rotate camera, perpendicularly to XOY, sometimes, clicking near the sphere, message box appears.
Update
MessageBox appears independently on camera angle, and it seems, that it detects intersection correctly, but mirrored, relatively to the window center. For example, if sphere is at (0, window.bottom-20) point then I will get MessageBox if I click at (0, 20) point.
What if calculation of the direction of the picking ray is wrong, if it was wrote for left-handed system, and I use right-handed?
Probably, because of the right-handed system, that is used by default in DirectX Tool Kit the next section from caster
pointX = ((2.0f * (float)mouseX) / (float)m_screenWidth) - 1.0f;
pointY = (((2.0f * (float)mouseY) / (float)m_screenHeight) - 1.0f) * -1.0f;
Should be changed to
pointX = (((2.0f * (float)mouseX) / (float)m_screenWidth) - 1.0f) * -1.0f;
pointY = (((2.0f * (float)mouseY) / (float)m_screenHeight) - 1.0f);
Important
That code also will work wrong because of depth independence, i.e. you may select sphere that is situated behind the sphere you clicking. For solve that I changed the code:
float distance3(float x1, float y1, float z1, float x2, float y2, float z2)
{
float dx=x1-x2;
float dy=y1-y2;
float dz=z1-z2;
return sqrt(dx*dx+dy*dy+dz*dz);
}
void Game::LButtonUp(int x, int y)
{
Vector3 eye(camx, camy, camz);
Vector3 at(Vector3::Zero);
m_view = Matrix::CreateLookAt(eye, at, Vector3::UnitY);
int last_index=-1;
float last_distance=99999.0f;//set the obviously highest value, may happen in your scene
for (int i = 0; i < vsphere; i++)
{
if (TestIntersection(m_projection, m_view, d3dsphere[i]->world, eye, d3dsphere[i]->radius, 800, 600, x, y))
{
float distance=distance3(camx,camy,camz, d3dsphere[i]->x, d3dsphere[i]->y, d3dsphere[i]->z);
if(distance<last_distance)
{
last_distance=distance;
last_index=i;
}
}
}
d3dsphere[last_index];//picked sphere
}
I am trying to display a 360 panorama using an IMU for head tracking.
Yaw works correctly but the roll and pitch are reverse. I also notice that the pitch contains some roll (and maybe vice-versa).
I am receiving (W, X, Y, Z) coordinate from the IMU that I am storing in an array as X, Y, Z, W.
The next step is converting the quaternion to a rotation matrix. I have looked at many examples, and can't seem to find anything wrong with the following code:
static GLfloat rotation[16];
// Quaternion (x, y, z, w)
static void quaternionToRotation(float* quaternion)
{
// Normalize quaternion
float magnitude = sqrt(quaternion[0] * quaternion[0] +
quaternion[1] * quaternion[1] +
quaternion[2] * quaternion[2] +
quaternion[3] * quaternion[3]);
for (int i = 0; i < 4; ++i)
{
quaternion[i] /= magnitude;
}
double xx = quaternion[0] * quaternion[0], xy = quaternion[0] * quaternion[1],
xz = quaternion[0] * quaternion[2], xw = quaternion[0] * quaternion[3];
double yy = quaternion[1] * quaternion[1], yz = quaternion[1] * quaternion[2],
yw = quaternion[1] * quaternion[3];
double zz = quaternion[2] * quaternion[2], zw = quaternion[2] * quaternion[3];
// Column major order
rotation[0] = 1.0f - 2.0f * (yy + zz);
rotation[1] = 2.0f * (xy - zw);
rotation[2] = 2.0f * (xz + yw);
rotation[3] = 0;
rotation[4] = 2.0f * (xy + zw);
rotation[5] = 1.0f - 2.0f * (xx + zz);
rotation[6] = 2.0f * (yz - xw);
rotation[7] = 0;
rotation[8] = 2.0f * (xz - yw);
rotation[9] = 2.0f * (yz + xw);
rotation[10] = 1.0f - 2.0f * (xx + yy);
rotation[11] = 0;
rotation[12] = 0;
rotation[13] = 0;
rotation[14] = 0;
rotation[15] = 1;
}
The rotation matrix is then used in the draw call as such:
static void draw()
{
// Get IMU quaternion
float* quaternion = tracker.getTrackingData();
if (quaternion != NULL)
{
quaternionToRotation(quaternion);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
// TODO: Multiply initialRotation quaternion with IMU quaternion
glMultMatrixf(initialRotation); // Initial rotation to point forward
glMultMatrixf(rotation); // Rotation based on IMU
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
gluSphere(quad, 0.1, 50, 50);
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
glFlush();
glutSwapBuffers();
}
I tried to set all but one fields in the quaternion to 0, and I notice that they all work individually, except roll and pitch is swapped around. I tried swapping X and Y but this does not seem to help.
Any help would be really appreciated. Please let me know as well if you have any steps that can let me debug my issue. Thanks!
I am trying to map a texture to a circle using GL_POLYGON using this code:
void drawCircleOutline(Circle c, int textureindex)
{
float angle, radian, x, y; // values needed by drawCircleOutline
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureLib[textureindex]);
glBegin(GL_POLYGON);
for (angle=0.0; angle<360.0; angle+=2.0)
{
radian = angle * (pi/180.0f);
x = (float)cos(radian) * c.r + c.pos.x;
y = (float)sin(radian) * c.r + c.pos.y;
glTexCoord2f(x, y);
glVertex2f(x, y);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
it looks like this when running.
And should look like this:
Try:
radian = angle * (pi/180.0f);
xcos = (float)cos(radian);
ysin = (float)sin(radian);
x = xcos * c.r + c.pos.x;
y = ysin * c.r + c.pos.y;
tx = xcos * 0.5 + 0.5;
ty = ysin * 0.5 + 0.5;
glTexCoord2f(tx, ty);
glVertex2f(x, y);
i want to make a sphere and put a camera which focuses at the center ,having a vector (VUP=0,1,0).I want to alter the spherical coordinates r,theta,phi.
The problem is that when i run the application,the sphere appears but when i press a key it disappears.
If i delete the glMatrixMode(GL_PROJECTION) from the setupmywindow,then at the beginning the sphere doesn't appear ,but if i press a key it appears.Then , bu pressing "r" and "p" ,it changes its radius but pressing "u" and "f" it rotates only one step.
#define PI 3.1415f
float theta = 0, phi = 0, dtheta = PI / 20, dphi = PI / 20;
float r = 0.2;
void setupmywindow()
{
glClearColor(1.0,1.0,1.0,0);
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glMatrixMode(GL_PROJECTION);
gluPerspective(30,1,2,100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
void myaxes(double size)
{
glBegin(GL_LINES);
glColor3f(0,0,0);glVertex3f(0,0,0); glColor3f(1,0,0);glVertex3f(size,0,0); //x-axis
glColor3f(0,0,0);glVertex3f(0,0,0); glColor3f(0,1,0);glVertex3f(0,size,0); //y-axis
glColor3f(0,0,0);glVertex3f(0,0,0); glColor3f(0,0,1);glVertex3f(0,0,size); //z-axis
glEnd();
}
void sphere()
{
float z1, x1, y1, z2, x2, y2, z3, x3, y3, z4, x4, y4;
float angle = 0,translate;
glTranslatef(0.0,0.0,translate);
angle++;
glRotatef(angle, 1.0, 1.0, 1.0);
glBegin(GL_QUAD_STRIP);
for(theta=0;theta<=2.0*PI;theta+=dtheta)
{
for(phi=0;phi<=PI;phi+=dphi)
{
z1 = r * sin(phi + dphi) * cos(theta + dtheta);
x1 = r * sin(phi + dphi) * sin(theta + dtheta);
y1 = r * cos(phi + dphi);
z2 = r * sin(phi) * cos(theta + dtheta);
x2 = r * sin(phi) * sin(theta + dtheta);
y2 = r * cos(phi);
z3 = r * sin(phi) * cos(theta);
x3 = r * sin(phi) * sin(theta);
y3 = r * cos(phi);
z4 = r * sin(phi + dphi) * cos(theta);
x4 = r * sin(phi + dphi) * sin(theta);
y4 = r * cos(phi + dphi);
glColor3f(1,0,0);
glVertex3f(x4, y4, z4);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
}
}
glEnd();
}
void myDrawing()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(r,theta,phi,0,0,0,0,1,0);
sphere();
myaxes(1.5);
glutSwapBuffers();
}
void mykeyboardcontrol(unsigned char key, int x, int y)
{
switch(key){
case 'r': r+=0.1;break; //increase radius
case 'p': r-=0.1;break; //decrease radius
case 'u': theta+=PI/20;break;//increase theta angle
case 'f': phi+=PI/20;break;//increase phi angle
}
printf("r=%f theta=%f phi=%f\n",r,theta,phi);
if(key==27) exit(0);
if(theta>2*PI) theta-=2*PI;
if(phi>PI) phi-=PI;
printf("r=%f theta=%f phi=%f\n",r,theta,phi);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutCreateWindow("Sphere");
setupmywindow();
glutDisplayFunc(myDrawing);
glutKeyboardFunc(mykeyboardcontrol);
glutMainLoop();
}
Here you go:
#include <GL/glut.h>
#include <cmath>
#include <cstdlib>
#include <cstdio>
const float PI = 3.14159f;
float camera_theta = 2.042033;
float camera_phi = 8.639376;
float camera_r = 15;
double aspect_ratio = 0;
void reshape(int w, int h)
{
aspect_ratio = (double)w / (double)h;
glViewport(0, 0, w, h);
}
void setupmywindow()
{
glClearColor(1,1,1,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
void myaxes(double size)
{
glBegin(GL_LINES);
glColor3f(0,0,0);
glVertex3f(0,0,0);
glColor3f(1,0,0);
glVertex3f(size,0,0); //x-axis
glColor3f(0,0,0);
glVertex3f(0,0,0);
glColor3f(0,1,0);
glVertex3f(0,size,0); //y-axis
glColor3f(0,0,0);
glVertex3f(0,0,0);
glColor3f(0,0,1);
glVertex3f(0,0,size); //z-axis
glEnd();
}
void sphere(float radius)
{
float z1, x1, y1, z2, x2, y2, z3, x3, y3, z4, x4, y4;
float dtheta = PI / 20;
float dphi = PI / 20;
glBegin(GL_QUADS);
for( float theta = 0; theta<=2.0*PI; theta+=dtheta )
{
for( float phi = 0; phi<=PI; phi+=dphi )
{
z1 = radius * sin(phi + dphi) * cos(theta + dtheta);
x1 = radius * sin(phi + dphi) * sin(theta + dtheta);
y1 = radius * cos(phi + dphi);
z2 = radius * sin(phi) * cos(theta + dtheta);
x2 = radius * sin(phi) * sin(theta + dtheta);
y2 = radius * cos(phi);
z3 = radius * sin(phi) * cos(theta);
x3 = radius * sin(phi) * sin(theta);
y3 = radius * cos(phi);
z4 = radius * sin(phi + dphi) * cos(theta);
x4 = radius * sin(phi + dphi) * sin(theta);
y4 = radius * cos(phi + dphi);
glColor3f(1,0,0);
glVertex3f(x4, y4, z4);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
}
}
glEnd();
}
void display(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect_ratio, 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// spherical coordinate camera transform, +Z is "up"
glTranslatef(0 ,0 , -camera_r);
glRotatef( (camera_theta - PI) * (180.0f/PI), 1,0,0 );
glRotatef( -camera_phi * (180.0f/PI), 0,0,1 );
sphere(2);
myaxes(5);
glutSwapBuffers();
}
void mykeyboardcontrol(unsigned char key, int x, int y)
{
switch(key){
case 'r': camera_r+=0.1;break; //increase radius
case 'p': camera_r-=0.1;break; //decrease radius
case 'i': camera_theta+=PI/20;break;//increase theta angle
case 'k': camera_theta-=PI/20;break;//increase theta angle
case 'j': camera_phi-=PI/20;break;//increase phi angle
case 'l': camera_phi+=PI/20;break;//increase phi angle
}
printf("r=%f theta=%f phi=%f\n",camera_r,camera_theta,camera_phi);
if(key==27) exit(0);
// clamp theta
if( camera_theta < 0 ) camera_theta = 0;
if( camera_theta > PI ) camera_theta = PI;
// wrap phi
if( camera_phi > 2*PI ) camera_phi -= 2*PI;
if( camera_phi < 2*PI ) camera_phi += 2*PI;
printf("r=%f theta=%f phi=%f\n",camera_r,camera_theta,camera_phi);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(400,400);
glutCreateWindow("Sphere");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(mykeyboardcontrol);
setupmywindow();
glutMainLoop();
return 0;
}
I have no clue why you were trying to pass r, theta, and phi into gluLookAt(), so I replaced that with a fixed oblique-ish camera angle looking at the origin. Also you seem to be overwriting theta and phi in sphere(), blasting away whatever mykeyboardcontrol() is trying to do. I couldn't tell if you want to orbit the camera around the origin or draw a partial sphere.