Drawing an array of objects in Open GL Glut - c++

I have been trying to draw multiple balls for a game I am making, I have tried to get this working but there are problems in my init class and display method class, I have commented it where the errors are.
Ball.h:
#pragma once
#include "Vector2f.h"
#include "Vector3f.h"
class Ball
{
private:
Vector3f position;
Vector3f velocity;
public:
Ball(void);
~Ball(void);
void Draw();
void SetPos(Vector3f New_position);
void SetVel(Vector3f New_velocity);
Vector3f GetPos();
};
Ball.cpp
#include "Ball.h"
#include "Vector2f.h"
#include "Vector3f.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
Ball::Ball(void)
{
Vector3f Temp_position;
position = Temp_position;
Vector3f Temp_velocity;
velocity = Temp_velocity;
}
Ball::~Ball(void)
{
}
void Ball::SetPos(Vector3f New_position)
{
position = New_position;
}
void Ball::Draw()
{
glPushMatrix();
glTranslatef(position.X(), position.Y(), position.Z());
glColor3d(1, 0, 0);
glutSolidSphere(0.3, 50, 50);
glPopMatrix();
}
void Ball::SetVel(Vector3f New_velocity)
{
velocity = New_velocity;
}
Vector3f Ball::GetPos()
{
Vector3f temp;
temp = position;
return temp;
}
I want the be able to draw an array of the balls in Main.cpp
Main.cpp
#include "Display.h"
#include "Vector3f.h"
#include "Ball.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include <math.h>
static float TableWidth = 4; // Z axis normal = 4
float Display::eyeX = -7.5; //-7.5
float Display::eyeY = 3; //3
float Display::eyeZ = 5; //5
float Display::Position[4] = { 1.0f, 0.0f, -3.5, 1.0f };
float Display::translateZ = -3.5;
float Display::translateX = 0.0;
//Timer Display::m_Timer = Timer();
float Display::lightX = 5.0; //5 2.5
float Display::lightY = 5.0;
float Display::lightZ = 2.5;
float m_TableX = -5.0f;
float m_TableZ = -2.5f;
float m_TableWidth = 2.5f;
float m_TableLength = 5.0f;
float ballx = 0.7;
float bally = 0.1;
float ballz = -0.7;
Ball Redball;
float BALL_RED_START = 0;
float RADIUS_OF_BALL = 0.3;
float BALL_RED_END = 8;
float m_ball;
void Display::Init(int argc, char ** argv)
{
glutInit(&argc, argv); // initializes glut
// sets display mode. These parameter set RGB colour model
// and double buffering.
glutInitWindowSize(500,500);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Pool Version 1.0");
// Set glut callback functions
glutDisplayFunc(Display::DisplayScene);
glutIdleFunc(Display::Idle);
glutReshapeFunc(Display::Resize);
glutKeyboardFunc(Display::KeyboardInput);
//m_Timer.getSeconds();
glEnable(GL_DEPTH_TEST);
glPointSize(5);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glClearColor(0,0,0,1);
glEnable(GL_COLOR_MATERIAL);
float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glEnable(GL_LIGHT0);
Redball.SetPos(Vector3f(0.0,0.3,0.0));
for(int i = BALL_RED_START; i < BALL_RED_START; i++)
{
glColor3f(1,0,0);
Redball[i]->SetPos(Vector3f (i+128,RADIUS_OF_BALL,45)); //I tried this but it doesn't work Error C2227
}
// Begin glut main loop
glutMainLoop();
}
void BallMovement()
{
//Vector3f position(0.0,0.3,0.0);
/*Redball.SetPos(Vector3f(0.0,0.3,0.0));*/
Vector3f New_velocity(0.01,0,0);
Redball.SetVel(New_velocity);
Vector3f New_position;
Vector3f Old_position;
Old_position = Redball.GetPos();
//New_position = Old_position + New_velocity;
New_position.SetX(Old_position.X() + New_velocity.X());
New_position.SetY(Old_position.Y() + New_velocity.Y());
New_position.SetZ(Old_position.Z() + New_velocity.Z());
Redball.SetPos(New_position);
}
void Display::DisplayScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the back buffer
glPushMatrix();
glLoadIdentity();
glNormal3f(0,1,0);
Vector3f didums = Redball.GetPos();
gluLookAt(eyeX, eyeY, eyeZ, // eye position
0, 0, 0, // what I'm looking at
0.0, 1.0, 0); // Up direction
float Position[] = {lightX, lightY, lightZ, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, Position);
DrawLight(0, Position);
/* Rendering code goes here */
for (int i = BALL_RED_START; i<BALL_RED_END;i++)
{
glColor3f(1,0,0);
Redball[i]->Draw(); //I tried this but it doesn't work Error C2227
}
drawTable();
drawTableLegFrontLeft();
drawTableLegFrontRight();
drawTableLegBackLeft();
drawTableLegBackRight();
drawCushions();
//drawCircle();
//drawHCircle();
Table(-2,-4.5,2,4.5); // Draws the table top in trianglestrip -4.5, 0.5, -0.5, 9.5
glPopMatrix();
glutSwapBuffers(); // Swap the front and back buffers
}
void Display::Resize(int w, int h)
{
/* Resize is called when window is resized */
glMatrixMode(GL_PROJECTION); // set matrix mode to profection
// this dictates how the 3d scene is "squashed" onto the 2d screen
glLoadIdentity();
glViewport(0, 0, w, h); // Set the part of the window to use.
gluPerspective(45, // field of view
(float)w/(float)h, // ration of window
1, // front clipping plane
1000 // back clipping plane
); // set the area in the 3d scene to draw
glMatrixMode(GL_MODELVIEW); // Setthe matrix mode to model view
// the matrix specifies how the 3d scene is viewed
/*glLoadIdentity();
gluLookAt(-3.5, 2, eyeZ, // eye position
1, 1, 0, // what I'm looking at
0.0, 1.0, 0); // Up direction*/
}
void Display::Idle()
{
/* When nothing else is happening, idle is called.
* Simulation should be done here and then
* the display method should be called
*/
BallMovement();
glutPostRedisplay();
}

I see you have declared Ball as Ball Redball; which will create a single Ball on the stack.
Then you attempt to treat it as a collection of Balls with Redball[i]->SetPos(...) and Redball[i]->Draw(). It appears you are attempting to work with 8 of them.
What you want to do is create an array of Balls, with a max size of 8 (according to BALL_RED_END). For simplicity, you could do
Ball RedBall[8];
for( //some conditions here )
{
RedBall[i].Draw();
}
as your declaration and usage.
Remember that anytime you use Redball.SetPos(...) will no longer be valid.

Related

OpenGL animation for scrolling text horizontally doesnt scroll

I am trying to scroll a text as a banner. I used openGL with glut to make this work. The whole code works if I use a figure like a square. The square scrolls over the screen.
Now I want to do this with text. Every time this program started. The text came at its starting position, but when the timer starts, it vanished. This is probably because the screen was cleared every clocktick, but the screen doesn't build up again.
Someone who can help me with this translation animation and text?
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glut.h>
using namespace std;
static int font_index = 0;
int state = 1;
void print_bitmap_string(/*void* font,*/ const char* s)
{
while (*s) {
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *s);
s++;
}
}
void my_reshape(int w, int h)
{
GLdouble size;
GLdouble aspect;
/* Use the whole window. */
glViewport(0, 0, w, h);
/* We are going to do some 2-D orthographic drawing. */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
size = (GLdouble)((w >= h) ? w : h) / 2.0;
if (w <= h) {
aspect = (GLdouble)h / (GLdouble)w;
glOrtho(-size, size, -size * aspect, size * aspect, -100000.0, 100000.0);
}
else {
aspect = (GLdouble)w / (GLdouble)h;
glOrtho(-size * aspect, size * aspect, -size, size, -100000.0, 100000.0);
}
/* Make the world and window coordinates coincide so that 1.0 in */
/* model space equals one pixel in window space. */
glScaled(aspect, aspect, 1.0);
/* Now determine where to draw things. */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
float yild;
float ystep;
float x_pos = -200;
float y_pos = 70;
void draw()
{
const char* bitmap_font_names[7] = { "Hello train" };
/* Draw the strings, according to the current mode and font. */
glTranslatef(0.5, -100, 0);
//set the text color
glColor4f(0.0f, 255.0f, 140.0f, 1.0f);
ystep = 100.0;
yild = 20.0;
glRasterPos2f(x_pos, y_pos + 1.25 * yild);
print_bitmap_string(bitmap_font_names[0]);
}
void display(void)
{
//change background color
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
draw();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(x_pos + 0.5f, 0.0f);
glVertex2f(x_pos+1.0f, 0.5f);
glVertex2f(x_pos+0.5f, 0.5f);
glEnd();
glutSwapBuffers();
}
void timer(int) {
glutPostRedisplay();
glutTimerFunc(1000 , timer, 0);
switch (state) {
case 1:
if (x_pos > -295) {
x_pos -= 1;
}
else {
state = -1;
}
break;
case -1:
x_pos = 180;
state = 1;
break;
}
cout << x_pos << endl;
}
int main(int argc, char** argv)
{
glutInitWindowSize(500, 150);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Train Display");
glutDisplayFunc(display);
glutReshapeFunc(my_reshape);
glutTimerFunc(1000, timer, 0);
glutMainLoop();
return 0;
}
glTranslate does not just set a translation matrix, but multiply the current matrix by a translation matrix. You need to load the identity matrix with glLoadIdentity before glTranslatef or save and restore the current matrix with glPushMatrix/glPopMatrix:
void draw()
{
const char* bitmap_font_names[7] = { "Hello train" };
glPushMatrix();
/* Draw the strings, according to the current mode and font. */
glTranslatef(0.5, -100, 0);
//set the text color
glColor4f(0.0f, 255.0f, 140.0f, 1.0f);
ystep = 100.0;
yild = 20.0;
glRasterPos2f(x_pos, y_pos + 1.25 * yild);
print_bitmap_string(bitmap_font_names[0]);
glPopMatrix();
}

OpenGL with two loops, one loop is not working

My OpenGL program is not working properly. Inside the drawScene() function I created two loops. One loop for GL_LINES another loop for GL_POINTS. The GL_LINES loop works fine but GL_POINTS loop doesn't work. Any help appreciated.
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define PI 3.14159265
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Change the background to sky blue
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 0.0f;
float _cameraAngle = 0.0f;
float x = -1.5;
float y = -0.5;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLineWidth (9.0f);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
double r = 0.5;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glPointSize (7.0f);
glBegin(GL_POINTS);
glColor3f(0.0f, 1.0f, 0.0f);
double r = 1.0;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
//glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glutSwapBuffers();
//glutPostRedisplay();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(60, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
//Create the window
glutCreateWindow("two circle");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0); //Add a timer
glutMainLoop();
return 0;
}
Right now, you're declaring the variable r in two places: where you set double r = 0.5; and at double r = 1.0;
Try changing it to:
double r = 0.5;
//First loop
r = 1.0;
//Second loop

Cannot get glLineStipple to work

I am building a virtual oscilloscope with OpenGL. I am able to plot the x and y axis and also create a grid. But I cannot get the grid lines to stipple using the code below... Any suggestions ?? glLineStipple is called in the DrawMainWindow function that is passed to glutDisplayFunction....
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//procedures for shared memory access
#include <sys/shm.h>
#include <sys/stat.h>
#include "binary_sems.h"
///////////////////////////////////////
//debug - FIXME - Add Controls !!!
///////////////////////////////////////
////////////////////////////////////////
// So in debug turn this off to run
// the oscilloscope standalone
////////////////////////////////////////
//#define USE_COMMS
////////////////////////////////////////
// Define a constant for the value of PI
////////////////////////////////////////
#define GL_PI 3.1415f
// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
//range
GLfloat nRange = 1000.0f;
//gain control
float gain = 1.00;
//enable / disable grid
int grid_enable = 1;
//debug
int frame_id=0;
//////////////////////////////////////////
//Shared Memory Variables
//////////////////////////////////////////
/*variable for shared memory*/
int segment_id;
char *shared_memory;
/*variables for semaphore*/
int semid;
//variables
float BorderClr[3] = {1, 1, 1}; //Default colour for borders
float Ch1TrClr[3] = {1, 1, 0}; //Default colour for channel 1 traces
float GridClr[3] = {1, 1, 1}; //Default colour for grid
float TextClr[3] = {1, 0, 0}; //Default colour for text
float PauseClr[3] = {1, 0, 0}; //Colour for "Paused" text
//defines
#define DISP_BUFFER_LENGTH 1000
//structure defining data points
typedef struct voltage_samples{
float volts; //this is the raw voltage data
float volts_scaled; //this is the scaled voltage data for display (x)
float time_stamp; //this is the time stamp (y )
} DISPLAY_SAMPLES;
//declare a buffer of display samples
DISPLAY_SAMPLES sample_buffer[DISP_BUFFER_LENGTH];
int display_update = 0;
//Function Prototypes
void DrawMainWindow(void);
void IdleProcessing(void);
void SetupRC(void);
void ChangeSize(int w, int h);
void SpecialKeys(int key, int x, int y);
void WriteText(char *text, float height, float x, float y, float z);
////////////////////////////////////////////////////////
//Procedure Entry Point
////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
#ifdef USE_COMMS
//Verify that the shared memory data buffer
//has been specified
if(argc != 3){
printf("ERROR:Usage::APPLICATION <Shared Memory Segment ID> <Semaphore ID for this shared memory segment>\n");
return(-1);
}
//Initialize shared memory parameters
/*get the segment ID from the command line */
segment_id = strtol(argv[1],NULL,0);
/*get the semaphore ID from the comand line*/
semid = strtol(argv[2],NULL,0);
/*attach to the shared memory segment*/
shared_memory = (char *)shmat(segment_id, 0, 0);
#endif
//Initialization parameters for glut
glutInit(&argc, argv);
//Suggest to O/S where the window should
//be initialized at.
//glutInitWindowPosition(0,0);
//Initialize the window size
glutInitWindowSize(640,480);
//Argument for next opened window
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//Create the window
glutCreateWindow("CUDA Oscilloscope");
//Register Special Keys and Change Size Functions
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
//Register callback function for redrawing window
glutDisplayFunc(DrawMainWindow);
//Register callback function for idle processing
glutIdleFunc(IdleProcessing);
//Enable depth testing ???
glEnable(GL_DEPTH_TEST);
//Set up drawing environment
//SetupRC();
//Start the infinite loop - function will never return
//till controlled ^c
glutMainLoop();
return 0;
}
/////////////////////////////////////////////////////////
//Functions
/////////////////////////////////////////////////////////
void DrawMainWindow(void)
{
//GLfloat x, y, z;
float x,y,z;
//Clear buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Save previous settings
glPushMatrix();
//Draw all samples
glColor3fv(Ch1TrClr);
//Get scaled / processed data from buffer;
//this was the data that was created during
//idle state
glBegin(GL_POINTS);
z = 0.00;
for(int ii=0; ii < DISP_BUFFER_LENGTH; ii++){
//plot point on the coordinate
x = -nRange + ii*2.00;
y = sample_buffer[ii].volts_scaled;
//plot the coordinate
glVertex3f(x,y,z);
}
glEnd();
if(grid_enable == 1){
//Grid Color and Line Widths
glColor3fv(GridClr);
//Draw X and Y axis
GLint factor = 10;
GLushort pattern = 0x5555;
glLineWidth(2);
//Draw X-Axis
glBegin(GL_LINES);
glLineStipple(factor, pattern);
glVertex3f(-nRange, 0.00, 0.00);
glVertex3f( nRange, 0.00, 0.00);
glEnd();
//Draw Y-Axis
glBegin(GL_LINES);
glLineStipple(factor, pattern);
glVertex3f(0.00, -nRange, 0.00);
glVertex3f(0.00, nRange, 0.00);
glEnd();
//Draw a 10x10 grid ( stipple lines )
factor = 10;
pattern = 0x5050;
glLineWidth(1);
// //Bottom to top - horizintal lines
for(float ii=-nRange; ii < nRange; ii += 100)
{
glLineStipple(factor, pattern);
glBegin(GL_LINES);
glVertex3f(-nRange, ii, 0.00);
glVertex3f( nRange, ii, 0.00);
glEnd();
}
// //Left to right - vertical lines
for(float ii=-nRange; ii < nRange+100; ii += 100)
{
glLineStipple(factor, pattern);
glBegin(GL_LINES);
glVertex3f(ii, -nRange, 0.00);
glVertex3f(ii, nRange, 0.00);
glEnd();
}
}
//Write Measurement parameters to the screen
glColor3fv(TextClr);
WriteText("(Y)::Vertical Scale=", 50.00, 300.00, 800.00, 0.00);
WriteText("(X)::Horizontal Scale=", 50.00, 300.00, 700.00, 0.00);
//FIXME - Display Time Settings
//FIXME - Display "Paused" if capture is paused
//FIXME - Display trigger settings
//FIXME - Display Ch1 Settings
//Restore previous settings
glPopMatrix();
//Puts rendered scene on front buffer
//glFlush is called by glutSwapBuffers implicitely
glutSwapBuffers();
}
//FIXME - Several functions are required for GUI
void IdleProcessing(void)
{
/*clear read buffer so new write data can be added*/
initSemAvailable(semid, 1);
/*try bump down semaphore to indicate completion of memory read*/
reserveSem(semid,0);
//Here we acquire and process the content of the
//data buffer
double *p = (double *)shared_memory;
for(int ii=0; ii < DISP_BUFFER_LENGTH; ii++){
#ifdef USE_COMMS
sample_buffer[ii].volts_scaled = gain*p[ii];
#else
sample_buffer[ii].volts_scaled = gain*cos((2.0f*GL_PI)*ii*4/DISP_BUFFER_LENGTH + rand()%2) + rand()%10;
#endif
}
#ifdef DEBUG
for(int ii=0; ii < DISP_BUFFER_LENGTH; ii++){
if(ii%10==0){
printf("\n");
}
printf("%f ",sample_buffer[ii].volts_scaled);
}
printf("\n");
#endif
printf("Frame Cntr = %d\r",frame_id);
frame_id++;
//FIXME - data processing during idle time
DrawMainWindow();
}
// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
// Set drawing color to green
glColor3f(1.0f, 1.0f, 1.0f);
//enable line stippling
glEnable(GL_LINE_STIPPLE);
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP){
//xRot-= 5.0f;
if(gain < 10000.00)
gain = gain + 100.0;
}
if(key == GLUT_KEY_DOWN){
//xRot += 5.0f;
if(gain > 0.00)
gain = gain - 100.0;
}
if(key == GLUT_KEY_LEFT)
//yRot -= 5.0f;
grid_enable = 1;
if(key == GLUT_KEY_RIGHT)
//yRot += 5.0f;
grid_enable = 0;
if(key > 356.0f)
xRot = 0.0f;
if(key < -1.0f)
xRot = 355.0f;
if(key > 356.0f)
yRot = 0.0f;
if(key < -1.0f)
yRot = 355.0f;
// Refresh the Window
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void WriteText(char *text, float height, float x, float y, float z)
{
const float charHeight = 119.05;
glPushMatrix();
glTranslatef(x,y,z);
glScalef(height/charHeight/1.5, height/charHeight, height/charHeight);
while(*text){
glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, (int)*text);
*text++;
}
glPopMatrix();
}

Drawing spheres with mouse positions in opengl

I am trying to draw spheres at the mouse locations everytime I click the screen.
I wrote a function to get the 3D mouse coordinates, everytime the mouse is clicked. It works like a charm.
Now how can I create spheres at those locations.
void display()
{
...
...
glColor3f(1,0,0)
glutWireSphere(3,100,100);
glTranslatef(X,Y,Z);
}
void MouseFunc()//where the 3D mouse coordinates are recieved
{
double X,Y,Z// where I store the coordinates.
.....
.....
glutDisplayFunc(display);//Because thats where I create the spheres
}
In MouseFunc store the position of the click into a array/list/vector visible to the drawing function, i.e. not in locally scoped variable. Then you call glutPostRedisplay to make GLUT call the display func you registered once in the initialization code using glutDisplayFunc.
In the display function itself you iterate over the array/list/vector and draw a sphere for each element according to the element's data.
Code sample due to request in comment
clicksphere.cc
#include <GL/glut.h>
#include <GL/gl.h>
#include <list>
typedef union v2f_t {
struct {
float x;
float y;
};
float v[2];
} v2f_t;
typedef std::list<v2f_t> v2flist_t;
v2flist_t sphere_centers;
void display(void)
{
int const window_width = glutGet(GLUT_WINDOW_WIDTH);
int const window_height = glutGet(GLUT_WINDOW_HEIGHT);
float const window_aspect = (float)window_width / (float)window_height;
glClearColor(0.5, 0.5, 1.0, 1.0);
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(window_aspect > 1.) {
glOrtho(-window_aspect, window_aspect, -1, 1, -1, 1);
}
else {
glOrtho(-1, 1, -1/window_aspect, 1/window_aspect, -1, 1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat const light_pos[4] = {-1.00, 1.00, 1.00, 0.};
GLfloat const light_color[4] = { 0.85, 0.90, 0.70, 1.};
GLfloat const light_ambient[4] = { 0.10, 0.10, 0.30, 1.};
glLightfv(GL_LIGHT0, GL_POSITION, light_pos),
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
for( v2flist_t::iterator sc = sphere_centers.begin();
sc != sphere_centers.end();
sc++ ) {
glPushMatrix();
glTranslatef(sc->x, sc->y, 0);
glutSolidSphere(0.1, 31, 10);
glPopMatrix();
}
glutSwapBuffers();
}
void mouseclick(
int button,
int state,
int mouse_x,
int mouse_y )
{
int const window_width = glutGet(GLUT_WINDOW_WIDTH);
int const window_height = glutGet(GLUT_WINDOW_HEIGHT);
float const window_aspect = (float)window_width / (float)window_height;
v2f_t const sc = {
(window_aspect > 1.0 ? window_aspect : 1.) *
( ((float)mouse_x / (float)window_width )*2. - 1.),
(window_aspect < 1.0 ? 1./window_aspect : 1.) *
( -((float)mouse_y / (float)window_height)*2. + 1.)
};
sphere_centers.push_back(sc);
glutPostRedisplay();
}
int main(
int argc,
char *argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow("Click to place spheres");
glutDisplayFunc(display);
glutMouseFunc(mouseclick);
glutMainLoop();
return 0;
};
You need to first create the transformation matrix, then draw. In other words:
glTranslatef(X,Y,Z); /* everything from here below would be translated */
glutWireSphere(3,100,100); /* draw with the current transformation matrix */

Drawing a ball and two cones in OpenGL C++

I have a code where I want to draw a bowl and two cones at a time.
But, it is showing only those cones, not showing the ball.
#include <GL/glut.h>
#include <stdlib.h>
#include <Math.h> // Needed for sin, cos
#define PI 3.14159265f
GLfloat ballRadius = 0.5f; // Radius of the bouncing ball
GLfloat ballX = 0.0f; // Ball's center (x, y) position
GLfloat ballY = 0.0f;
GLfloat ballXMax, ballXMin, ballYMax, ballYMin; // Ball's center (x, y) bounds
GLfloat xSpeed = 0.02f; // Ball's speed in x and y directions
GLfloat ySpeed = 0.007f;
int refreshMillis = 30; // Refresh period in milliseconds
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
}
static void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// This is ball's code that is not being drawn.
***glTranslatef(ballX, ballY, 0.0f); // Translate to (xPos, yPos)
// Use triangular segments to form a circle
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f, 0.0f, 0.0f); // Blue
glVertex2f(0.0f, 0.0f); // Center of circle
int numSegments = 100;
GLfloat angle;
for (int i = 0; i <= numSegments; i++) { // Last vertex same as first vertex
angle = i * 2.0f * PI / numSegments; // 360 deg for all segments
glVertex2f(cos(angle) * ballRadius, sin(angle) * ballRadius);
}
glEnd();***
//End of ball code
glColor3d(0,1,0);
glPushMatrix();
glTranslated(-1.0,0.5,-6);
glRotated(65, -1.0, 0.0, 0.0);
glutSolidCone(1, 2, 70, 50);
glPopMatrix();
glPushMatrix();
glTranslated(0.0,-1.5,-6);
glRotated(65, -1.0, 3.0, 0.0);
glutWireCone(1,2, 16, 16);
glPopMatrix();
glutSwapBuffers();
}
/* Program entry point */
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(740,580);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Programming Techniques - 3D Cones");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glClearColor(1,1,1,1);
glutMainLoop();
return EXIT_SUCCESS;
}
The reason you don't see the circle is that it's clipped against the near plane. With glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); you specify that the near plane is at z = -2, and the far plane at z = -100. Anything outside these values are clipped. But by using glVertex2, your z values for the circle vertices are 0, so all of them are clipped. You can fix it by calling glTranslatef(ballX, ballY, -10.0f); instead.
A couple more pointers:
Always reset the matrix mode to GL_MODELVIEW (e.g. in your resize() function). You don't have to, but it's a good convention.
Always glPush/PopMatrix() before modifying the matrix stack (e.g. when translating the circle).
glColor3f(1.0f, 0.0f, 0.0f); // Blue? ;)