opengGL drawing a line - c++

So far this is my code:
#include <iostream>
#include <cstdlib>
#include <GL/glut.h>
#include <cmath>
void keyboard(unsigned char key, int x, int y);
void display(void);
void timer(int);
static float x=0.0f,y=0.0f;
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowPosition(200,200);
glutInitWindowSize(640,480);
glutCreateWindow("draw a line");
glutKeyboardFunc(&keyboard);
glutDisplayFunc(&display);
glutTimerFunc(10,timer,0);
glutMainLoop();
return EXIT_SUCCESS;
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case '\x1B':
exit(EXIT_SUCCESS);
break;
}
}
void timer(int value){
x+=0.001;
y+=0.0005;
glutPostRedisplay();
glutTimerFunc(10,timer,0);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity ();
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
glFlush();
}
What this does is that it lights up a pixel every 10 msecs from the point (0,0) to (1,0.5). What I want is that when a pixel lights up it stays in that state, so eventually you will see a line. How can I achieve this?

I am not familiar with glut but I am guessing display is the function that is called on each redraw. This function starts with glClear(GL_COLOR_BUFFER_BIT). This function clears your color buffer on each redraw.
You might find that removing glClear does not entirely fix your problem. This could well be because your graphics context may be double buffered and to make things more efficient, the front buffer is not copied to the back buffer on each animation run.
You best bet to get the desired effect will probably be to draw a line that grows on each animation run.

why do things the hard way? although the older OGL API is deprecated, you can use GL_LINES to do this:
glBegin(GL_LINES);
glVertex2f(x_start,y_start);
glVertex2f(x_end,y_end);
glEnd();
This will draw the line fully in one go, which is easier and a bit more efficient (it also allows you to benefit from the line anti-aliasing hint).

The display function is being called every time you call glutPostRedisplay(). And every time the display function is called, you clear the screen.
You need to write a function that will iterate through all of the points you want to display. Each iteration will call something like a drawPoint() function.
Perhaps something like this:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 1.0f, 0.0f);
for (int i = 0; i < num_points; i++)
{
drawPoint(points(i));
}
glFlush();
}
Alternatively, you could skip writing a new function and do this:
glBegin(GL_POINTS);
for (int i = 0; i < num_points; i++)
{
glVertex2f(points(i).getX(), points(i).getY());
}
glEnd();

If your using, GL_LINES. A way to do it is to have an array of points you want to draw EG: p[0], p[1], p[2], p[3], p[4], p[5] ... then draw it using some for loop
glBegin(GL_LINES);
for(...) {
glVertex2f(p[i ]->x,p[i ]->y);
glVertex2f(p[i+1]->x,p[i+1]->y);
}
glEnd();
So using this method you can replace p[] with a function allowing you to make pretty shapes
glVertex2f(functionx(i ),functiony(i ));
glVertex2f(functionx(i+1),functiony(i+1));
note: lines work weirdly they dont link up you need to have a start point to end point kind of thing hence the i+1
I guess your trying to draw stuff like cardioid's using polar coordinates?

Related

OpenGL drawing a grid

Im new in OpenGL and im trying to make a 12x15 grid, so it appears something like an array but still a grid. I have this code so far:
#include <windows.h>
#include <GL/glut.h>
void display(){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
// Horizontal lines.
for (int i=0; i<=12; i++) {
glVertex2f(0, i);
glVertex2f(15, i);
}
// Vertical lines.
for (int i=0; i<=15; i++) {
glVertex2f(i, 0);
glVertex2f(i, 12);
}
glEnd();
glFlush();
}
void handleKeypress(unsigned char key, int x, int y){
switch (key){
case 27: //Escape key
exit(0);
}
}
main(int argc, char** argv){
glutInit(&argc, argv);
glutCreateWindow("Grid Test");
glutInitWindowSize(600, 480);
glutInitWindowPosition(100, 100);
glutDisplayFunc(display);
glutKeyboardFunc(handleKeypress);
glutMainLoop();
}
and yet the program window has this:
test grid
What is the mistake I made? Should I write a function for the grid drawing out of the display function?
When no projection or other transformation is applied, the visible coordinates range from -1 to 1 on each axis. What you see is the lower left part starting from (0,0). If you want to see the whole grid, you will have to set transformation matrices to get it where you want.

Translate a triangle using animation(one by one after some interval) with opengl and c++

I want to make a space invader game in opengl. So I thought of creating the enemies using triangles. Before making the game, I want to try out my hand in animation. I have triangle. i want to translate it left upto some point with animation(i.e, triangle is translated after some interval of time. It should look as if it is moving).After reaching some point in the left, I want to translate it back to the same position or some distances right. The process should go on till the screen is open. I used sleep function. But it is not working. No animation is shown. Only the translated triangle is drawn at different translated position. Help me.
Here is my code-
#include "windows.h"
#include <gl/glut.h>
#include<stdio.h>
void init( void )
{
printf( "OpenGL version: %s\n", (char*)glGetString(GL_VERSION));
printf( "OpenGL renderer: %s\n", (char*)glGetString(GL_RENDERER));
//Configure basic OpenGL settings
glClearColor(1.0, 1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,640.0,0.0,480.0);
glColor3f(1.0,0.0,0.0);
glPointSize(3);
}
void house(int x, int y,int z)
{
glPushMatrix();
glTranslatef(x, y,z);
glBegin (GL_LINES);
glVertex2i (0,30);
glVertex2i (15,60);
glVertex2i (15,60);
glVertex2i (30,30);
glVertex2i (30,30);
glVertex2i (0,30);
glEnd();
//Sleep(200);
glPopMatrix();
//glutSwapBuffers();
}
// Main drawing routine. Called repeatedly by GLUT's main loop
void display( void )
{
//Clear the screen and set our initial view matrix
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
int i;
for(i = 10; i < 350; i = i + 50)
{
house(i,20,0);
Sleep(200);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFlush();
}
// Entry point - GLUT setup and initialization
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode (GLUT_DEPTH | GLUT_SINGLE| GLUT_RGB);
glutInitWindowSize (800, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow( "OpenGL Test" );
glutDisplayFunc( display );
init();
glutMainLoop();
return 0;
}
In main() you have declared your display() as display callback function. GLUT will call this function either when it determines that the window need to be redrawn or when it is told to redraw it for example by the function glutPostRedisplay().
The display function is expected to call redraw the windows at a specific point in time. The glFlush() will force the execution of the GL commands.
The problem is that your animation loop is inside the redraw function and glFlush() is called at the end, showing the result at once. And you don't tell GLUT to redraw the windows. This is why you don't seee the animation.
For the purpose of the tutorial, I propose you to define a global variable for the initial position of the house drawing. Of course, you'll have to improve this as soon as you understood how all this works.
static int pos = 10; // temporary work around, just for the demo
Then define a timer function, that gets called after a time interval. This will be the core of your animation, organizing the moving, and the redrawing of the window by calling glutPostRedisplay() :
void timerfunc(int value) // handle animation
{
pos += 50; // update the postion
if (pos<350) // as in your originial loop
glutTimerFunc(200, timerfunc, 0); // plan next occurence
glutPostRedisplay(); // redraw the window
}
Activate your timer function, in main() just before launching glutMainLoop():
glutTimerFunc(200, timerfunc, 0); // call a timer function
glutMainLoop(); // this call is already in your code
Your display function can then be changed into:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
house(pos, 20, 0); // draw the house at its last calculated position
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFlush();
}
Then it works in animated modus !

Glut Open GL object wont animate

My polygon wont move, I tried many things and i think glClear(GL_COLOR_BUFFER_BIT);or glutMainLoop(); wont do their job. So first picture stay the same. There is no animation.
float x=0;
float y=0;
float b=0;
void displayCB(void)
{
glClear(GL_COLOR_BUFFER_BIT);
kvadrat();
}
void kvadrat()
{
glBegin(GL_POLYGON);
glColor3f(1, 0, 0); glVertex2d(0.5-x, 0.5-y);
glColor3f(1, 0, 0); glVertex2d(0.5-x, -0.5-y);
glColor3f(1, 0, 0); glVertex2d(-0.5-x, -0.5-y);
glColor3f(1, 0, 0); glVertex2d(-0.5-x, 0.5-y);
glEnd();
Sleep(1999);
glFlush();
x=x+0.01; // I modified this value so it will always be between 0.5 and -0.5,
//this is just example
}
int main(int argc, char *argv[])
{
int win;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(800,600);
win = glutCreateWindow("Elementi");
glClearColor(0.0,0.0,0.0,0.0);
glutDisplayFunc(displayCB);
glutKeyboardFunc(keyCB);
glutMainLoop();
return 0;
}
I think you may be moving the position only a very small increment every two seconds, so the image appears to be static, but it's not, it's just changing very slowly. Try taking out the Sleep(1999) and see whether your animation works any better.
If you need to animate over time, it is better to instead use glutGet(GLUT_ELAPSED_TIME) to figure out how much time has elapsed since the last frame and use that to scale your deltas.
I fixed problem with glutPostRedisplay(); // Inform GLUT that the display has changed

Showing stuff issue(opengl)

I am having some trouble running a simple program:(code below text)
i would like to print as an output a square with [50,50],[-50,-50],[50,-50],[-50,50] coordinates.
I'm setting up a glOrtho matrix in init() and then in my display func i print the square with the above coordinates as glVertex2f (for example glVertex2f(50.0,-50.0)) Is it the correct way or does glVertex2f not take real coordinates as values?
Anyway here is the code: (it compiles nicely, however it doesnt show anything in graphics window)
#include <iostream>
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <windows.h>
#include <GL/glut.h>
#endif
#define SCR_WID 640
#define SCR_HEI 480
#include "imageloader.h"
using namespace std;
//*****************************CUSTOM FUNCS***********************************//
void init()
{
glViewport(0,0,SCR_WID,SCR_HEI);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((double)SCR_WID,0.0,(double)SCR_HEI,0.0,-5.0,-20.0);
glMatrixMode(GL_MODELVIEW);
}
//*****************************CALLBACKS (win 1)******************************//
void resizeFunc(int w, int h)
{
glutReshapeWindow(SCR_WID,SCR_HEI);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
glVertex2f(1.0,1.0);
glVertex2f(-1.0,1.0);
glVertex2f(1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
glutSwapBuffers();
}
void key(unsigned char key, int x, int y)
{
if (key == 'q' || key == 27 )
exit(0);
glutPostRedisplay();
}
//**********************************main func*********************************//
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(SCR_WID,SCR_HEI);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("TestGlut");
glutReshapeFunc(resizeFunc);
glutDisplayFunc(display);
glutIdleFunc(display);
glutKeyboardFunc(key);
init();
glutMainLoop();
return EXIT_SUCCESS;
}
Your init function is a little odd
glViewport(0,0,SCR_WID,SCR_HEI);
The default viewport is already the full window, so this is redundant.
glPushMatrix();
You never call glPopMatrix or manipulate the matrix stack in any other way elsewhere, so why are you doing this?
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((double)SCR_WID,0.0,(double)SCR_HEI,0.0,-5.0,-20.0);
Calling glLoadIdentity immediately before glOrtho is a waste. glOrtho overwrite the current matrix, so it doesn't matter what it was before. Also glLoadIdentity resets the matrix value back to it's default of an identity matrix, which is what it would be anyway at program start, so it's doubly redundant.
Also, the glOrtho params are 'left right bottom top near far'. You've reversed the X and Y axes by putting a larger number for left and bottom than for right and top. At best this will give you a projection that will put the (0,0) coordinate at the lower right of the screen, which is pretty unusual. Finally, your near and far planes lie completely in negative Z space. That means that vertices that are specified with only two values (glVertex2f as you're using) will always be excluded since they have an implicit 0 for their z coordinate.
void resizeFunc(int w, int h)
{
glutReshapeWindow(SCR_WID,SCR_HEI);
}
Why bother with a resize function if you're going to ignore the input width and height?
glBegin(GL_QUADS);
glVertex2f(1.0,1.0);
glVertex2f(-1.0,1.0);
glVertex2f(1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
Aside from the fact that these coordinates will produce clipped vertices (because their Z value is implicitly 0, and thus outside of your near/far clip region), you're specifying them in what appear to be in normalized clip coordinates. If you corrected the Z shape problem that genpfault mentioned (by swapping vertex 3 and 4) then these would take up the whole screen if you were working with the default projection matrix. By setting an ortho matrix using the screen pixel dimensions, you've created a square that would be 2 pixels wide and two pixels tall, located in the lower right hand corner of the screen.
void key(unsigned char key, int x, int y)
{
...
glutPostRedisplay();
}
Why? If you want your program to render continuously, and not just when someone hits a key, then you should have glutPostRedisplay() in an idle function, not in the keypress function.
int main(int argc, char *argv[])
{
...
glutIdleFunc(display);
...
}
Don't set your idle function to the display function. If you want your program to animate, make an actual idle function that calls glutPostRedisplay.

freeglut/ glu 3d drawing

I'm trying to draw a blue quad across the bottom of a room.
This is the the code I've been attempting to use, but there is no quad, just the green clear color.
#include <iostream>
#include <vector>
#include <cmath>
#include <GL/glu.h>
#include <GL/freeglut.h>
bool keystates[256];
bool speckeystates[256];
// manage key events
void keys(unsigned char key, int x, int y) {
keystates[key]=true;
}
void keyup(unsigned char key, int x, int y) {
keystates[key]=false;
}
void skeys(int key, int x, int y) {
speckeystates[key]=true;
}
void skeyup(int key, int x, int y) {
speckeystates[key]=false;
}
void draw(void) {
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(0,0,0,640,480,640,0,1,0); // from near-top-left to far-bottom-right, floor should be visible
glBegin(GL_QUADS);
glColor3ub(15,15,255); // visible blue color
glVertex3i(0,480,0); // draw quad across bottom
glVertex3i(640,480,0);
glVertex3i(640,480,640);
glVertex3i(0,480,640);
glEnd();
glFlush(); // flush drawing
glutSwapBuffers(); // swap the buffers
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640,480);
glutInitWindowPosition(0,0);
glutCreateWindow("Window!"); // init window stuff
glutDisplayFunc(draw); // our frame/draw event
glutKeyboardFunc(keys);
glutKeyboardUpFunc(keyup);
glutSpecialFunc(skeys);
glutSpecialUpFunc(skeyup); // init key event stuff
glEnable(GL_DEPTH_TEST); // init opengl stuff
glClearColor(0.2f,0.3f,0.2f,1.0f);
gluPerspective(45.0,640/480,0,640); // x: 0-640 y: 0-480 z: 0-640
glDepthFunc(GL_LEQUAL);
glutMainLoop(); // begin the loop
}
I am going to answer your question, but first I'd advise you to try and forget about the glBegin function as well as glVertex/color etc. This is a very outdated API from the time when a draw call (e.g. a transfer of data from RAM to graphics memory) was less expensive than the rendering itself, so it didn't matter that you were inefficiently sending data because it took the graphics card more time to process whatever you sent it the last frame than it took the CPU and DMA to get the data from one memory to the other.
A few years later, the exact opposite was true, so the standard expanded to include VBOs so you don't need to send each vertex via a separate draw call, but they kept the immediate mode (which is what you are using) for compatibility reasons.
Nowadays the immediate mode is (finally) deprecated, so it's a bad idea to use it, you can find some decent tutorials about the new API here
Anyway your problem is the way you setup your camera, you stand in the point 0,0,0 and look at the 640,480,640 point which means that the vertices will be defined in the wrong order, causing them to get culled, either change the glulookat call and inverse the target and the eye positions, or change the culling mode