I have set up a mouse function which is called in my main() like so:
struct point
{
int x;
int y;
};
std::vector <point> points;
point OnePoint;
void processMouse(int button, int state, int x, int y)
{
if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
{
int yy;
yy = glutGet(GLUT_WINDOW_HEIGHT);
y = yy - y; /* In Glut, Y coordinate increases from top to bottom */
OnePoint.x = x;
OnePoint.y = y;
points.push_back(OnePoint);
}
glutPostRedisplay();
}
and to print a line through the vertices I have written some code in my display function that allows me to do just that:
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
for (int i = 0; i < points.size();i++)
{
glVertex2i(points[i].x, points[i].y);
}
glEnd();
However now what I want to do is move all the lines either left or right when I click the correct arrow keys to do so, but I can't figure out how.
I'm aware that it could possibly be something like:
glVertex2i(points[i].x + 10, points[i].y); // moving points 10 along the x axis
However since i is out of the for loop, I get error messages
You should introduce a new variable:
std::vector <point> points;
point offset; // <- how much to offset points
Make sure to set it to zero during initialization.
Then in the drawing code you add that offset to each point:
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
for (int i = 0; i < points.size();i++)
glVertex2i(points[i].x + offset.x, points[i].y + offset.y);
glEnd();
Or use a translation matrix to do that automagically:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(offset.x, offset.y, 0);
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
for (int i = 0; i < points.size();i++)
glVertex2i(points[i].x, points[i].y);
glEnd();
glPopMatrix();
On the key-press handler you just change the offset:
// left-arrow:
offset.x -= 1;
// right-arrow:
offset.x += 1;
...
Related
I am working on an nbody simulator and I want to display it with OpenGL. I want to always be looking at the centre of mass reference frame. I have the following code. I calculate the COM and I set the center coordinate in the gluLookAt function to be the center of mass. I then subtract the "zoom" from the z coordinate to get the eye position. By logic this should ensure that I am always looking at whatever value the center of mass is. The only issue is that I marked where the center of mass should be on the screen with a red dot and it is moving. Shouldn't it never move if I am always looking at it from the same relative position? Here is my code. Focus on the display function since I assume that is where the error will be. I had similar code working in another project and I can't really find any differences.
#include "Universe.cuh"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "timer.hpp"
#include <GL/glut.h>
Universe u;
float* vbuf;
double angle = 0.0, zoom = 1000;
void display()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
float3 c = u.getCenterOfMass();
gluLookAt(c.x, c.y, c.z - zoom, c.x, c.y, c.z, 0, 1, 0);
glScalef(0.1, 0.1, 0.1);
glRotated(angle, 1, 0, 0);
glColor4f(1, 1, 1, 0.25);
glBegin(GL_POINTS);
{
glColor3f(1.0, 0.0, 0.0);
glVertex3d(c.x, c.y, c.z);
}
glEnd();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (double)w / (double)h, 1.0, zoom * 1e9);
glMatrixMode(GL_MODELVIEW);
}
void copy_to_vbuf()
{
for(int i = 0; i < u.size(); i++)
{
vbuf[3 * i + 0] = u.getObjects()[i].p.x;
vbuf[3 * i + 1] = u.getObjects()[i].p.y;
vbuf[3 * i + 2] = u.getObjects()[i].p.z;
}
}
void keyboard(unsigned char c, int x, int y)
{
if(c == 'w')
angle += 1;
else if(c == 's')
angle -= 1;
else if(c == '=')
zoom /= 1.2;
else if(c == '-')
zoom *= 1.2;
glutPostRedisplay();
}
void idle()
{
u.timeStep();
copy_to_vbuf();
glutPostRedisplay();
}
int main(int argc, char** argv)
{
cudaSetDevice(0);
srand(time(0));
u.getConfiguration().max_velocity = 10;
u.getConfiguration().softening_factor = 0.01;
u.getConfiguration().threshold_angle = 35;
u.getConfiguration().time_step = 0.1;
const int N = 5;
vbuf = new float[3 * N];
for(int i = 0; i < N; i++)
{
Object o;
o.m = rand() % 100 + 1;
o.p.x = 500.0 * rand() / RAND_MAX - 250.0;
o.p.y = 500.0 * rand() / RAND_MAX - 250.0;
o.p.z = 500.0 * rand() / RAND_MAX - 250.0;
u.addObject(o);
}
copy_to_vbuf();
glutInit(&argc, argv);
glutInitDisplayMode(GL_DOUBLE);
glutInitWindowSize(1000, 1000);
glutCreateWindow("N-Body");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPointSize(1.0);
glutMainLoop();
return 0;
}
Two points regarding:
glScalef(0.1, 0.1, 0.1);
glRotated(angle, 1, 0, 0);
Since your axis is not centered on the 'COM', when you apply rotation the COM point will not stay in place and logically would move around the screen.
AFIK the normal order is scale,rotate,translate for transformations. This will apply the rotation and then scale.
EDIT:
To expand on that: Currently you take an arbitrary point rotate it, scale it and then focus on the point where it used to be. If you want to rotate your model (e.g. point marking the 'COM') around itself, it needs to be centered at (0,0,0).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
So I have this code that produces fireworks using what appears to be a particle effect, but I don't understand what is going on in the code. Could someone explain it to me, particularly the initialize function and the draw blast blast function. If you could annotate it with notes that would be super.
/* fireworks.c - simulate fireworks with particle systems */
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
//to correct ASCI deviations in Microsoft VC++ 6.0
#define M_PI (3.1415926535897932384626433832795)
double drand48()
{ return (rand()%10000)/10000.0; }
//end of corrections
#endif
#define MAX_POINTS 5000
int numPoints;
GLfloat curx, cury;
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
GLfloat red, green, blue;
int step; int length;
void initialize()
{ int j; double temp, temp2;
numPoints = drand48()*(MAX_POINTS-1);
curx = -0.5 + drand48();
cury = 0.0 + drand48();
red = 0.5 + 0.5*drand48();
green = 0.5 + 0.5*drand48();
blue = 0.5 + 0.5*drand48();
glPointSize(1.5);
step = 0;
length = 700 + 300*drand48();
/* initialize the blast */
for (j=0 ; j<numPoints ; j++ ) {
x[j] = curx;
y[j] = cury;
temp = drand48();
temp2 = drand48()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp)/length;
yacc[j] = (sin(temp2) * temp)/length;
}
}
void draw_blast(void)
{ int i;
double glow = (length - step) / (double)length;
glColor3f(red*glow, green*glow, blue*glow);
glBegin(GL_POINTS);
for (i=0;i<numPoints;i++) {
x[i] += xacc[i];
y[i] += yacc[i];
glVertex2f(x[i], y[i]);
}
glEnd();
glFlush();
glutSwapBuffers();
}
void display(void)
{ int i;
glClear(GL_COLOR_BUFFER_BIT);
if (step < 0.9*length) {
for (i=0; i<numPoints; i++)
yacc[i] -= 0.02 / length; // gravity
draw_blast();
}
step ++;
if (step > length) initialize();
}
void idle(void)
{
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: exit(0); break;
}
}
void reshape (int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0,
-1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w,
-1.0, 1.0);
else
glOrtho(-1.0*(GLfloat)w/(GLfloat)h, 1.0*(GLfloat)w/(GLfloat)h,
-1.0, 1.0,
-1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (800, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow ("Fireworks");
glClearColor (0.0, 0.0, 0.0, 0.0);
initialize();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Yes, it is a particle system. However - not a particularly efficient one.
Let's go through it step by step:
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
x and y hold the particles' positions. xacc and yacc hold their velocities.
In initialize:
numPoints = drand48()*(MAX_POINTS-1);
This sets a random number of particles...
curx = -0.5 + drand48();
cury = 0.0 + drand48();
red = 0.5 + 0.5*drand48();
green = 0.5 + 0.5*drand48();
blue = 0.5 + 0.5*drand48();
glPointSize(1.5);
step = 0;
length = 700 + 300*drand48();
... with a random center position, color, and radius (length).
for (j=0 ; j<numPoints ; j++ ) {
This starts the initialization for every particle.
x[j] = curx;
y[j] = cury;
Sets the particle's position the the center position.
temp = drand48();
temp2 = drand48()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp)/length;
yacc[j] = (sin(temp2) * temp)/length;
Sets a random direction of the particle (temp2) and a random velocity based on the system's radius (temp / length).
In drawBlast():
double glow = (length - step) / (double)length;
glColor3f(red*glow, green*glow, blue*glow);
Slowly fades the particles' color to black.
x[i] += xacc[i];
y[i] += yacc[i];
Advance the particle by their velocity. This assumes a constant frame rate.
glVertex2f(x[i], y[i]);
Draw the particle as a point.
In display():
yacc[i] -= 0.02 / length; // gravity
Accelerate every particle downwards. I.e. simulate that the particles fall.
I'm trying to do selection in opengl but it is not working.
I draw objects I receive from a .obj file (v, vn, f, o and such indices). Each object consists from "groups" and each group is a group of GL_POLYGON.
Here is the draw function:
void draw(GLenum mode) {
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(100.0, 0.0, 0.0);
glColor3f(0, 0, 1);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 100.0, 0.0);
glColor3f(0, 1, 0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 100.0);
glEnd();
glColor4f(1.0, 1.0, 1.0, 1.0);
if (changeFOV) {
fovAngle += fovScale;
changeFOV = false;
setTransformations();
}
for (unsigned int i = 0; i < objects.size(); i++) {
objectItem currObject = objects[i];
for (unsigned int j = 0; j < currObject.getGroups().size(); j++) {
group currGroup = currObject.getGroups().at(j);
for (unsigned int k = 0; k < currGroup.getFs().size(); k++) {
if (mode == GL_SELECT)
glPushName(currGroup.getName());
glPushMatrix();
vector<pair<int, int> > currF = currGroup.getFs()[k];
glBegin(GL_POLYGON);
for (unsigned int kk = 0; kk < currF.size(); kk++) {
Vector3f currVertex = vertexes.at(
(currF.at(kk).first - 1 >= 0) ?
currF.at(kk).first - 1 : 0);
Vector3f currNormal = vertexesNormal.at(
(currF.at(kk).second - 1 >= 0) ?
currF.at(kk).second - 1 : 0);
glNormal3f(currNormal.x, currNormal.y, currNormal.z);
glVertex3f(currVertex.x / 1, currVertex.y / 1,
currVertex.z / 1);
}
glEnd();
glPopMatrix();
}
}
}
}
The drawing works ok and I see the object on the screen.
This is all the picking procedure
/* PICKING */
void processHits(GLint hits, GLuint *buffer) {
float z1, z2;
for (int i = 0; buffer[i] > 0; i += 5) {
z1 = buffer[i + 1] / 4294967295.0;
z2 = buffer[i + 2] / 4294967295.0;
printf("z1 = %f ,z2 = %f zValue = %f\n", z1, z2, zValue[0]);
if ((zValue[0] <= z1 + 0.0001 && zValue[0] >= z2 - 0.0001)
|| (zValue[0] >= z1 - 0.0001 && zValue[0] <= z2 + 0.0001)) { //try to locate which name is correlated with the pressed pixel according to z value
ii = buffer[i + 3];
jj = buffer[i + 4];
}
}
}
void startPicking(GLuint *selectionBuf) {
glSelectBuffer(bufSize, selectionBuf); //declare buffer for input in selection mode
glRenderMode(GL_SELECT); //change to selecting mode
glInitNames(); //initialize names stack
glPushName(-1); //push name
}
void pick(int button, int x, int y) {
//use selection mode to pick
glReadPixels(x, viewport[3] - y, 1, 1, GL_RGBA, GL_FLOAT, pix);
//printf("depth = %f, x = %d, y = %d\n",pixels[(viewport[3]-y)*512+x],x,viewport[3]-y);
glMatrixMode(GL_PROJECTION);
glReadPixels((GLdouble) x, (GLdouble) viewport[3] - y, 2, 2,
GL_DEPTH_COMPONENT, GL_FLOAT, zValue);
glPushMatrix(); //saves current projection matrix
startPicking(selectionBuf); //preper selection mode
glLoadIdentity();
gluPickMatrix((GLdouble) x, (GLdouble) viewport[3] - y, 1, 1, viewport); //change matrices so only the area of the picking pixel can be seen.
gluPerspective(fovAngle, 1, near, far); //return to perspective state
glMatrixMode(GL_MODELVIEW);
draw(GL_SELECT); //draws board on background
hits = glRenderMode(GL_RENDER); //gets hits number
glMatrixMode(GL_PROJECTION);
glPopMatrix(); //restores projection matrix
glMatrixMode(GL_MODELVIEW);
processHits(hits, selectionBuf); //check hits
if(hits > 0)
printf("touched: %d\n",selectionBuf[3]);
//printf("depth %f hits: %d\n\n",pixels[(viewport[3]-y)*512+x], hits);
if (zValue[0] < 1.0) {
isPick = true;
xx = x;
yy = y;
if (button == GLUT_RIGHT_BUTTON)
zMove = true;
else
zMove = false;
}
}
the pick function is called when the mouse is clicked (using opengl mouse function).
The error I'm receiving is that no objects appears to be hit when clicking on an object.
I'm using Ubuntu 14.04 LTS with Opengl 3.0
I don't know how to ask or what specifically ask, I would appreciate some inputs on the code if you see something wrong..
You seemed to have missed using glPopName()
GLNames used in the selection buffer are pushed on a stack. So unless you call glPopName() the stack would never unwind. The working of this is similar to the calls glPushMatrix() and glPopMatrix().
Typically this is what the code flow looks like.
//Push the name of the primitives on top of selection stack
glPushName(...)
//Set Transformations / Draw the primitives
..
..
//Pop the name (Clear the stack for pushing another name)
glPopName();
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();
}
this program creates an image with 100 boxes, after the box is created, it's 4 coordinates are stored in the index of the class array Tile so I can refernce each tile later in my code. This works fine, excpect that I can not reference the Tile array in my main function, only in the Draw() function where it is created. Any solutions would be appreciated.
EDIT: Making Tiles* Tile[100] global does not seem to solve the issue.
Simplified Code:
#include <iostream>
class Tiles {
public:
Tiles() : mA (1){}
double mA;
};
void Function1() {
Tiles Tile[5];
Tile[1].mA = 10;
}
int main(int iArgc, char** cppArgv) {
Function1();
Tile[1].mA = 2; // ERROR "Tile" is unidentified.
return 0;
}
Full Code:
#include <iostream>
#include <glut.h>
class Tiles {
public:
Tiles() : mA () , mB() , mC() , mD() , mCP(){}
double mA[2] , mB[2] , mC[2] , mD[2] , mCP[2];
};
void Draw() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
double dX1 = 0.0, dY1 = 0.0, dMidX = 0.0, dMidY = 0.0, dXC = 0.0, dYC = 0.0;
int sq = 0, row = 1, CoordMap = 0;
Tiles Tile[100];
//Tiles* Tile = new Tiles[100]; doesnt seem to be any different..
for (int i=0; i < 10;i++ ) { // ROWS
for (int i2=0; i2 < 10; i2++) { // BOXES
glBegin(GL_LINE_STRIP);
glVertex3f(dX1, dY1, 0.0);
Tile[sq].mA[1] = dX1;
Tile[sq].mA[2] = dY1;// Bottom Left
dX1 = dX1 + .1;
dXC = dX1;
dYC = dY1;
glVertex3f(dX1, dY1, 0.0);
Tile[sq].mB[1] = dX1;
Tile[sq].mB[2] = dY1;// Bottom Right
dY1 = dY1 + .1;
glVertex3f(dX1, dY1, 0.0);
Tile[sq].mC[1] = dX1;
Tile[sq].mC[2] = dY1;// Top Left
dX1 = dX1 - .1;
glVertex3f(dX1, dY1, 0.0);
Tile[sq].mD[1] = dX1;
Tile[sq].mD[2] = dY1;// Top Right
glEnd();
glBegin(GL_POINTS);
glVertex3f((dX1 + .05) , (dY1 - .05), 0.0);
glEnd();
++sq;
dX1 = dXC;
dY1 = dYC;
}
row++;
dX1 = 0.0;
dY1 = ((row * .1) - .1);
}
glFlush();
}
void Initialize() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(250, 250);
glutInitWindowPosition(200, 200);
glutCreateWindow("XoaX.net");
Initialize();
glutDisplayFunc(Draw);
glutMainLoop();
//Tile[2].mA[1] = 2; //
return 0;
}
This code is modified from it's orginal version written by XoaX - Michael Hall.
Thank you
To make your Tiles array accesible from main() you must declare Tiles within the main() scope. For example, move your declaration Tiles Tile[100]; to global scope, i.e. just before void Draw() { line.
If you want to make it accessible from main, the answer is to move it to global scope, but..
You're using openGL and glut here, and you're calling glutMainLoop just before accessing Tile in main().. as written in the specification, glutMainLoop never return once called..
if by chances, you're trying to cout the value before the call to glutMainLoop, the draw method will not have been called, since it was called from within glutMainLoop.. which make the value to still be 0..
references : http://www.opengl.org/documentation/specs/glut/spec3/node14.html