Updating a graph through C++ and GLUT - c++

I have written a c++ program in Xcode to implement Symbolic Regression & Genetic Programming. I'd like to create a window to visualize the reference data (an array of 2d points) and the best function that the program generates each generation.
To put it simply, I'd like the window to show 2 graphs, and have it be updated with a for loop. From what I understand, GLUT seems like a good framework, and I've written a function to display the reference data (std::vector is how I'm storing the "referenceDataSet" variable):
void renderScene(){
// The min/max variables are just for scaling & centering the graph
double minX, maxX, minY, maxY;
minX = referenceDataSet[0].first;
maxX = referenceDataSet[0].first;
minY = referenceDataSet[0].second;
maxY = referenceDataSet[0].second;
for (int i = 0; i < referenceDataSet.size(); i++) {
minX = min(minX, referenceDataSet[i].first);
maxX = max(maxX, referenceDataSet[i].first);
minY = min(minY, referenceDataSet[i].second);
maxY = max(maxY, referenceDataSet[i].second);
}
glLoadIdentity ();
glClear(GL_COLOR_BUFFER_BIT);
glBegin( GL_LINE_STRIP );
glColor4f( 1.0, 0.0, 0.0, 1.0);
for (int i = 0; i < referenceDataSet.size(); i++) {
glVertex2f((referenceDataSet[i].first-minX)/(maxX-minX)-0.5, (referenceDataSet[i].second-minY)/(maxY-minY)-0.5);
}
glEnd();
glFlush();
}
void renderInit(int argc, char **argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(600, 600);
glutCreateWindow("");
glutDisplayFunc(renderScene);
glutCheckLoop();
}
The problem with this is that I'm not sure how I should go about updating the window, or drawing a second graph that constantly changes.
Also, this is my first question on Stack Overflow, so I apologize if I'm not doing something correctly here, or if any of this is difficult to understand. I searched as best I could for the answer, but couldn't really find anything relevant.

In glut or OpenGL, glutIdleFunc(void (*func)(void)) is used to update the scene.
The idle func will call the glutDisplayFunc every time the scene refreshes.
Reference is here http://www.opengl.org/resources/libraries/glut/spec3/node63.html
I guess renderScene() is your glutDisplayFunc. And you need to register an idle function using glutIdleFunc. In the idle function, you can change the parameters for the second graph that constantly changes, and renderScene() will be called again after changes in the idle function are done.

Related

OGLFT draws text when GLStipple is used

I have an interesting bug that has been "bugging" me for a few days now.
I am currently using OpenGL to draw text on a screen. I am utilizing the OGLFT library to assist the drawing. This library actually uses the freetype2 library. I am actually not doing anything special with the text. I am only looking for monochromatic text.
Anyways, after implementing the library, I noticed that the text is only drawn correct when I have glStipple enabled. I believe that there is some interference issue between the OGLFT library and what I am enabling.
I was wondering if there is anyone out there with some experience on using the OGLFT library. I am posting a minimalist example of my code to demonstrate what is going on:
(Please note that there are some variables that are used to st the zoom factor of my glCanvas and the position of the camera and that this is only for 2D)
double _zoomX = 1.0;
double _zoomY = 1.0;
double _cameraX = 0;
double _cameraY = 0;
/* This function gets called everytime a draw routine is needed */
void modelDefinition::onPaintCanvas(wxPaintEvent &event)
{
wxGLCanvas::SetCurrent(*_geometryContext);// This will make sure the the openGL commands are routed to the wxGLCanvas object
wxPaintDC dc(this);// This is required for drawing
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
updateProjection();
OGLFT::Monochrome *testface = new OGLFT::Monochrome( "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 8);
testface->draw(0, 0, "test");
glEnable(GL_LINE_STIPPLE);// WHen I comment out this line, the text is unable to be drawn
glLineStipple(1, 0b0001100011000110);
glBegin(GL_LINES);
glVertex2d(_startPoint.x, _startPoint.y);
glVertex2d(_endPoint.x, _endPoint.y);
glEnd();
glDisable(GL_LINE_STIPPLE);
SwapBuffers();
}
void modelDefinition::updateProjection()
{
// First, load the projection matrix and reset the view to a default view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-_zoomX, _zoomX, -_zoomY, _zoomY, -1.0, 1.0);
//Reset to modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, (double)this->GetSize().GetWidth(), (double)this->GetSize().GetHeight());
/* This section will handle the translation (panning) and scaled (zooming).
* Needs to be called each time a draw occurs in order to update the placement of all the components */
if(_zoomX < 1e-9 || _zoomY < 1e-9)
{
_zoomX = 1e-9;
_zoomY = _zoomX;
}
if(_zoomX > 1e6 || _zoomY > 1e6)
{
_zoomX = 1e6;
_zoomY = _zoomX;
}
glTranslated(-_cameraX, -_cameraY, 0.0);
}
Also one thing to note is that the code below the glEnable(GL_LINE_STIPPLE); is required. It is as if the glStipple needs to be drawn correctly for the text to be displayed correctly.
Looking through your code, I believe that your intention is to render it as a greyscale? If so, then you can simply use the OGLFT::Grayscale *testface = new OGLFT::Grayscale( "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 8);
This will get what you need without having to worry about the issue that you posted. In fact, I recommend doing it this way too.

Loading a model and displaying it using OpenGL?

I am tring to load the model and display it using OpenGL. The code runs fine with no errors but nothing is displayed. Can someone help me regarding this issue?
The source code:
int cube;
int number_faces;
int number_vertices;
struct coordinate {
float x, y, z;
coordinate(float a, float b, float c): x(a), y(b), z(c) {};
};
struct face {
int faces[3];
face (int f1, int f2, int f3){
faces[0] = f1;
faces[1] = f2;
faces[2] = f3;
};
};
// function prototype
bool loadObject(const char * file_name);
int main(int argc, char ** argv)
{
//initialize Glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(w_x_position, w_y_position);
glutInitWindowSize(w_width, w_height);
glutCreateWindow("Assignment 1");
//function call
init();
glutDisplayFunc(display);
//loop main
glutMainLoop();
return 0;
}
bool loadObject(const char * file_name){
//initialize stuff
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//create the vectors that will hold the file coordinates
std::vector<std::string*> points;
std::vector<coordinate*> vertex;
std::vector<face*> faces;
//check if the file opens
if ( !file_name ) {
return false;
}
// open file
FILE *fp = fopen( file_name, "r" );
if ( !fp ) {
return false;
}
// num of vertices and indices
fscanf( fp, "data%d%d", &number_vertices, &number_faces);
//push the content into the vertexs
for(int i=0;i<number_vertices;i++) {
float x_temp, y_temp, z_temp;
fscanf( fp, "%f%f%f", &x_temp, &y_temp,&z_temp );
vertex.push_back(new coordinate(x_temp, y_temp, z_temp));
}
for (int y=0; y<number_faces;y++){
int a,b,c;
fscanf( fp, "%d%d%d", &a, &b, &c);
faces.push_back(new face(a, b, c));
}
//draw the modle
int number;
number = glGenLists(1);
glNewList(number, GL_COMPILE);
for(int i =0; i <faces.size();i++){
glBegin(GL_TRIANGLES);
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 the poiters for memory space
for(int i=0;i<points.size();i++){
delete points[i];
}
for(int i=0;i<faces.size();i++){
delete faces[i];
}
for(int i=0;i<vertex.size();i++){
delete vertex[i];
}
return number;
}
First of all I guess you are mixing something up.
The steps should be:
Start the programm
Create everything that is needed for OpenGL
Load your model. You just need to do this once. For modern openGL you can create a so called VertexBuffer for storing you vertices.
Start the GameLoop which normally should have at least three parts
parse the input from the player like KeyBoard and Mouse
Update the scene corresponding to your game logic and the input of the user
Draw everything to the screen
If the user decided so, close the program and clean everything up.
Using glut you can provide function pointer to glut which calls your input, update and reder method, There is also an idle method and various other you can provide, so you do not need to make your own loop.
The 2nd problem I can see in your code beside the not so good structure is that you are missing to set a Modelview Matrix. You've just set a projection matrix and no modelMatrix. But for a better understanding just let me explain a bit more about the render part of the gameLoop.
The render method will draw everything to the screen/window. For each model you have to provide a modelview matrix which will translate, rotate and scale the mesh/model and a projectionmatrix which will bring the 3D world to a 2D screen (There is a bit more about math and a lot more details but we will keep it short and easy here). In older versions of OpenGL there is already a stack implemented on which you can push or pop the matrices. The matrix on top of the stack will be used to draw the mesh. If you want another projection and/or modelmatrix for a 2nd or 3rd mesh just change the matrix on top of the stack. During the loading of a mesh you do not need to priovide any other information. Just position, uv or color for each vertex.
You drawing will be roughly like this (pseudocode):
ClearEverythingFromLastCall();
glMatrixMode(GL_PROJECTION);
SetProjectionMatrixOnStack(); (pushMatrix)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
ChangeMatrixForCurrentObject();
drawObject();
glutSwapBuffers(); // This shpuld be the last line of you method
drawObject depends on what technique you are using (fixedFunctionPipeline from older OpenGL versions, or the programmable pipeline from OpenGL 3.0 and newer (which I think is the better one)).
So there are a lot of errors in you code and not the "one" little bug which breaks you code. I highly recommend to start with a good tutorial. For older OpenGL I recommend http://nehe.gamedev.net/ or http://videotutorialsrock.com/ (If you are able to speak german I can give you some tutorials in german also). Both start from the very beginning with the fixed pipeline.

Mouse-drag object in OpenGL/GLUT [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I have been searching all day for a tutorial or example code for a simple program - click on object (like a 2D rectangle for example) then as you hold and move the mouse the object follows the mouse, then on mouse release the object remains in new location. In other words, I want to understand how to drag and drop an object with the mouse events.
Could anyone help to point me in the right direction of any useful sources of information relating to this problem?
Thanks for all the responses so far.
I have worked out how to do it, so I will go ahead an answer my own question.
I am using GLUT as a mouse handler:
When the mouse is clicked and moving (glutMotionFunc) the drag function is called.
In the drag function the mouse coordinates (x,y) are converted to a Points struct while being converted into window coordinates.
If the mouse is within the square then drag the square by changing it's coordinates and redisplay.
I am still very new to OpenGL and C++ so I do apologize for the messy coding. I am a bit frustrated in doing it this way as the redrawn square makes it seem the cursor snaps to the center. I welcome alternative solutions to this problem and criticism of my code, for learning purposes.
CODE (included glut and using namespace std):
// points structure made of two coordinates; x and y
struct Points
{
float x,y; // initializor
Points() { x = 0.0; y = 0.0; } // constructor
Points(float _x, float _y) : x(_x), y(_y) {}
};
// square made of 4 points
class Square
{
public:
Points pts[4]; // square structure
Square(); // initialize constructor
void draw(Square *sqr); // draw square
Points mouse(int x, int y); // get mouse coordintaes
Square* drag(Square *sqr, Points *mouse); // change points of sqr
};
// square constructor
Square::Square()
{
pts[0] = Points(0.2,0.2);
pts[1] = Points(0.4,0.2);
pts[2] = Points(0.4,0.4);
pts[3] = Points(0.2,0.4);
};
// draw function
void Square::draw(Square *sqr)
{
// draw square fill
int i;
glColor3f(0.2, 0.2, 0.2);
glBegin(GL_QUADS);
for (i = 0; i < 4; ++i)
{
glVertex2f(sqr->pts[i].x, sqr->pts[i].y);
}
glEnd();
// draw square points
i = 0;
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; ++i)
{
glVertex2f(sqr->pts[i].x, sqr->pts[i].y);
}
glEnd();
}
// mouse function
Points Square::mouse(int x, int y)
{
int windowWidth = 400, windowHeight = 400;
return Points(float(x)/windowWidth, 1.0 - float(y)/windowHeight);
}
// drag function
Square* Square::drag(Square *sqr, Points *mouse)
{
sqr->pts[0].x = mouse->x - 0.1;
sqr->pts[0].y = mouse->y - 0.1;
sqr->pts[1].x = mouse->x + 0.1;
sqr->pts[1].y = mouse->y - 0.1;
sqr->pts[3].x = mouse->x - 0.1;
sqr->pts[3].y = mouse->y + 0.1;
sqr->pts[2].x = mouse->x + 0.1;
sqr->pts[2].y = mouse->y + 0.1;
return sqr;
}
// GLOBAL
// create square object
Square* sqr = new Square;
// display at start
void display() {
glClear(GL_COLOR_BUFFER_BIT);
sqr->draw(sqr);
glFlush();
}
// drag function
void drag (int x, int y)
{
// int x and y of mouse converts to screen coordinates
// returns the point as mousePt
Points mousePt = sqr->mouse(x,y);
//create pointer to window point coordinates
Points* mouse = &mousePt;
// if the mouse is within the square
if (mouse->x > sqr->pts[0].x && mouse->y > sqr->pts[0].y)
{
if (mouse->x < sqr->pts[2].x && mouse->y < sqr->pts[2].y)
{
// then drag by chaning square coordinates relative to mouse
sqr->drag(sqr,mouse);
glutPostRedisplay();
}
}
}
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(400, 400);
glutInitWindowPosition(200, 200);
glutCreateWindow("Move Box");
glutMotionFunc(drag);
Initialize();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
OpenGL is only concerned with the drawing process. Everything else (mouse input, object picking, scene management/alterations, etc.) is completely up to you to implement.
Here's a rough outline:
Install a mouse click event handler (the exact method to use depends on the framework used and/or the operating system)
In the mouse click event handler perform a picking operation. This usually involves unprojecting the mouse window position into the world space (see gluUnproject) resulting in a ray. Test each object in the scene if it intersects with the ray; you'll have to implement this yourself, because OpenGL just draws thing (there is no such thing as a "scene" in OpenGL).
If a object has been picked register it to be manipulated in the mouse drag handler
everytime a mouse drag event happens adjust the object's position data and trigger of the OpenGL display (you always redraw the whole thing in OpenGL).
When the mouse is released unregister the object from the drag handler.
As mentioned by others, OpenGL does not handle user input. You want to use a library for that. If you want a more all-around solution, you can even use a more complete render or physics engine.
For simple user input, you can use SDL (e.g. this is for mouse input).
For more complete 2D stuff, you can just use Box2D. Here are a whole bunch of tutorials.
The heavy-weight solution is a complete render engine, such as Ogre3D or CrystalSpace.
As mentioned by others, you need to get a mouse handler to get the mouse position first. Then you need a way to pick an object. You have a few options to do the picking in OpenGL.
If you are using classic OpenGL, you can use the select buffer. The following link is a good tutorial
http://www.lighthouse3d.com/opengl/picking/index.php3?openglway
If you are using modern opengl, which is shader based, you can use FBO based picking.
http://ogldev.atspace.co.uk/www/tutorial29/tutorial29.html
You can always implement a ray tracking picking yourself in both cases. The gluUnproject can help a lot in the implementation.
http://schabby.de/picking-opengl-ray-tracing/
After that, you just need to update the object position according to the mouse movement or acceleration.

suspend a function for sometime in opengl

I have a function Drwa() this is rendering a triangle on screen.and also i have another Draw_poly() which is rendering a Rectangle on screen. And i also i m rotating rectangle and triangle both simultaneously.I want to keep speed of rotation different for both how will i do ?
Let suppose i am moving an object on screen and another i m rotating then how will i do ? That's why i m looking for function moving of object will keep time limited and rotating object will not keep time.So rotation will be fast and moving of object will be slow
First, define your rotation as angle per second. Then in your main draw function, compute the elapsed time in second, multiply by the angular speed, and you're done.
I would like to partecipate with a an answer of mine.
The answer of genpfault could be good as much as you need, but if you would like to produce a good animation you need to design a better software.
Here, look at my answer. However, reading another your question, I think you are missing some fundamental point: learn OpenGL architecture, practice on each OpenGL entry point, read books.
At last, but not least, I would you suggest to search for answer already told on stackoverflow. This is supposed to be a question & answer site...
Rotate one less/slower than the other:
static float rot_a = 0.0;
static float rot_b = 0.0;
rot_a += 1.0;
rot_b += 0.5;
glPushMatrix();
glRotatef( rot_a, 0, 0, 1 );
Draw_A();
glPopMatrix();
glPushMatrix();
glRotatef( rot_b, 0, 0, 1 );
Draw_B();
glPopMatrix();
Alternatively you can spin up some threads that modify your object positions and sleep() without blocking the render thread.
Position obj_a;
Position obj_b;
void thread_1()
{
while( !done )
{
sleep(1);
modify_pos( obj_a );
}
}
void thread_2()
{
while( !done )
{
sleep(2);
modify_pos( obj_b );
}
}
void draw()
{
glPushMatrix();
position_object( obj_a );
Draw_A();
glPopMatrix();
glPushMatrix();
position_object( obj_b );
Draw_B();
glPopMatrix();
}
int main()
{
...
launch_thread( thread_1 );
launch_thread( thread_2 );
...
return 0;
}

Limit Speed Of Gameplay On Different Computers

I'm creating a 2D game using OpenGL and C++.
I want it so that the game runs at the same speed on different computers, At the moment my game runs faster on my desktop than my laptop (i.e. my player moves faster on my desktop)
I was told about QueryPerformanceCounter() but I don't know how to use this.
how do I use that or is there a better/easier way?
My Display function
void display()
{
static long timestamp = clock();
// First frame will have zero delta, but this is just an example.
float delta = (float)(clock() - timestamp) / CLOCKS_PER_SEC;
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
createBackground();
int curSpeed = (player.getVelocity()/player.getMaxSpeed())*100;
glColor3f(1.0,0.0,0.0);
glRasterPos2i(-screenWidth+20,screenHeight-50);
glPrint("Speed: %i",curSpeed);
glRasterPos2i(screenWidth-200,screenHeight-50);
glPrint("Lives: %i",lives);
glRasterPos2i(screenWidth-800,screenHeight-50);
glPrint("Heading: %f",player.getHeading());
for(int i = 0;i<90;i++){
if (numBullets[i].fireStatus == true){
numBullets[i].updatePosition(player);
if (numBullets[i].getXPos() > screenWidth || numBullets[i].getXPos() < -screenWidth || numBullets[i].getYPos() > screenHeight || numBullets[i].getYPos() < -screenHeight ){
numBullets[i].fireStatus = false;
numBullets[i].reset(player);
numBullets[i].~Bullet();
}
}
}
player.updatePosition(playerTex,delta);
glFlush();
timestamp = clock();
}
My Update positiom method
void Player::updatePosition(GLuint playerTex, float factor){
//draw triangle
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, playerTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTranslatef(factor*XPos, factor*YPos, 0.0);
glRotatef(heading, 0,0,1);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glTexCoord2f(0.0, 1.0); glVertex2f(-40,40);
glTexCoord2f(0.0, 0.0); glVertex2f(-40,-40);
glTexCoord2f(1.0, 0.0); glVertex2f(40,-40);
glTexCoord2f(1.0, 1.0); glVertex2f(40,40);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
XPos += speed*cos((90+heading)*(PI/180.0f));
YPos += speed*sin((90+heading)*(PI/180.0f));
}
As a rule, you want to do all gameplay calculations based on a time delta, i.e. the amount of time that has passed since the last frame. This will standardize speed on all machines. Unless you want extreme precision, you can use clock() (from <ctime>) to get the current timestamp.
Example:
void main_loop() {
static long timestamp = clock();
// First frame will have zero delta, but this is just an example.
float delta = (float)(clock() - timestamp) / CLOCKS_PER_SEC;
calculate_physics(delta);
render();
timestamp = clock();
}
void calculate_physics(float delta) {
// Calculate expected displacement per second.
applyDisplacement(displacement * delta);
}
void render() {
// Do rendering.
}
EDIT: If you want higher precision, you should use your OS timer features. On Windows, the most precise method is using QueryPerformanceCounter(). Example
#include <windows.h>
void main_loop(double delta) {
// ...
}
int main() {
LARGE_INTEGER freq, last, current;
double delta;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&last);
while (1) {
QueryPerformanceCounter(&current);
delta = (double)(current.QuadPart - last.QuadPart) / (double)freq.QuadPart;
main_loop(delta);
last = current;
}
}
Most games use a frame time-scaling factor. Essentially, you find the length of the frame your physics and movement are set at and divide it between the actual length of the frame the game is running at (1/fps). This produces a scalar factor which you can multiply by changes in movement to keep all movements consistent while maintaining the benefits from increasing the FPS.
A good example is here.
The best solution to your problem is to only update the positions of your objects once every 10 ms (or something similar) but render the objects as often as possible. This is called "fixed time step" as you only update the game state at fixed intervals. This requires you to decouple the rendering code from the update code (which is a good idea anyway).
Basically (in psudoe code) what you would do is something like:
accumulatedTimeSinceLastUpdate = 0;
while(gameIsRunning)
{
accumulatedTimeSinceLastUpdate += timeSinceLastFrame();
while(accumulatedTimeSinceLastUpdate >= 10) // or another value
{
updatePositions();
accumulatedTimeSinceLastUpdate -= 10;
}
display();
}
This means that if your computer is running super-duper fast display() will be called a lot of times and every now and then updatePositions(). If your computer is ultra slow updatePositions may be called several times for each time display() is called.
Here's another good read (in addition to Mason Blier's):
http://gafferongames.com/game-physics/fix-your-timestep/