Drawing a line with GLUT - c

I have the next code using OPENGL GLUT, this code draws a line at a cursor position. Once you click the right button of the mouse it captures the coordinates x0, y0 of the line, then when the mouse moves to another pixel while pushing the button the coordinates(x1,y1) change, and finally when the button is released the line is drawn.
#include<windows.h>
#include <gl/glut.h>
float a[90000];
int x0=0,y0=0,xf=0,yf=0;
int print=0;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 300.0, 0.0,300.0);
}
void putpixel(int x,int y)
{
glColor3f(0.0, 0.9,0.7);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void Bresenham(int x0, int y0, int x1, int y1)
{
int dx,dy,p,x,y,px = 1,py = 1,twoDy_Dx,twoDy,i;
glColor3f(0.0,0.0,1.0);
dx = x1-x0;
dy = y1-y0;
if(dx < 0)
dx = dx*-1;
if(dy < 0)
dy = dy*-1;
if(x1 < x0)
px = -1;
if(y1 < y0)
py = -1;
x = x0;
y = y0;
if( dx > dy )
{
putpixel(x,y);
p = 2 * dy - dx;
twoDy_Dx = 2 * ( dy - dx );
twoDy = 2 * dy;
for( i = 0; i < dx; i++ )
{
if( p >= 0 )
{
y += py;
p += twoDy_Dx;
}
else
p += twoDy;
x += px;
putpixel(x,y);
}
}
else
{
putpixel(x,y);
p = 2*dx - dy;
twoDy_Dx = 2 * ( dx - dy );
twoDy = 2*dx;
for( i = 0; i < dy; i++ )
{
if( p >= 0 )
{
x += px;
p += twoDy_Dx;
}
else
p += twoDy;
y += py;
putpixel(x,y);
}
}
glFlush();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
if(print==1)
glDrawPixels(300,300,GL_RGB,GL_UNSIGNED_BYTE,a);
Bresenham(x0,y0,xf,yf);
glutSwapBuffers();
glFlush();
}
void onMotion(int x,int y)
{
xf=x;
yf=300-y;
glutPostRedisplay();
}
void onMouse(int button, int e, int x, int y)
{
if((button == GLUT_LEFT_BUTTON) && (e == GLUT_DOWN))
{
x0 = x;
y0 = abs(300-y);
print = 1;
}
if( (button == GLUT_RIGHT_BUTTON) && (e==GLUT_DOWN))
{
print=0;
}
if ( (button == GLUT_LEFT_BUTTON || button == GLUT_RIGHT_BUTTON) && (e == GLUT_UP) )
{
print=0;
}
}
void onPassive(int x,int y)
{
x0=-1;y0=-1;xf=-1;yf=-1;
glReadPixels( 0.0, 0.0,300.0,300.0,GL_RGB,GL_UNSIGNED_BYTE,a);
}
int main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(300, 300);
glutCreateWindow("Line");
init();
glutDisplayFunc(display);
glutMotionFunc(onMotion);
glutMouseFunc(onMouse);
glutPassiveMotionFunc(onPassive);
glutMainLoop();
}
The problem that I have is that when the button is pushed and while the final coordinates are changing, the line should be drawn as a pointed line: ---------
but when it reaches the final coordinates, the line should be drawn like this: _________. How can I do this?

Related

How to make Bresenham algorithm working backward?

I got an exersise where I would like to draw a line with Bressenham algorithm.
The thing is that it's working perfectly for lines who goes down and on the right, but when the line goes up or backward, it doesn't work anymore ...
Does anybody can help me on that ?
void draw_line(t_data img, int xStart, int yStart, int xEnd, int yEnd)
{
int dx;
int dy;
int pk;
int x;
int y;
dx = xEnd - xStart;
dy = yEnd - yStart;
x = xStart;
y = yStart;
while(x <= xEnd)
{
if(pk >= 0)
{
printf("in if ");
my_mlx_pixel_put(&img, x, y, 0x00FF0000);
y = y + 1;
pk = pk + 2 * dy - 2 * dx;
}
else
{
my_mlx_pixel_put(&img, x, y, 0x00FF0000);
pk = pk + 2 * dy;
}
x = x + 1;
count ++;
}
}
Its working for this
draw_line(img, 300, 300, 400, 360);
But not for this
draw_line(img, 300, 300, 200, 260);
Thanks for your help !!
You are working in the first octant. If you want to draw lines in all direction you have to check the 8 octant.
here is my implentation of bresenham for the 8 octant:
void bresenham(int x1, int y1, int x2, int y2) {
int dx = x2 - x1;
int dy = y2 - y1;
int error;
/** first quarter */
if(dx >= 0 && dy >= 0) {
/** 1st octant */
if (dx >= dy) {
error = -dx;
int y = y1;
for(int x = x1; x < x2; x++) {
draw_pixel(x, y);
error = error + 2 * dy;
if (error >= 0) {
y++;
error = error - 2 * dx;
}
}
}
/** 2nd octant */
else {
error = -dy;
int x = x1;
for(int y = y1; y < y2; y++) {
draw_pixel(x, y);
error = error + 2 * dx;
if (error >= 0) {
x++;
error = error - 2 * dy ;
}
}
}
}
/** second quarter */
else if (dx <= 0 && dy >= 0) {
/** 4th octant */
if(dx < -dy) {
error = dx;
int y = y1;
for(int x = x1; x > x2; x--) {
draw_pixel(x, y);
error = error + 2 * dy;
if (error >= 0) {
y++;
error = error + 2 * dx;
}
}
}
/** 3rd octant */
else {
error = -dy;
int x = x1;
for(int y = y1; y < y2; y++) {
draw_pixel(x, y);
error = error - 2 * dx;
if (error >= 0) {
x--;
error = error - 2 * dy;
}
}
}
}
/** 3rd quarter */
else if (dx <= 0 && dy <= 0) {
/** 5th octant */
if(dx <= dy) {
error = 2 * dx;
int y = y1;
for(int x = x1; x > x2; x--) {
draw_pixel(x, y);
error = error - 2 * dy;
if (error >= 0) {
y--;
error = error + 2 * dx;
}
}
}
/** 6th octant */
else {
error = 2 * dy;
int x = x1;
for(int y = y1; y > y2; y--) {
draw_pixel(x, y);
error = error - 2 * dx;
if (error >= 0) {
x--;
error = error + 2 * dy ;
}
}
}
}
/* 4th quarter */
else if(dx >= 0 && dy <= 0) {
/** 7th octant */
if(dx < -dy) {
error = 2 * dy;
int x = x1;
for(int y = y1; y > y2; y--) {
draw_pixel(x, y);
error = error + 2 * dx;
if (error >= 0) {
x++;
error = error + 2 * dy ;
}
}
}
/** 8th octant */
else {
error = -dx;
int y = y1;
for(int x = x1; x < x2; x++) {
draw_pixel(x, y);
error = error - 2 * dy;
if (error >= 0) {
y--;
error = error - 2 * dx;
}
}
}
}
}

opengl not showing output from renderFunction

I was implementing this dda algorithm using opengl. However, for some reason, it doesn't plot the second line. I tried putting printf at every line, which shows that it IS executing. However, there is no output in my window
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>
int choice = 0;
void DDA(x0, y0, x1, y1)
const x0, y0, x1, y1;
{
glOrtho(-500, 500, -500, 500, -1, 1);
float dx = x1 - x0;
float dy = y1 - y0;
int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
float xInc = (float)steps/dx;
float yInc = (float)steps/dy;
int x = x0, y = y0;
for(int i = 0; i < steps; i++) {
glBegin(GL_POINTS);
glColor3f(1.0, 3.0, 2.0);
glVertex2i(x, y);
x += xInc;
y += yInc;
glEnd();
glFlush();
}
}
void Bresenham(x0, y0, x1, y1)
const x0, y0, x1, y1;
{
glOrtho(-500, 500, -500, 500, -1, 1);
int x = x0;
int y = y0;
int dx = x1 - x0;
int dy = y1 - y0;
int p = 2*dy-dx;
int m = dy / dx;
glBegin(GL_POINTS); {
glColor3f(2.0, 3.0, 5.0);
while(x != x1) {
if(m < 1) {
glVertex2i(x, y);
x++;
if(p >= 0) {
p += 2*(dy - dx);
y++;
}
else {
p += 2*dy;
}
}
else {
glVertex2i(x, y);
y++;
if(p >= 0) {
p += 2*(dx - dy);
x++;
}
else {
p += 2*dx;
}
}
}
glVertex2i(x, y);
}
glEnd();
glFlush();
}
void circle(x0, y0, r)
const x0, y0, r;
{
}
void renderDDA(void) {
DDA(0, 0, 300, 400);
DDA(0, 0, 200, 200);
}
void renderBresenham(void) {
Bresenham(0, 0, 300, 100);
Bresenham(0, 0, 500, 0);
}
void renderCircle(void) {
}
main(argc, argv)
char** argv;
{
redo:
printf("ENTER YOUR CHOICE: ");
scanf("%d", &choice);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(1920, 1680);
glutCreateWindow(argv[1]);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
switch (choice) {
case 0:
glutDisplayFunc(renderDDA);
break;
case 1:
glutDisplayFunc(renderBresenham);
break;
case 2:
glutDisplayFunc(renderCircle);
break;
default:
printf("NO SUCH CHOICE!!");
goto redo;
}
glutMainLoop();
return 0;
}
I also tried swapping the lines. Then it draws only the upper line. it does execute the second call however.
glOrtho does not set an orthographic projection, it defines an orthographic projection matrix and multiplies the current matrix by the orthographic projection matrix.
You've to set the identity matrix before calling glOrtho:
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
Further there is an issue in the algorithm. The type of x and y has to be float. If you would trunc the result to int, then it is only possible to draw lines with angles that are aligned to multiples of 45 degreess, because x and y change exactly by 0 or 1 at each step:
float x = x0, y = y0;
for(int i = 0; i < steps; i++) {
glBegin(GL_POINTS);
glColor3f(1.0, 3.0, 2.0);
glVertex2i((int)(x+0.5f), (int)(y+0.5f));
x += xInc;
y += yInc;
glEnd();
}
Note, changing the type from int to float causes that x and y are tracked with full precision. glVertex2i((int)(x+0.5f), (int)(y+0.5f)) ensures that coordinates (x, y) are rounded to the integral position when the point is draw.
I recommend to move the setting of the projection matrix from and glFlush from DDA respectively Bresenham to renderDDA respectively renderBresenham:
void DDA(float x0, float y0, float x1, float y1)
{
float dx = x1 - x0;
float dy = y1 - y0;
int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
float xInc = (float)steps/dx;
float yInc = (float)steps/dy;
float x = x0, y = y0;
for(int i = 0; i < steps; i++) {
glBegin(GL_POINTS);
glColor3f(1.0, 3.0, 2.0);
glVertex2i((int)(x+0.5f), (int)(y+0.5f));
x += xInc;
y += yInc;
glEnd();
}
}
void Bresenham(float x0, float y0, float x1, float y1)
{
int x = x0;
int y = y0;
int dx = x1 - x0;
int dy = y1 - y0;
int p = 2*dy-dx;
int m = dy / dx;
glBegin(GL_POINTS); {
glColor3f(2.0, 3.0, 5.0);
while(x != x1) {
if(m < 1) {
glVertex2i(x, y);
x++;
if(p >= 0) {
p += 2*(dy - dx);
y++;
}
else {
p += 2*dy;
}
}
else {
glVertex2i(x, y);
y++;
if(p >= 0) {
p += 2*(dx - dy);
x++;
}
else {
p += 2*dx;
}
}
}
glVertex2i(x, y);
}
glEnd();
}
void renderDDA(void) {
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
DDA(0, 0, 300, 400);
DDA(0, 0, 200, 200);
glFlush();
glutSwapBuffers();
}
void renderBresenham(void) {
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
Bresenham(0, 0, 300, 100);
Bresenham(0, 0, 500, 0);
glFlush();
glutSwapBuffers();
}

function to draw a straight line in c

I'm trying to create a function to draw a straight line by reading two points from the user, (x1,y1) where the line begins and (x2,y2) where it ends.
here's my function:
void line(struct pixels* screen)
{
float X, Y;
int i, j, x1, y1, x2, y2, mX, mY;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if ((x1 >= 0 && x1 <= screen->width) && (y1 >= 0 && y1 <= screen->height) && (x2 >= 0 && x2 <= screen->width) && (y2 >= 0 && y2 <= screen->height))
{
X = (x2 - x1);
Y = (y2 - y1);
if (X < 0)
mX = X*(-1);
else
mX = X;
if (Y < 0)
mY = Y*(-1);
else
mY = Y;
if( mX>mY )
{
if (X > 0)
{
for (i = 0; i < X; i++)
{
j = (int)(((i*Y) / X) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
else
{
for (i = 0; i > X; i--)
{
j = (int)(((i*Y) / X) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
}
else
{
if (Y > 0)
{
for (j = 0; j < Y; j++)
{
i = (int)(((j*X) / Y) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
else
{
for (j = 0; j > Y; j--)
{
i = (int)(((j*X) / Y) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
}
}
else
printf("ERROR: coordinates exceed the screen limits\n");
}
the problem is : when the user enters for example line from (1,1) to (10,10) the code works perfectly, but when it's from (10,10) to (1,1) it doesn't work!
Google Bresenham’s Line Drawing Algorithm. There is a fantastic tutorial/explanation of how do to this kind of thing at How OpenGL works: software renderer in 500 lines of code. Your specific question is brought up in the article. Highly recommended.
Here is his C++ implementation:
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
bool steep = false;
if (std::abs(x0-x1)<std::abs(y0-y1)) {
std::swap(x0, y0);
std::swap(x1, y1);
steep = true;
}
if (x0>x1) {
std::swap(x0, x1);
std::swap(y0, y1);
}
int dx = x1-x0;
int dy = y1-y0;
float derror = std::abs(dy/float(dx));
float error = 0;
int y = y0;
for (int x=x0; x<=x1; x++) {
if (steep) {
image.set(y, x, color);
} else {
image.set(x, y, color);
}
error += derror;
if (error>.5) {
y += (y1>y0?1:-1);
error -= 1.;
}
}
}

Pattern Flood Fill Algorithm

I have implemented a flood fill algorithm that is working correctly for solid color fills. Now I´m working on a pattern fill and decided to add a flag to see how to fill the area ( with a color or with a pattern). However when using the the algorithm with pattern fill gets stuck while painting the area.
This is my original code that works with solid colors:
void floodFillStack(int x, int y, byte newColor, byte oldColor) {
int y1;
if (oldColor == newColor) return;
if (get_pixel(x, y) != oldColor) return;
//draw current scanline from start position to the top
y1 = y;
while (y1 < h && get_pixel(x, y1) == oldColor) {
plot_pixel(x, y1, newColor);
y1++;
}
//draw current scanline from start position to the bottom
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == oldColor) {
plot_pixel(x, y1, newColor);
y1--;
}
//test for new scanlines to the left
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor);
}
y1--;
}
//test for new scanlines to the right
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x < w - 1 && get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 &&get_pixel(x, y1) == newColor) {
if (x < w - 1 && get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor);
}
y1--;
}
}
And here is with the pattern modification (it still works with solid colors).
int pattern1[6][6] = { {0,1,0,1,0,1},
{1,0,1,0,1,0},
{0,1,0,1,0,1},
{1,0,1,0,1,0},
{0,1,0,1,0,1},
{1,0,1,0,1,0} };
int pattern2[6][6] = { {0,0,1,1,0,0},
{0,1,0,0,1,0},
{1,0,0,0,0,1},
{1,0,0,0,0,1},
{0,1,0,0,1,0},
{0,0,1,1,0,0} };
void floodFillStack(int x, int y, byte newColor, byte oldColor, int pattern_fill) {
int y1;
if (oldColor == newColor) return;
if (get_pixel(x, y) != oldColor) return;
//draw current scanline from start position to the top
y1 = y;
while (y1 < h && get_pixel(x, y1) == oldColor) {
if (pattern_fill == 0) {
if (fill_pattern == 1) {
if (pattern1[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
} else {
if (pattern2[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
}
} else {
plot_pixel(x, y1, newColor);
}
y1++;
}
//draw current scanline from start position to the bottom
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == oldColor) {
if (pattern_fill == 0) {
if (fill_pattern == 1) {
if (pattern1[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
} else {
if (pattern2[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
}
} else {
plot_pixel(x, y1, newColor);
}
y1--;
}
//test for new scanlines to the left
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor, pattern_fill);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor, pattern_fill);
}
y1--;
}
//test for new scanlines to the right
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x < w - 1 &&get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor, pattern_fill);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == newColor) {
if (x < w - 1 && get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor, pattern_fill);
}
y1--;
}
}
Can anyone help me see the problem?
EDIT:
Thanks to WeatherVane for the suggestion. The algorithm is no longer stuck, but it does not cover the entire area. Here´s a picture:
Your floodfill is likely to misfire if you ignore the 0 values in your pattern masks. Instead of that, always fill with one of two colours (both different from the background).
You will also have to change some of your conditional tests. Instead of
(... == newColor)
you could use
(... != oldColor)
or
(... == newColor1 || ... == newColor2)
When you fill with a solid color, every pixel that starts at oldColor gets changed to newColor. This means that a test of that pixel later in the process won't match against it again.
When you try to fill with a pattern, some of those pixels are going to remain as oldColor. You get stuck in an infinite loop, retesting those same pixels over and over.

how to convert OpenGL code using vertex arrays into code using vertex buffer objects?

this is my draw() function written in C, using vertex arrays:
void draw(float x1, float x2, float y1, float y2)
{
glPushMatrix();
glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);
if( pts.size > 0 )
{
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, (float*)pts.data );
glDrawArrays( GL_LINE_STRIP, 0, pts.size / 2 );
glDisableClientState( GL_VERTEX_ARRAY );
}
glPopMatrix();
};
before calling draw(), pts get's updated inside the update() function:
void update(double (* func)(double x), float x1, float x2, int N)
{
double x, dx = (double)1.0/(double)N;
vector_cleanup( &pts );
m = 0;
for(x = x1; x < x2; x += dx)
{
vector_resize( &pts, pts.size + 2 );
*(float*)vector_get( &pts, pts.size-2 ) = (float)x;
*(float*)vector_get( &pts, pts.size-1 ) = (float)func3(x);
m++;
}
}
I hope that by converting this code to use VBO, my graphics performance will increase.
EDIT: func3() can be anything, e.g. sin(x) or just some linear mapping. All I'm currently trying to do is, to find out how quickly I can plot a bunch of points.
Using GLEW for extension wrangling:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
typedef struct vector /*dynamic vector of void* pointers. This one is used only by the deflate compressor*/
{
void* data;
size_t size; /*in groups of bytes depending on type*/
size_t allocsize; /*in bytes*/
unsigned typesize; /*sizeof the type you store in data*/
} vector;
static unsigned vector_resize(vector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
{
if(size * p->typesize > p->allocsize)
{
size_t newsize = size * p->typesize * 2;
void* data = realloc(p->data, newsize);
if(data)
{
p->allocsize = newsize;
p->data = data;
p->size = size;
}
else return 0;
}
else p->size = size;
return 1;
}
static void vector_cleanup(void* p)
{
((vector*)p)->size = ((vector*)p)->allocsize = 0;
free(((vector*)p)->data);
((vector*)p)->data = NULL;
}
static void vector_init(vector* p, unsigned typesize)
{
p->data = NULL;
p->size = p->allocsize = 0;
p->typesize = typesize;
}
static void* vector_get(vector* p, size_t index)
{
return &((char*)p->data)[index * p->typesize];
}
/* function to calculate each data point */
float func(float x)
{
return (float)sin(x);
}
GLuint vbo = 0;
GLsizei vertcount = 0;
void update(float (* func)(float x), float x1, float x2, int N)
{
float x, dx = 1.0f/N;
vector pts;
vector_init( &pts, sizeof( float ) );
for(x = x1; x < x2; x += dx)
{
vector_resize( &pts, pts.size + 2 );
*(float*)vector_get( &pts, pts.size-2 ) = x;
*(float*)vector_get( &pts, pts.size-1 ) = func(x);
}
vertcount = (GLsizei)( pts.size / 2 );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, pts.size * pts.typesize, pts.data, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
vector_cleanup( &pts );
}
/* plotting function - very slow */
void draw(float x1, float x2, float y1, float y2)
{
glPushMatrix();
glScalef( 1.0f / (x2 - x1), 1.0f / (y2 - y1), 1.0f );
glTranslatef( -x1, -y1, 0.0f );
glColor3f( 1.0f, 1.0f, 1.0f );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, 0 );
glDrawArrays( GL_LINE_STRIP, 0, vertcount );
glDisableClientState( GL_VERTEX_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glPopMatrix();
};
/* Redrawing func */
float xmin = -10, xmax = 10, ymin = -5, ymax = 5;
void redraw(void)
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// -x, +x, -y, +y, number points
draw(xmin, xmax, ymin, ymax);
glutSwapBuffers();
};
/* Idle proc. Redisplays, if called. */
int nPoints = 3000;
void idle(void)
{
// shift 'xmin' & 'xmax' by one.
xmin++;
xmax++;
update(func, xmin, xmax, nPoints);
glutPostRedisplay();
};
/* Key press processing */
void key(unsigned char c, int x, int y)
{
if(c == 27) exit(0);
};
/* Window reashape */
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
};
/* Main function */
int main(int argc, char **argv)
{
GLenum err;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Graph plotter");
glutReshapeWindow(1024, 800);
// init GLEW and output some GL info
err = glewInit();
printf("GL_VERSION : %s\n", glGetString(GL_VERSION) );
printf("GL_VENDOR : %s\n", glGetString(GL_VENDOR) );
printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER) );
if( GLEW_OK != err )
{
printf("glewInit failed: %s", glewGetErrorString(err));
return EXIT_FAILURE;
}
if( !glewIsSupported("GL_VERSION_1_5") )
{
printf("OpenGL version 1.5 or greater required.\n");
return EXIT_FAILURE;
}
glGenBuffers( 1, &vbo );
/* Register GLUT callbacks. */
glutDisplayFunc(redraw);
glutKeyboardFunc(key);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
/* Init the GL state */
glLineWidth(2.0);
/* Main loop */
glutMainLoop();
return 0;
}

Resources