OpenGL: Issues Making Icons Rotate [duplicate] - c++

This question already has an answer here:
C : display every x milliseconds (OpenGL)
(1 answer)
Closed 7 years ago.
I have successfully drawn a square with a line through it, a trapezoid with a line through it, and a square on top of a trapezoid with a line through it. At this point I'm just attempting to make all of the icons rotate slowly on the screen, but can't figure out where I'm going wrong.
I've modeled my program after a previous one that I wrote that makes a polygon walk across the screen and jump up and do a flip, but for some reason I can't get any movement out of any of my icons. Is my TimerFunction not behaving as I would expect?
I know it's tedious to read, but I included my whole code because I'm not sure where the issue might be...
void init(void); //function that initializes the window clear color
void DrawsAllIcons(float x[], float y[], int ndraws, int pointsperdraw [], int drawtype[], float colorr[], float colorg[], float colorb[], float rotate, float scalex, float scaley, float transx, float transy); //function to draw the functions in the opened window
void SetupRC(void);
void RenderScene(void);
void settrans2 (float rotate, float scalex, float scaley, float transx, float transy);//function that sets the clear color used to set the state of the OpenGL system
void TimerFunction(int );
//square
float rotate = 00.0;
float xCoords [7] = {1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 0.0};
float yCoords [7] = {1.0,-1.0,-1.0,1.0,1.0,2.0,-2.0};
int numberofDraws = 2;
int pointsPerDraw[2] = {5, 2};
int typeOfDraw[2] = {2,1};
float colorR[3] = {1.0,0.0,0.0};
float colorg[3] = {0.0,1.0,0.0};
float colorb[3] = {0.0,0.0,1.0};
float transx = 5.0;
float transy = 5.0;
float scalex = 2.0;
float scaley = 2.0;
//trapezoid
float rotate2 = 00.0;
float xCoords2 [6] = {1.0, 1.5, -1.5, -1.0, 0.0, 0.0};
float yCoords2 [6] = {1.0,-1.0,-1.0,1.0,2.0,-2.0};
int numberofDraws2 = 2;
int pointsPerDraw2[2] = {4, 2};
int typeOfDraw2[2] = {3,1};
float colorR2[3] = {0.0,0.0,0.0};
float colorg2[3] = {1.0,1.0,0.0};
float colorb2[3] = {0.0,0.0,1.0};
float transx2 = -5.0;
float transy2 = -5.0;
float scalex2 = 2.0;
float scaley2 = 2.0;
//Square on trapezoid
float rotate3 = 00.0;
float xCoords3 [6] = {1.0, 1.0, -1.0, -1.0, 0.0,0.0};
float yCoords3 [6] = {1.0,0.0,0.0,1.0,3.0,-3.0};
int numberofDraws3 = 2;
int pointsPerDraw3[2] = {4, 2};
int typeOfDraw3[2] = {3,1};
float colorR3[3] = {1.0,0.0,0.0};
float colorg3[3] = {0.0,1.0,0.0}; //go down dont overthink
float colorb3[3] = {0.0,0.0,0.0};
float transx3 = 0.0;
float transy3 = 0.0;
float scalex3 = 1.0;
float scaley3 = 1.0;
//trapezoid under square
float rotate4 = 00.0;
float xCoords4 [6] = {1.5, 2.0, -2.0, -1.5, 0.0, 0.0};
float yCoords4 [6] = {0.0,-1.0,-1.0,0.0,3.0,-3.0};
int numberofDraws4 = 2;
int pointsPerDraw4[2] = {4, 2};
int typeOfDraw4[2] = {3,1};
float colorR4[3] = {0.0,0.0,0.0};
float colorg4[3] = {1.0,1.0,0.0};
float colorb4[3] = {0.0,0.0,1.0};
float transx4 = 0.0;
float transy4 = 0.0;
float scalex4 = 1.0;
float scaley4 = 1.0;
int main(int argc, char* *argv)
{
char header[]="This Bad Boy'll Draw any Icon you can think of"; //set up window title
glutInit(&argc, argv); // initialize glopen utility toolkit
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); // Set up the display mode with a buffer and colors **
glutInitWindowSize(560,440); //window size and position
glutInitWindowPosition(140,20);
SetupRC();
glutCreateWindow(header); // Open and label the window
glutDisplayFunc(RenderScene); //points to the function that will be drawing the item // Set the state of the rendering machine
glutTimerFunc(30, TimerFunction, 1);
glutMainLoop(); // Call and activate the main
return 0;
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);//note clear color was set in SetupRC
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,540,440); //set viewpoint to dimensions
glOrtho(-20.0,20.0,-20.0,20.0,1.0,-1.0);
glClear(GL_COLOR_BUFFER_BIT);
DrawsAllIcons(xCoords, yCoords, numberofDraws, pointsPerDraw,typeOfDraw,colorR,colorg,colorb, rotate, transx,transy,scalex,scaley); //used GL_LINE_STRIP for the square to show that that case worked
DrawsAllIcons(xCoords2, yCoords2, numberofDraws2, pointsPerDraw2,typeOfDraw2,colorR2,colorg2,colorb2, rotate2, transx2,transy2,scalex2,scaley2); //used GL_POLYGON and GL_LINE for rest
DrawsAllIcons(xCoords3, yCoords3, numberofDraws3, pointsPerDraw3,typeOfDraw3,colorR3,colorg3,colorb3, rotate3, transx3,transy3,scalex3,scaley3);
DrawsAllIcons(xCoords4, yCoords4, numberofDraws4, pointsPerDraw4,typeOfDraw4,colorR4,colorg4,colorb4, rotate4, transx4,transy4,scalex4,scaley4);
glEnd();
glutSwapBuffers(); //
}
void DrawsAllIcons (float x[], float y[], int ndraws, int pointsperdraw [], int drawtype[], float colorr[], float colorg[], float colorb[], float rotateD, float transxD, float transyD, float scalexD, float scaleyD)
{
settrans2(rotateD,scalexD,scaleyD,transxD, transyD);
int k=0; //index for arrays
int drawTooIndex = 0;
ndraws=ndraws-1;
for (int j=0; j<=ndraws; j++) //runs through
{
int whatCase = drawtype[j]; //sees what type of draw
drawTooIndex +=pointsperdraw[j];
switch (whatCase)
{
case 1:
{
glColor3f(colorr[j],colorg[j],colorb[j]);
glBegin(GL_LINES);
glVertex2f(x[k], y[k]); //sets vertex at the first point at k in the point arrays
int i = k+1;
k++;
for (i; i <drawTooIndex; i++)
{
glVertex2f(x[i], y[i]);
k++;
}
glEnd();
glFlush();
}
break;
case 2:
{
glColor3f(colorr[j], colorg[j], colorb[j]);
glBegin(GL_LINE_STRIP);
glVertex2f(x[k], y[k]);
int m = k+1;
k++;
for (m; m <drawTooIndex; m++)
{
glVertex2f(x[m], y[m]);
k++;
}
glEnd();
glFlush();
}
break;
case 3:
{
glColor3f(colorr[j], colorg[j], colorb[j]);
glShadeModel(GL_FLAT);
glBegin(GL_POLYGON);
glVertex2f(x[k], y[k]);
int n = k+1; //gets index of where to start drawing in the x and y arrays
k++;
for (n; n <drawTooIndex; n++)
{
glVertex2f(x[n], y[n]);
k++;
}
glEnd();
glFlush();
}
break;
}
}
}
void SetupRC(void)
{ // function sets the clear color of an open window, and then clears the open window
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color to pale green
return;
}//end of SetupRC
void settrans2(float rotateDD, float scalexDD, float scaleyDD, float transxDD, float transyDD)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(transxDD,transyDD,0.0);
glRotatef(rotateDD, 0.0, 0.0, 1.0); // where to put this in the program?
glScalef(scalexDD, scaleyDD, 1.0);
return;
}
void TimerFunction(int value)
{
rotate+=5.0;
rotate2+=5.0;
rotate3+=5.0;
rotate4+=5.0;
}

glutTimerFunc()s only fire once, you need to re-arm them in your callback to get another, as well as poking GLUT for a redraw with the new values:
void TimerFunction(int value)
{
rotate+=5.0;
rotate2+=5.0;
rotate3+=5.0;
rotate4+=5.0;
glutPostRedisplay();
glutTimerFunc( 30, TimerFunction, 1 );
}
All together:
#include <GL/glut.h>
//square
float rotate = 00.0;
float xCoords [7] = {1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 0.0};
float yCoords [7] = {1.0,-1.0,-1.0,1.0,1.0,2.0,-2.0};
int numberofDraws = 2;
int pointsPerDraw[2] = {5, 2};
int typeOfDraw[2] = {2,1};
float colorR[3] = {1.0,0.0,0.0};
float colorg[3] = {0.0,1.0,0.0};
float colorb[3] = {0.0,0.0,1.0};
float transx = 5.0;
float transy = 5.0;
float scalex = 2.0;
float scaley = 2.0;
//trapezoid
float rotate2 = 00.0;
float xCoords2 [6] = {1.0, 1.5, -1.5, -1.0, 0.0, 0.0};
float yCoords2 [6] = {1.0,-1.0,-1.0,1.0,2.0,-2.0};
int numberofDraws2 = 2;
int pointsPerDraw2[2] = {4, 2};
int typeOfDraw2[2] = {3,1};
float colorR2[3] = {0.0,0.0,0.0};
float colorg2[3] = {1.0,1.0,0.0};
float colorb2[3] = {0.0,0.0,1.0};
float transx2 = -5.0;
float transy2 = -5.0;
float scalex2 = 2.0;
float scaley2 = 2.0;
//Square on trapezoid
float rotate3 = 00.0;
float xCoords3 [6] = {1.0, 1.0, -1.0, -1.0, 0.0,0.0};
float yCoords3 [6] = {1.0,0.0,0.0,1.0,3.0,-3.0};
int numberofDraws3 = 2;
int pointsPerDraw3[2] = {4, 2};
int typeOfDraw3[2] = {3,1};
float colorR3[3] = {1.0,0.0,0.0};
float colorg3[3] = {0.0,1.0,0.0}; //go down dont overthink
float colorb3[3] = {0.0,0.0,0.0};
float transx3 = 0.0;
float transy3 = 0.0;
float scalex3 = 1.0;
float scaley3 = 1.0;
//trapezoid under square
float rotate4 = 00.0;
float xCoords4 [6] = {1.5, 2.0, -2.0, -1.5, 0.0, 0.0};
float yCoords4 [6] = {0.0,-1.0,-1.0,0.0,3.0,-3.0};
int numberofDraws4 = 2;
int pointsPerDraw4[2] = {4, 2};
int typeOfDraw4[2] = {3,1};
float colorR4[3] = {0.0,0.0,0.0};
float colorg4[3] = {1.0,1.0,0.0};
float colorb4[3] = {0.0,0.0,1.0};
float transx4 = 0.0;
float transy4 = 0.0;
float scalex4 = 1.0;
float scaley4 = 1.0;
void settrans2(float rotateDD, float scalexDD, float scaleyDD, float transxDD, float transyDD)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(transxDD,transyDD,0.0);
glRotatef(rotateDD, 0.0, 0.0, 1.0); // where to put this in the program?
glScalef(scalexDD, scaleyDD, 1.0);
return;
}
void DrawsAllIcons( float x[], float y[], int ndraws, int pointsperdraw [], int drawtype[], float colorr[], float colorg[], float colorb[], float rotateD, float transxD, float transyD, float scalexD, float scaleyD)
{
settrans2(rotateD,scalexD,scaleyD,transxD, transyD);
int k=0; //index for arrays
int drawTooIndex = 0;
ndraws=ndraws-1;
for (int j=0; j<=ndraws; j++) //runs through
{
int whatCase = drawtype[j]; //sees what type of draw
drawTooIndex +=pointsperdraw[j];
switch (whatCase)
{
case 1:
{
glColor3f(colorr[j],colorg[j],colorb[j]);
glBegin(GL_LINES);
glVertex2f(x[k], y[k]); //sets vertex at the first point at k in the point arrays
int i = k+1;
k++;
for (i; i <drawTooIndex; i++)
{
glVertex2f(x[i], y[i]);
k++;
}
glEnd();
glFlush();
}
break;
case 2:
{
glColor3f(colorr[j], colorg[j], colorb[j]);
glBegin(GL_LINE_STRIP);
glVertex2f(x[k], y[k]);
int m = k+1;
k++;
for (m; m <drawTooIndex; m++)
{
glVertex2f(x[m], y[m]);
k++;
}
glEnd();
glFlush();
}
break;
case 3:
{
glColor3f(colorr[j], colorg[j], colorb[j]);
glShadeModel(GL_FLAT);
glBegin(GL_POLYGON);
glVertex2f(x[k], y[k]);
int n = k+1; //gets index of where to start drawing in the x and y arrays
k++;
for (n; n <drawTooIndex; n++)
{
glVertex2f(x[n], y[n]);
k++;
}
glEnd();
glFlush();
}
break;
}
}
}
void RenderScene(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color to pale green
glClear(GL_COLOR_BUFFER_BIT);//note clear color was set in SetupRC
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,540,440); //set viewpoint to demensions
glOrtho(-20.0,20.0,-20.0,20.0,1.0,-1.0);
glClear(GL_COLOR_BUFFER_BIT);
DrawsAllIcons(xCoords, yCoords, numberofDraws, pointsPerDraw,typeOfDraw,colorR,colorg,colorb, rotate, transx,transy,scalex,scaley); //used GL_LINE_STRIP for the square to show that that case worked
DrawsAllIcons(xCoords2, yCoords2, numberofDraws2, pointsPerDraw2,typeOfDraw2,colorR2,colorg2,colorb2, rotate2, transx2,transy2,scalex2,scaley2); //used GL_POLYGON and GL_LINE for rest
DrawsAllIcons(xCoords3, yCoords3, numberofDraws3, pointsPerDraw3,typeOfDraw3,colorR3,colorg3,colorb3, rotate3, transx3,transy3,scalex3,scaley3);
DrawsAllIcons(xCoords4, yCoords4, numberofDraws4, pointsPerDraw4,typeOfDraw4,colorR4,colorg4,colorb4, rotate4, transx4,transy4,scalex4,scaley4);
glEnd();
glutSwapBuffers(); //
}
void TimerFunction(int value)
{
rotate+=5.0;
rotate2+=5.0;
rotate3+=5.0;
rotate4+=5.0;
glutPostRedisplay();
glutTimerFunc( 30, TimerFunction, 1 );
}
int main(int argc, char* *argv)
{
char header[]="This Bad Boy'll Draw any Icon you can think of"; //set up window title
glutInit(&argc, argv); // initialize glopen utility toolkit
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); // Set up the display mode with a buffer and colors **
glutInitWindowSize(560,440); //window size and positoin
glutInitWindowPosition(140,20);
glutCreateWindow(header); // Open and label the window
glutDisplayFunc(RenderScene); //points to the fucntion that will be drawing the item // Set the state of the rendering machine
glutTimerFunc(30, TimerFunction, 1);
glutMainLoop(); // Call and activate the main
return 0;
}

Related

OpenGL yoyo program troubles

I'm having trouble getting my yoyo program to work; I have a growing and shrinking string to go along with the yoyo moving and spinning, but I've got the string moving along with the yoyo. I need to have the string staying stationary while the yoyo spins up and down.I have to have the string and yoyo's movements allocated onto one button as well. Mind helping me with my code? (also please excuse the lackluster yoyo; I wanted to finish the programming before designing it)
#include "stdafx.h"
#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>
void firstDisplay();
void secondDisplay();
void movement();
void init();
void drawButton();
void handleButton(int button, int state, int x, int y);
const int Width=720;
const int Height = 480;
static float PI = 3.14159;
static float radius = 25;
static float INC= (PI/30);
static GLfloat spin = 0.0;
static GLfloat deltaz = .001;
static GLfloat deltax = 0.0;
static GLfloat deltay = 0.0;
//######################################################### Main #########################################################
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE | GLUT_DEPTH);
glutInitWindowSize(Width,Height);
glutInitWindowPosition(0,0);
glutCreateWindow("Yoyo");
glutDisplayFunc(firstDisplay);
glutMouseFunc(handleButton);
init();
glutMainLoop();
return;
}
//######################################################### Draw Button #########################################################
void drawButton()
{
glBegin(GL_POLYGON);
float theta;
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(1,0,1);
glVertex2f(40 + radius * cos(theta), 40 + radius*sin(theta));
}
glEnd();
}
//######################################################### Second Display #########################################################
void secondDisplay()
{
float theta;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON); //Here is the yoyo
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(1,1,1);
float radius1 = 75;
glVertex2f(360 + radius1 * cos(theta), 80 + radius1*sin(theta));
}
glEnd();
glBegin(GL_POLYGON); //Here is the yoyo design
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(0,1,1);
float radius1 = 55;
glVertex2f(350 + radius1 * cos(theta), 90 + radius1*sin(theta));
}
glEnd();
glFlush();
return;
}
//######################################################### First Display #########################################################
void firstDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
float theta;
glBegin(GL_POLYGON); //Here is the yoyo
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(1,1,1);
float radius1 = 75;
glVertex2f(360 + radius1 * cos(theta), 80 + radius1*sin(theta));
}
glEnd();
glBegin(GL_POLYGON); //Here is the yoyo
for (theta = 0.0; theta <= 2 * PI; theta += INC)
{
glColor3f(0,1,1);
float radius1 = 55;
glVertex2f(350 + radius1 * cos(theta), 90 + radius1*sin(theta));
}
glEnd();
drawButton();
glutSwapBuffers();
glFlush();
return;
}
//######################################################### Draw String #########################################################
void draw_string()
{
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(363, 8.25 - deltay, 0.0);
glVertex3f(357, 8.25 - deltay, 0);
glVertex3f(357, 6, 0);
glVertex3f(363, 6, 0);
glEnd();
}
//######################################################### Button Controls #########################################################
void handleButton(int button, int state, int x, int y)
{
static int index =-1;
if(button == GLUT_LEFT_BUTTON)
{
if(y>= 10 && y<= 100)
{
if (state == GLUT_DOWN)
{
glutIdleFunc(movement);
}
if (state == GLUT_UP)
{
glutIdleFunc(NULL);
}
}
glutSwapBuffers();
}
}
//######################################################### Yoyo Movement #########################################################
void movement()
{
static int goingup = 0;
glClear(GL_COLOR_BUFFER_BIT);
if(goingup==1)
{
deltay -= 6;
if(deltay <= 0)
{
goingup = 0;
}
spin = spin -5;
if(spin < 360)
{
spin = spin + 360;
}
}
if(goingup == 0)
{
deltay += 6;
if (deltay >= 315)
{
goingup = 1;
}
spin = spin +5;
if(spin < 360)
{
spin = spin + 360;
}
}
glPushMatrix();
glTranslatef(360+deltax, 80+deltay, 0.0);
glRotatef(spin,0.0,0.0,1.0);
glTranslatef(-360,-80, 0.0);
secondDisplay();
draw_string();
glPopMatrix();
drawButton();
glutSwapBuffers();
}
//######################################################### Init #########################################################
void init()
{
glClearColor(0, 0, 0, 0.0);
glColor3f(1, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,Width,Height,0);
return;
}
I solved my problem. I went separated the draw_string() and seconddisplay() functions within the movement function like so:
}
glPushMatrix();
glTranslatef(360+deltax, 80+deltay, 0.0);
glRotatef(spin,0.0,0.0,1.0);
glTranslatef(-360,-80, 0.0);
secondDisplay();
glPopMatrix();
glPushMatrix();
glTranslatef(360+deltax, 80+deltay, 0.0);
glRotatef(0,0.0,0.0,1.0);
glTranslatef(-360,-80, 0.0);
draw_string();
glPopMatrix();
drawButton();
glutSwapBuffers();
}
I removed the spin from draw_string()'s glRotatef.

switch between glOrtho and gluPerspective

I'm working in a little OpenGL - GLUT program (i'm totally noob), and i'm having many problems switching between gluPerspective and glOrtho pressing a key (for example 'p').
I've take some screenhots to illustrate the problem... using gluPerspective and glOrtho
And here's my code...
#if defined(__APPLE__)
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#else
#include <GL/gl.h>
#include <GL/greeglut.h>
#endif
#include <iostream>
#include <math.h>
#include "model.h"
using namespace std;
// actual vector representing the camera\'s direction
float lx = 0.0f,lz = -1.0f;
// XZ position of the camera
float x = 0.0f,z = 5.0f;
// angle for rotating triangle
float angle = 0.0f;
float fov = 45.0;
Model m;
Model m1;
Model m2;
Model m3;
double maxX, maxY, maxZ;
double minX, minY, minZ;
double centX, centY, centZ;
double maxTam;
bool persp = true;
double min(double x, double y) {
if(x < y) return x;
return y;
}
double max(double x, double y) {
if(x > y) return x;
return y;
}
void setMinMaxXYZ(void) {
maxX = minX = m.vertices()[0];
maxY = minY = m.vertices()[1];
maxZ = minZ = m.vertices()[2];
for(int i = 3; i < m.vertices().size(); i += 3) {
maxX = max(maxX,m.vertices()[i]);
minX = min(minX,m.vertices()[i]);
maxY = max(maxY,m.vertices()[i+1]);
minY = min(minY,m.vertices()[i+1]);
maxZ = max(maxZ,m.vertices()[i+2]);
minZ = min(minZ,m.vertices()[i+2]);
}
centX = ((maxX - minX)/2) + minX;
centY = ((maxY - minY)/2) + minY;
centZ = ((maxZ - minZ)/2) + minZ;
}
void changeView(void) {
int w = glutGet(GLUT_WINDOW_WIDTH);
int h = glutGet(GLUT_WINDOW_HEIGHT);
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(persp) gluPerspective(fov, ratio, 0.1f, 100.0f);
else glOrtho(-1,1,-1,1,-0.5,100.0);
glMatrixMode(GL_MODELVIEW);
}
void changeSize(int w, int h) {
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0) h = 1;
if(w == 0) w = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(persp) gluPerspective(fov, ratio, 0.1f, 100.0f);
else glOrtho(-1,1,-1,1,0.1,100.0);
glViewport(0,0,w,h);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
// Posicionament de la càmera
gluLookAt( x, 1.0f, z,
x+lx, 1.0f, z+lz,
0.0f, 1.0f, 0.0f);
glClearColor(0.5,0.5,1.0,1.0);
// dibuix terra
glColor3f(0.0f, 255.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-5.0f, 0.0f, -5.0f);
glVertex3f(-5.0f, 0.0f, 5.0f);
glVertex3f( 5.0f, 0.0f, 5.0f);
glVertex3f( 5.0f, 0.0f, -5.0f);
glEnd();
// Models .obj
for (int i = 0; i < 3; ++i) {
float transX, transY, transZ;
if(i == 0) {
m = m1;
transX = -1.25; transY = 0.5; transZ = -2.0;
} else if(i == 1) {
m = m2;
transX = -0.5; transY = 0.5; transZ = 2.5;
} else {
m = m3;
transX = 2.5; transY = 0.25; transZ = -0.5;
}
setMinMaxXYZ();
maxTam = max(max(maxX - minX, maxY - minY), maxZ - minZ);
glPushMatrix();
glTranslated(-(centX / maxTam), -(centY / maxTam), -(centZ / maxTam));
glTranslated(transX,transY,transZ);
glScaled(1.0/maxTam,1.0/maxTam,1.0/maxTam);
glBegin(GL_TRIANGLES);
for(int i = 0; i < m.faces().size(); i++){
const Face &f = m.faces()[i];
glColor3f(Materials[f.mat].diffuse[0],Materials[f.mat].diffuse[1],Materials[f.mat].diffuse[2]);
for(int j = 0; j < 3; j++)
glVertex3dv(&m.vertices()[f.v[j]]);
}
glEnd();
glPopMatrix();
}
glutSwapBuffers();
}
void processKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
else if(key == 'p'){
persp = not persp;
changeView();
}
}
void processSpecialKeys(int key, int xx, int yy) {
float fraction = 0.1f;
switch (key) {
case GLUT_KEY_LEFT :
angle -= 0.01f;
lx = sin(angle);
lz = -cos(angle);
break;
case GLUT_KEY_RIGHT :
angle += 0.01f;
lx = sin(angle);
lz = -cos(angle);
break;
case GLUT_KEY_UP :
x += lx * fraction;
z += lz * fraction;
break;
case GLUT_KEY_DOWN :
x -= lx * fraction;
z -= lz * fraction;
break;
}
}
void idle(void) {
glutPostRedisplay();
}
void iniView(void) {
int w = glutGet(GLUT_WINDOW_WIDTH);
int h = glutGet(GLUT_WINDOW_HEIGHT);
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, ratio, 0.1f, 100.0f);
//glOrtho(-1,1,-1,1,0.01,1000);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
// init GLUT i creació finestra
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("IDI: Bloc 3 - Càmeres i perspectives");
// Carregar models .obj
m1.load("model/legoman-assegut.obj");
m2.load("model/Shaun_Hastings.obj");
m3.load("model/porsche.obj");
// crides
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(idle);
glutKeyboardFunc(processKeys);
glutSpecialFunc(processSpecialKeys);
iniView();
// OpenGL init
glEnable(GL_DEPTH_TEST);
// loop
glutMainLoop();
return 1;
}
It's supposed that i should see the green "floor" in the glOrtho view... what i'm doing wrong??
ps. Model objects are .obj files delivered by the teacher.
edit:
Finally, the glOrtho works properly. But now... i've got another question, how can i do to maximize the window and (in glOrtho mode) the image does not deform??
In changeSize() function... when i'm using gluPerspective it works fine, but not with glOrtho!!
the fact that you don't see the floor with orthographic projection is actually expected given the way you set up your modelview matrix:
it happens because your floor is parallel to the XZ plane - and your view vector is, too.
// Posicionament de la càmera
gluLookAt( x, 1.0f, z,
x+lx, 1.0f, z+lz,
0.0f, 1.0f, 0.0f);
the first 3 arguments of gluLookAt are the xyz-components of the camera position, the next 3 arguments are the xyz of the 'center of interest'. the vector between those 2 points is the view vector, and its y-component is 0, meaning it is parallel to XZ and thus your floor.
if you want to see the floor + orthographic projection, you'll have to tilt the camera so that it looks down.

OpenGL OBJ Loader Error: EXC_BAD_ACCESS code = 1

I've just began learning OpenGL and this program is a mixture of stuff I've put together myself and some stuff straight copied from tutorials to speed up the process (like the whole OBJ loader you will see soon).
I'm having an error on
glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
//draw the faces
glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);
and that error is EXC_BAD_ACCESS code = 1. I'm completely lost for answers to this issue and I've searched around but couldn't find anything unfortunately. I also know for a fact that it is loading the file as well because that was the first issue I faced but resolved. Below is all my code (which is in one file. I'll be making a whole new project from scratch soon).
Main.cpp
#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cmath>
void init();
void keyboard(unsigned char key, int x, int y);
void reshape(int w, int h);
void display();
void camera();
void cubePositions();
void drawCube();
void enable();
void plane();
// Roation angles.
float xPos = 0;
float yPos = 0;
float zPos = 0;
float xRot = 0;
float yRot = 0;
float angle = 0.0;
float lastx, lasty;
// Cubes position arrays.
float cubePosZ[10];
float cubePozX[10];
// Fog variables.
GLfloat fogAngle = 0.0;
GLfloat density = 0.1;
GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
void makeCheckImage(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
struct coordinate{
float x,y,z;
coordinate(float a,float b,float c) : x(a),y(b),z(c) {};
};
//for faces, it can contain triangles and quads as well, the four variable contain which is that
struct face{
int facenum;
bool four;
int faces[4];
face(int facen,int f1,int f2,int f3) : facenum(facen){ //constructor for triangle
faces[0]=f1;
faces[1]=f2;
faces[2]=f3;
four=false;
}
face(int facen,int f1,int f2,int f3,int f4) : facenum(facen){ //overloaded constructor for quad
faces[0]=f1;
faces[1]=f2;
faces[2]=f3;
faces[3]=f4;
four=true;
}
};
//we rotate or object with angle degrees
int loadObject(const char* filename)
{
std::vector<std::string*> coord; //read every single line of the obj file as a string
std::vector<coordinate*> vertex;
std::vector<face*> faces;
std::vector<coordinate*> normals; //normal vectors for every face
std::ifstream in(filename); //open the .obj file
if(!in.is_open()) //if not opened, exit with -1
{
std::cout << "Nor oepened" << std::endl;
return -1;
}
char buf[256];
//read in every line to coord
while(!in.eof())
{
in.getline(buf,256);
coord.push_back(new std::string(buf));
}
//go through all of the elements of coord, and decide what kind of element is that
for(int i=0;i<coord.size();i++)
{
if(coord[i]->c_str()[0]=='#') //if it is a comment (the first character is #)
continue; //we don't care about that
else if(coord[i]->c_str()[0]=='v' && coord[i]->c_str()[1]==' ') //if vector
{
float tmpx,tmpy,tmpz;
sscanf(coord[i]->c_str(),"v %f %f %f",&tmpx,&tmpy,&tmpz); //read in the 3 float coordinate to tmpx,tmpy,tmpz
vertex.push_back(new coordinate(tmpx,tmpy,tmpz)); //and then add it to the end of our vertex list
}else if(coord[i]->c_str()[0]=='v' && coord[i]->c_str()[1]=='n') //if normal vector
{
float tmpx,tmpy,tmpz; //do the same thing
sscanf(coord[i]->c_str(),"vn %f %f %f",&tmpx,&tmpy,&tmpz);
normals.push_back(new coordinate(tmpx,tmpy,tmpz));
}else if(coord[i]->c_str()[0]=='f') //if face
{
int a,b,c,d,e;
if(count(coord[i]->begin(),coord[i]->end(),' ')==3) //if it is a triangle (it has 3 space in it)
{
sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b);
faces.push_back(new face(b,a,c,d)); //read in, and add to the end of the face list
}else{
sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b,&e,&b);
faces.push_back(new face(b,a,c,d,e)); //do the same, except we call another constructor, and we use different pattern
}
}
}
//raw
int num; //the id for the list
num=glGenLists(1); //generate a uniqe
glNewList(num,GL_COMPILE); //and create it
for(int i=0;i<faces.size();i++)
{
if(faces[i]->four) //if it's a quad draw a quad
{
glBegin(GL_QUADS);
//basically all I do here, is use the facenum (so the number of the face) as an index for the normal, so the 1st normal owe to the first face
//I subtract 1 because the index start from 0 in C++
glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
//draw the faces
glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);
glEnd();
}else{
glBegin(GL_TRIANGLES);
glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
glEnd();
}
}
glEndList();
//delete everything to avoid memory leaks
for(int i=0;i<coord.size();i++)
delete coord[i];
for(int i=0;i<faces.size();i++)
delete faces[i];
for(int i=0;i<normals.size();i++)
delete normals[i];
for(int i=0;i<vertex.size();i++)
delete vertex[i];
return num; //return with the id
}
// Sets the position of the cubes randomly. Can later be used for more purposeful placements.
void cubePositions()
{
for (int i = 0; i < 10; i++)
{
cubePosZ[i] = rand() % 5 + 5;
cubePozX[i] = rand() % 5 + 5;
}
}
void drawCube()
{
for (int i = 0; i < 10; i++)
{
glPushMatrix();
//glTranslated(-cubePozX[i + 1] * 10, -1, -cubePosZ[i + 1] * 10);
glTranslated((i + 4), 0, (i - 5));
glTranslatef(i, 0, 5 * i);
glScalef(2, 2, 2);
glBegin(GL_QUADS);
glTexCoord2f(1, 0);
glVertex3f(-1, -1, 0);
glNormal3f(1, 1, 1);
glTexCoord2f(1, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(0, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(0, 0);
glVertex3f(1, -1, 0);
glVertex3f(-1, -1, -1);
glVertex3f(-1, 1, -1);
glEnd();
glPopMatrix();
}
}
void plane()
{
glPushMatrix();
glColor4f(1.0, 0.0, 1.0, 1.0);
glTranslatef(0, -2.5, 0.0);
glScalef(100, 2, 100);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1, 0, 1);
glTexCoord2f(1.0, 0.0);
glVertex3f(-1, 0, -0.5);
glTexCoord2f(1.0, 1.0);
glVertex3f(1, 0, -0.5);
glTexCoord2f(0.0, 1.0);
glVertex3f(1, 0, 1);
glEnd();
glPopMatrix();
}
int cube;
void init()
{
cubePositions();
cube = loadObject("/Users/Admin/test.obj");
}
void enable()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
float col[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, col);
}
void camera()
{
glRotatef(xRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glTranslated(-xPos, -yPos, -zPos);
}
void display()
{
glClearColor(0.8, 0.8, 0.8, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
enable();
drawCube();
plane();
glCallList(cube);
glTranslated(-2, 0, 0);
glutSwapBuffers();
angle++;
}
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 1000.0);
glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
if (key == 27)
{
exit(0);
}
if (key == 'q')
{
xRot += 0.5;
if (xRot > 360)
{
xRot -= 360;
}
}
if (key == 'z')
{
xRot -= 0.5;
if (xRot < - 360)
{
xRot += 360;
}
}
if (key == 'w')
{
float xRotRad;
float yRotRad;
xRotRad = (xRot / 180 * 3.14159f);
yRotRad = (yRot / 180 * 3.14159f);
xPos += float(sin(yRotRad));
zPos -= float(cos(yRotRad));
yPos -= float(sin(xRotRad));
}
if (key == 's')
{
float xRotRad;
float yRotRad;
xRotRad = (xRot / 180 * 3.14159f);
yRotRad = (yRot / 180 * 3.14159f);
xPos -= float(sin(yRotRad));
zPos += float(cos(yRotRad));
yPos += float(sin(xRotRad));
}
if (key == 'd')
{
yRot += 1;
if (yRot > 360)
{
yRot -= 360;
}
}
if (key == 'a')
{
yRot -= 1;
if (yRot < -360)
{
yRot += 360;
}
}
if (key == 'x')
{
yPos -= 1;
}
if (key == 'c')
{
yPos += 1;
}
}
void mouseMovement(int x, int y)
{
int diffX = x - lastx;
int diffY = y - lasty;
lastx = x;
lasty = y;
xRot += (float)diffY;
yRot += (float)diffX;
}
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(1000, 1000);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL GLUT Computing - Taylor Moore");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(mouseMovement);
glutMainLoop();
return 0;
}
EXC_BAD_ACCESS usually means you are trying to access a chunk of memory that has been released or dealloc'ed. Here's the first response to a Google search on the term EXC_BAD_ACCESS that explains two strategies for tracking down the cause.

How to drag a graph around the window in OpenGL/c++

below is the code so far, my problem lies in dragging the graph around the window ? i can't seem to do it ? any tips for me guys ?? What i want is when you click and hold down the left mouse button you should be able to drag the graph around the window ?
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#if !defined(GLUT_WHEEL_UP)
# define GLUT_WHEEL_UP
# define GLUT_WHEEL_DOWN 4
#endif
/* Set initial size of the display window. */
GLsizei winWidth = 600, winHeight = 600;
/* Set size of world-coordinate clipping window. */
GLfloat xwcMin = -50.0, xwcMax = 50.0;
GLfloat ywcMin = -50.0, ywcMax = 50.0;
bool leftButton;
int downX, downY;
class wcPt3D {
public:
GLfloat x, y, z;
};
void init (void) {
/* Set color of display window to white. */
glClearColor (1.0, 1.0, 1.0, 0.0);
}
void plotPoint (wcPt3D bezCurvePt) {
glBegin (GL_POINTS);
glVertex2f (bezCurvePt.x, bezCurvePt.y);
glEnd ( );
}
/* Compute binomial coefficients C for given value of n. */
void binomialCoeffs (GLint n, GLint * C) {
GLint k, j;
for (k = 0; k <= n; k++) {
/* Compute n!/(k!(n - k)!). */
C [k] = 1;
for (j = n; j >= k + 1; j--)
C [k] *= j;
for (j = n - k; j >= 2; j--)
C [k] /= j;
}
}
void computeBezPt (GLfloat t, wcPt3D * bezPt, GLint nCtrlPts,
wcPt3D * ctrlPts, GLint * C) {
GLint k, n = nCtrlPts - 1;
GLfloat bezBlendFcn;
bezPt->x = bezPt->y = bezPt->z = 0.0;
/* Compute blending functions and blend control points. */
for (k = 0; k < nCtrlPts; k++) {
bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, n - k);
bezPt->x += ctrlPts [k].x * bezBlendFcn;
bezPt->y += ctrlPts [k].y * bezBlendFcn;
bezPt->z += ctrlPts [k].z * bezBlendFcn;
}
}
void bezier (wcPt3D * ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
wcPt3D bezCurvePt;
GLfloat t;
GLint *C;
/* Allocate space for binomial coefficients */
C = new GLint [nCtrlPts];
binomialCoeffs (nCtrlPts - 1, C);
for (int i = 0; i <= nBezCurvePts; i++) {
t = GLfloat (i) / GLfloat (nBezCurvePts);
computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C);
plotPoint (bezCurvePt);
}
delete [ ] C;
}
void displayFcn (void) {
glClear (GL_COLOR_BUFFER_BIT); // Clear display window.
/* Set example number of control points and number of
* curve positions to be plotted along the Bezier curve.
*/ GLint nCtrlPts = 4, nBezCurvePts = 1000;
wcPt3D ctrlPts [4] = { {-40.0, -40.0, 0.0}, {-10.0, 200.0, 0.0},
{10.0, -200.0, 0.0}, {40.0, 40.0, 0.0} };
glPointSize (4);
glColor3f (1.0, 0.0, 0.0); // Set point color to red.
bezier (ctrlPts, nCtrlPts, nBezCurvePts);
glutSwapBuffers();
}
void winReshapeFcn (GLint newWidth, GLint newHeight) {
/* Maintain an aspect ratio of 1.0. */
glViewport (0, 0, xwcMin, ywcMin);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
glutPostRedisplay();
}
void MouseCallback(int button, int state, int x, int y) {
downX = x;
downY = y;
leftButton = ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN));
glutPostRedisplay();
}
void MotionCallback(int x, int y) {
if (leftButton){
downX=downX+x;
downY=downY+y;
gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
}
downX = x;
downY = y;
glutPostRedisplay();
}
/*
void MouseCallback(int button, int state, int x, int y) {
if (button == GLUT_WHEEL_UP && glutGetModifiers()==GLUT_ACTIVE_CTRL) {
}else if (button == GLUT_WHEEL_DOWN)
glutPostRedisplay();
}
*/
int main (int argc, char** argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition (50, 50);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Bezier Curve");
init ( );
glutDisplayFunc (displayFcn);
glutReshapeFunc (winReshapeFcn);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
glutMainLoop ( );
}
Try this:
#include <GL/glut.h>
#include <cmath>
// Compute binomial coefficients C for given value of n.
void binomialCoeffs
(
GLint n,
GLint* C
)
{
for (GLint k = 0; k <= n; k++)
{
// Compute n!/(k!(n - k)!).
C [k] = 1;
for (GLint j = n; j >= k + 1; j--)
C [k] *= j;
for (GLint j = n - k; j >= 2; j--)
C [k] /= j;
}
}
struct wcPt3D
{
GLfloat x, y, z;
};
void computeBezPt
(
GLfloat t,
wcPt3D* bezPt,
GLint nCtrlPts,
wcPt3D* ctrlPts,
GLint* C
)
{
GLint n = nCtrlPts - 1;
GLfloat bezBlendFcn;
bezPt->x = bezPt->y = bezPt->z = 0.0;
// Compute blending functions and blend control points.
for (GLint k = 0; k < nCtrlPts; k++)
{
bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, n - k);
bezPt->x += ctrlPts [k].x * bezBlendFcn;
bezPt->y += ctrlPts [k].y * bezBlendFcn;
bezPt->z += ctrlPts [k].z * bezBlendFcn;
}
}
void bezier
(
wcPt3D* ctrlPts,
GLint nCtrlPts,
GLint nBezCurvePts
)
{
// Allocate space for binomial coefficients
GLint* C = new GLint [nCtrlPts];
binomialCoeffs (nCtrlPts - 1, C);
glBegin (GL_POINTS);
for (int i = 0; i <= nBezCurvePts; i++)
{
GLfloat t = GLfloat (i) / GLfloat (nBezCurvePts);
wcPt3D bezCurvePt;
computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C);
glVertex2f (bezCurvePt.x, bezCurvePt.y);
}
glEnd();
delete [ ] C;
}
int btn;
int startMouseX = 0;
int startMouseY = 0;
int startTransX = 0;
int startTransY = 0;
int curTransX = 0;
int curTransY = 0;
void MouseCallback(int button, int state, int x, int y)
{
btn = button;
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
startMouseX = x;
startMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
startTransX = curTransX;
startTransY = curTransY;
}
glutPostRedisplay();
}
void MotionCallback(int x, int y)
{
int curMouseX = x;
int curMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
if ( btn == GLUT_LEFT_BUTTON )
{
curTransX = startTransX + ( curMouseX - startMouseX );
curTransY = startTransY + ( curMouseY - startMouseY );
}
glutPostRedisplay();
}
// Set size of world-coordinate clipping window.
GLfloat xwcMin = -50.0, xwcMax = 50.0;
GLfloat ywcMin = -50.0, ywcMax = 50.0;
void displayFcn ()
{
// Clear display window.
glClearColor (1.0, 1.0, 1.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glTranslatef( curTransX / w * 2, curTransY / h * 2, 0 );
gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
// Set example number of control points and number of
// curve positions to be plotted along the Bezier curve.
GLint nCtrlPts = 4, nBezCurvePts = 1000;
wcPt3D ctrlPts [4] =
{
{-40.0, -40.0, 0.0},
{-10.0, 200.0, 0.0},
{10.0, -200.0, 0.0},
{40.0, 40.0, 0.0}
};
// Set point color to red.
glPointSize (4);
glColor3f (1.0, 0.0, 0.0);
bezier (ctrlPts, nCtrlPts, nBezCurvePts);
glutSwapBuffers();
}
int main (int argc, char** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition (50, 50);
glutInitWindowSize (600, 600);
glutCreateWindow ("Bezier Curve");
glutDisplayFunc (displayFcn);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
glutMainLoop ( );
}
Adapted from my answer here.
EDIT: Minimal(-ish) difference version:
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#if !defined(GLUT_WHEEL_UP)
# define GLUT_WHEEL_UP
# define GLUT_WHEEL_DOWN 4
#endif
/* Set initial size of the display window. */
GLsizei winWidth = 600, winHeight = 600;
/* Set size of world-coordinate clipping window. */
GLfloat xwcMin = -50.0, xwcMax = 50.0;
GLfloat ywcMin = -50.0, ywcMax = 50.0;
class wcPt3D {
public:
GLfloat x, y, z;
};
void init (void) {
/* Set color of display window to white. */
glClearColor (1.0, 1.0, 1.0, 0.0);
}
void plotPoint (wcPt3D bezCurvePt) {
glBegin (GL_POINTS);
glVertex2f (bezCurvePt.x, bezCurvePt.y);
glEnd ( );
}
/* Compute binomial coefficients C for given value of n. */
void binomialCoeffs (GLint n, GLint * C) {
GLint k, j;
for (k = 0; k <= n; k++) {
/* Compute n!/(k!(n - k)!). */
C [k] = 1;
for (j = n; j >= k + 1; j--)
C [k] *= j;
for (j = n - k; j >= 2; j--)
C [k] /= j;
}
}
void computeBezPt (GLfloat t, wcPt3D * bezPt, GLint nCtrlPts,
wcPt3D * ctrlPts, GLint * C) {
GLint k, n = nCtrlPts - 1;
GLfloat bezBlendFcn;
bezPt->x = bezPt->y = bezPt->z = 0.0;
/* Compute blending functions and blend control points. */
for (k = 0; k < nCtrlPts; k++) {
bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, n - k);
bezPt->x += ctrlPts [k].x * bezBlendFcn;
bezPt->y += ctrlPts [k].y * bezBlendFcn;
bezPt->z += ctrlPts [k].z * bezBlendFcn;
}
}
void bezier (wcPt3D * ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
wcPt3D bezCurvePt;
GLfloat t;
GLint *C;
/* Allocate space for binomial coefficients */
C = new GLint [nCtrlPts];
binomialCoeffs (nCtrlPts - 1, C);
for (int i = 0; i <= nBezCurvePts; i++) {
t = GLfloat (i) / GLfloat (nBezCurvePts);
computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C);
plotPoint (bezCurvePt);
}
delete [ ] C;
}
int curTransX = 0;
int curTransY = 0;
void displayFcn (void) {
glClear (GL_COLOR_BUFFER_BIT); // Clear display window.
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glTranslatef( curTransX / w * 2, curTransY / h * 2, 0 );
gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
/* Set example number of control points and number of
* curve positions to be plotted along the Bezier curve.
*/ GLint nCtrlPts = 4, nBezCurvePts = 1000;
wcPt3D ctrlPts [4] = { {-40.0, -40.0, 0.0}, {-10.0, 200.0, 0.0},
{10.0, -200.0, 0.0}, {40.0, 40.0, 0.0} };
glPointSize (4);
glColor3f (1.0, 0.0, 0.0); // Set point color to red.
bezier (ctrlPts, nCtrlPts, nBezCurvePts);
glutSwapBuffers();
}
int btn;
int startMouseX = 0;
int startMouseY = 0;
int startTransX = 0;
int startTransY = 0;
void MouseCallback(int button, int state, int x, int y) {
btn = button;
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
startMouseX = x;
startMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
startTransX = curTransX;
startTransY = curTransY;
}
glutPostRedisplay();
}
void MotionCallback(int x, int y) {
int curMouseX = x;
int curMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
if ( btn == GLUT_LEFT_BUTTON )
{
curTransX = startTransX + ( curMouseX - startMouseX );
curTransY = startTransY + ( curMouseY - startMouseY );
}
glutPostRedisplay();
}
/*
void MouseCallback(int button, int state, int x, int y) {
if (button == GLUT_WHEEL_UP && glutGetModifiers()==GLUT_ACTIVE_CTRL) {
}else if (button == GLUT_WHEEL_DOWN)
glutPostRedisplay();
}
*/
int main (int argc, char** argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition (50, 50);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Bezier Curve");
init ( );
glutDisplayFunc (displayFcn);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
glutMainLoop ( );
}

Draw A Sphere With Opengl

I draw the sphere by OpenGL.
This program can draw sphere when "SLIED = STACK".
But It's doesn't work when "SLIED not equal STACK".
I may be mistake "index array".
I want to use VBO and DMA(Dynamic memory allocate.use flat array).
But If You have another good idea, teach me.
//#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib,"glew32.lib")
#include <gl/glew.h>
#include <math.h>
#include <GL/freeglut/freeglut.h>
#define WIDTH 640
#define HEIGHT 480
#define M_PI 3.14159265358979323846
float angle=0.0f;
//functions----------------------------------------------//
void Shere_dma(double radius, int nSlice, int nStack);
void setSphereData(double radius, int nSlice, int nStack);
void DrawSphereVBO(void);
//-------------------------------------------------------//
//variabless---------------------------------------------//
int SLICE=0;
int STACK=0;
GLuint SVboId[3];
GLfloat* Svertex;//Vertex
GLfloat* Snormal;//Normal
GLfloat* Scolor; //Color
GLuint* indices_top; //TOP indices
GLuint* indices_bottom; //BOTTOM indies
GLuint* indices_side; //SIDE indices
//-------------------------------------------------------//
//Memory Allocate
void Shere_dma(double radius, int nSlice, int nStack){
Svertex = new GLfloat[(nSlice+1)*(nStack+1)*3];
Snormal = new GLfloat[(nSlice+1)*(nStack+1)*3];
Scolor = new GLfloat[(nSlice+1)*(nStack+1)*3];
indices_top = new GLuint[(nSlice+1)*(nStack+1)*3];
indices_bottom = new GLuint[(nSlice+1)*(nStack+1)*3];
indices_side = new GLuint[(nSlice+1)*(nStack+1)*4];
}
//inputData
void setSphereData(double radius, int nSlice, int nStack){
double phi; //Azimuth
double theta; //long
int coordinates=0;
int Slice_current_point_no=0;
int Slice_next_point_no=0;
const int x = 0;
const int y = 1;
const int z = 2;
const int p1 = 0;
const int p2 = 1;
const int p3 = 2;
const int p4 = 3;
//Vertex
for(int i = 0;i <= nSlice;i++)
{
phi = 2.0 * M_PI * (double)i / (double)nSlice;
for(int j = 0;j <= nStack;j++)
{
theta = M_PI * (double)j / (double)nStack;
Svertex[coordinates+x] = (float)(radius * sin(theta) * cos(phi)); //x
Svertex[coordinates+y] = (float)(radius * sin(theta) * sin(phi)); //y
Svertex[coordinates+z] = (float)(radius * cos(theta)); //z
Snormal[coordinates+x] = (float)(radius * sin(theta) * cos(phi)); //x
Snormal[coordinates+y] = (float)(radius * sin(theta) * sin(phi)); //y
Snormal[coordinates+z] = (float)(radius * cos(theta)); //z
Scolor[coordinates+x] = 1.0; //x
Scolor[coordinates+y] = 0.0; //y
Scolor[coordinates+z] = 0.0; //z
coordinates += 3;
}
}
//TOP
coordinates = 0;
Slice_current_point_no = 0;
Slice_next_point_no = nSlice;
for(int i = 0; i < nSlice; i++){
indices_top[coordinates+p1] = Slice_current_point_no;
indices_top[coordinates+p2] = indices_top[coordinates]+1;
indices_top[coordinates+p3] = Slice_next_point_no+2;
coordinates+=3;
Slice_current_point_no += nSlice+1;
Slice_next_point_no += nSlice+1;
}
//BOTTOM
coordinates =0;
Slice_current_point_no = 0;
Slice_next_point_no = nSlice;
for(int i = 0; i < nSlice; i++){
indices_bottom[coordinates+p1] = Slice_current_point_no+(nStack-1);
indices_bottom[coordinates+p2] = indices_bottom[coordinates]+1;
indices_bottom[coordinates+p3] = Slice_next_point_no+(nStack);
coordinates+=3;
Slice_current_point_no += nSlice+1;
Slice_next_point_no += nSlice+1;
}
//↓May be wrong ********************************************************************************//
//SIDE
coordinates=0;
Slice_current_point_no = 0;
Slice_next_point_no = nSlice+1;
for(int i=0; i < nSlice;i++){
for(int j=1; j < nStack-1; j++){
indices_side[coordinates+p1] = Slice_current_point_no+j;
indices_side[coordinates+p2] = indices_side[coordinates]+1;
indices_side[coordinates+p3] = Slice_next_point_no+(j+1);
indices_side[coordinates+p4] = Slice_next_point_no+j;
coordinates+=4;
}
Slice_current_point_no += nSlice+1;
Slice_next_point_no += nSlice+1;
}
//↑May be wrong ********************************************************************************//
glGenBuffers(3,&SVboId[0]);
//Vertex
glBindBuffer(GL_ARRAY_BUFFER,SVboId[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*(nSlice+1)*(nStack+1)*3,
Svertex,GL_DYNAMIC_DRAW);
//Normal
glBindBuffer(GL_ARRAY_BUFFER,SVboId[1]);
glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*(nSlice+1)*(nStack+1)*3,
Snormal,GL_DYNAMIC_DRAW);
//Color
glBindBuffer(GL_ARRAY_BUFFER,SVboId[2]);
glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*(nSlice+1)*(nStack+1)*3,
Scolor,GL_STREAM_DRAW);
}
//Draw
void DrawSphereVBO(void)
{
int point=0;
//Enable
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
//Vertex
glBindBuffer(GL_ARRAY_BUFFER,SVboId[0]);
glVertexPointer(3, GL_FLOAT, 0, 0);
//Normal
glBindBuffer(GL_ARRAY_BUFFER,SVboId[1]);
glNormalPointer(GL_FLOAT, 0, 0);
//Color
glBindBuffer(GL_ARRAY_BUFFER,SVboId[2]);
glColorPointer(3,GL_FLOAT, 0, 0);
//---------------------------------Draw---------------------------------------------------//
//TOP
for(int i=0; i<SLICE;i++){
glDrawRangeElements(GL_TRIANGLES, point, point+2, 3, GL_UNSIGNED_INT, indices_top+i*3);
point+=3;
}
//BOTTOM
point=0;
for(int i=0; i<SLICE;i++){
glDrawRangeElements(GL_TRIANGLES, point, point+2, 3, GL_UNSIGNED_INT, indices_bottom+i*3);
point+=3;
}
//↓May be wrong ********************************************************************************//
//SIDE
point=0;
for(int i=0; i< (SLICE*(STACK-2));i++){
glDrawRangeElements(GL_QUADS, point, point+3, 4, GL_UNSIGNED_INT, indices_side+i*4);
point+=4;
}
//↑May be wrong ********************************************************************************//
//---------------------------------Draw---------------------------------------------------//
//Disable
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,WIDTH,HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0, 5.0,5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle,0.0f,1.0f,0.0f);
DrawSphereVBO();
glutSwapBuffers();
}
void idle(void)
{
glutPostRedisplay();
angle+=0.2f;
}
void Init(){
glewInit();
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
SLICE = 5;
STACK = 5;
Shere_dma(1,SLICE,STACK); //MemoryAllocate
setSphereData(1,SLICE,STACK); //InputData
}
int main(int argc, char *argv[])
{
glutInitWindowPosition(100, 100);
glutInitWindowSize(WIDTH, HEIGHT);
glutInit(&argc, argv);
glutCreateWindow("VBO");
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutDisplayFunc(display);
glutIdleFunc(idle);
Init();
glutMainLoop();
return 0;
}
I refer to this code.
void drawSphere(double radius, int nSlice, int nStack)
{
int i, j;
double phi; //
double theta; //long
float p[31][31][3]; //Vertex
float *p1,*p2,*p3,*p4;
if(nSlice > 30) nSlice = 30;
if(nStack > 30) nStack = 30;
//Vertex
for(i = 0;i <= nSlice;i++)
{
phi = 2.0 * M_PI * (double)i / (double)nSlice;
for(j = 0;j <= nStack;j++)
{
theta = M_PI * (double)j / (double)nStack;
p[i][j][0] = (float)(radius * sin(theta) * cos(phi));//x
p[i][j][1] = (float)(radius * sin(theta) * sin(phi));//y
p[i][j][2] = (float)(radius * cos(theta)); //z
}
}
//Top(j=0)
for(i = 0;i < nSlice; i++)
{
p1 = p[i][0]; p2 = p[i][1];
p3 = p[i+1][1];
glBegin(GL_TRIANGLES);
glNormal3fv(p1); glVertex3fv(p1);
glNormal3fv(p2); glVertex3fv(p2);
glNormal3fv(p3); glVertex3fv(p3);
glEnd();
}
//Bottom
j=nStack-1;
for(i = 0;i < nSlice; i++)
{
p1 = p[i][j]; p2 = p[i][j+1];
p3 = p[i+1][j];
glBegin(GL_TRIANGLES);
glNormal3fv(p1); glVertex3fv(p1);
glNormal3fv(p2); glVertex3fv(p2);
glNormal3fv(p3); glVertex3fv(p3);
glEnd();
}
for(i = 0;i < nSlice;i++){
for(j = 1;j < nStack-1; j++)
{
p1 = p[i][j]; p2 = p[i][j+1];
p3 = p[i+1][j+1]; p4 = p[i+1][j];
glBegin(GL_QUADS);
glNormal3fv(p1); glVertex3fv(p1);
glNormal3fv(p2); glVertex3fv(p2);
glNormal3fv(p3); glVertex3fv(p3);
glNormal3fv(p4); glVertex3fv(p4);
glEnd();
}
}
}
I've written a tutorial on generating sphere meshes - it doesn't come with source code, but describes the process and walks you through the issues you'll encounter. You can find the tutorial at: http://sol.gfxile.net/sphere/index.html
I would recommend using spherical coordinates using two angles phi (elevation) and theta (around) or by using the equation of the sphere: x2 + y2 + z2 = r2
were you keep one of the values constant and increment later as you replace values in the 2nd to find the 3rd value.