plotting points in opengl - c++

I am trying to print some points on the window and nothing is getting displayed on the window.The window background is set to grey color and that is all that happens.No points appear on the screen.here is my code
#include <GL/freeglut.h>
#include <GL/gl.h>
#include<unistd.h>
#include<iostream>
using namespace std;
float a[2]={0,0.7},b[2]={-0.3,-0.5},c[2]={0.5,-0.55};
float m[2]={0.0,0.0};
int roll_die() {
int k= (rand()%6) + 1;
return k;
}
void midpoint(float p[],float q[],float *k )
{
for(int i=0;i<2;i++)
{
k[i]=(p[i]+q[i])/2;
}
}
void displaypoint(float a[])
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glBegin(GL_POINT);
glVertex2f(a[0], a[1]);
glEnd();
glPointSize(8.0);
glFlush();
}
void setup()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POINTS);
glVertex2f(a[0], a[1]);
glVertex2f(b[0],b[1]);
glVertex2f(c[0],c[1]);
glEnd();
glPointSize(8.0);
glFlush();
}
void chaos()
{
int num;
for(int i=0;i<1000;i++)
{
num=roll_die();
if(num==1 || num==2)
midpoint(m,a,m);
else if(num==3 || num==4)
midpoint(m,b,m);
else
midpoint(m,c,m);
displaypoint(m);
usleep(2000);
}
}
int main(int argc, char **argv)
{
int num;
float a[2]={0,0.7},b[2]={-0.3,-0.5},c[2]={0.5,-0.55};
float m[2]={0.0,0.0};
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL - Creating a triangle");
glClearColor(0.4, 0.4, 0.4, 0.4);
glutDisplayFunc(setup);
glutDisplayFunc(chaos);
glutMainLoop();
return 0;
}

There were several problems. To find them I just compiled it myself and worked through them:
GL_POINT should be GL_POINTS in displaypoint. GL_POINT means something else entirely -- you still use GL_POINTS even if you only display one point
You were clearing each time you drew a point, so you would only ever see one point (but the point wasn't drawing in the first place due to the above). Only clear when you want to wipe the whole screen.
I've not used glut so I'm not positive, but it looks like you immediately overrode the displayFunc callback with chaos, so I don't think setup was ever called. I just pushed setup into the beginning of your chaos loop.
You defined your arrays again in main -- it doesn't matter, but those were not being used. Only the global ones were used. I recommend adding -Wall to your compiler flags if you haven't already, as the compiler would have told you this :)
Really the point of failure was that you were clearing each time you drew a point while also not actually drawing that point due to the use of GL_POINT.
Since you're new to GL, I'll mention that glGetError() is extremely useful as a first-pass debugging mechanism. You can call it and check the return value at various points in your program to see if GL is telling you that you've done something wrong. In this case, for example, calling glGetError() after your drawpoint function would have returned the error GL_INVALID_ENUM, because you used an invalid enum value (GL_POINT rather than GL_POINTS) for your call to glBegin().
Here is a working example for you in case it helps. I hope you don't mind that I reformatted & compacted it to make it easier to share here (and some was to help me read and understand it). That's a neat program, I had no idea it was going to output what it did when I got it working. Cool :)
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <unistd.h>
float a[2] = { 0.0f, 0.70f };
float b[2] = { -0.3f, -0.50f };
float c[2] = { 0.5f, -0.55f };
float m[2] = { 0.0f, 0.00f };
void midpoint(float p[], float q[], float* k) {
for (int i = 0; i < 2; i++)
k[i] = (p[i] + q[i]) / 2;
}
void chaos() {
glPointSize(1.0);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
for(int i = 0; i < 100000; i++) {
int num = (rand() % 6) + 1;
if (num < 3)
midpoint(m, a, m);
else if (num < 5)
midpoint(m, b, m);
else
midpoint(m, c, m);
glBegin(GL_POINTS);
glVertex2f(m[0], m[1]);
glEnd();
glFlush();
}
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL - Creating a triangle");
glutDisplayFunc(chaos);
glutMainLoop();
return 0;
}
Output:
Let me know if anything doesn't make sense.

Related

How to Improve Accuracy of Iteration?

I'm trying to make code, c++, to plot the Mandlebrot Set. However, whenever I run my code, see below, the convergence is poor. How do I fix that? I provided some code below. There's also a screenshot of the Mandelbrot Set, red, and my code's approximation, greyscale.
#include <GL/glut.h>
void renderscene(void) {
double x=0;
double y=0;
double ix=0;
double iy=0;
int n=1;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for(x=-3;x<3;x=x+0.01){
for(y=-3;y<3;y=y+0.01){
for(n=1;n<50;n=n+1){
ix=ix*ix-iy*iy+x;
iy=2*iy*ix+y;
if(ix*ix+iy*iy>4){
break;
}
}
ix=0;
iy=0;
glPointSize(1);
glColor3f(0.1*n,0.1*n,0.1*n);
glBegin(GL_POINTS);
glVertex2f(x*0.4,y*0.4);
glEnd();
}
}
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowPosition(300,200);
glutInitWindowSize(500,500);
glutCreateWindow("Hello");
glutDisplayFunc(renderscene);
glutMainLoop();
return 1;
}
You are using the wrong ix in the computation of the new iy.
Try
double nextix=ix*ix-iy*iy+x;
iy=2*iy*ix+y;
ix = nextix;

Getting points equidstant from each other in openGL on a circle

I'm trying to write code for a weaving pattern in OpenGL.
Weaving Pattern
Pic
Now, I am trying to write code for a similar pattern using a circle.
I draw a circle using points, each point is drawn using cos and sin functions.
I understand this is not as efiicient as SeigeLord's method as it makes higher use of resources.
I am able to get the circle, I want to get points on it's circumference.
My code :
#include<GL/glut.h>
#include<stdio.h>
#include<math.h>
int n, r;
void display()
{
int i, j;
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-50, 50, -50, 50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for (i = 0;i <= 360;i += 1)
{
glBegin(GL_POINTS);
glVertex2f(r*cos(i), r*sin(i));
glEnd();
}
/*for (i = 0;i < 360;i += 10)
{
glBegin(GL_LINES);
glVertex2f(r*cos(i), r*sin(i));
glVertex2f(r*cos(i + 300), r*sin(i + 300));
glEnd();
}*/
glFlush();
}
int main(int argc, char **argv)
{
r = 30;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(300, 50);
glutInitWindowSize(800, 800);
glutCreateWindow("Cylinder");
glutDisplayFunc(display);
glutMainLoop();
}
I tried using the commented code for getting lines between points 300 degrees apart, do this every at point 10 degrees apart.(It looks good at 3 degrees apart).
Now, this obviously doesn't work as we use trigonometric functions, which won't space out the points equally.
I hope you understand my question, how can I get points on the circle equally apart?
One solution, I think might work is, while plotting the points itself, if I use an array to save every nth point, I may get equidistant points. Am I right? Is there any other way of getting the points?
Please do correct me if I am wrong anywhere above, I am just newbie here.
Note that sin and cos take their input in radians(i.e. 0 to 2* pi), not degrees(0 to 360). So your code should probably be
for (i = 0;i <= 360;i += 1)
{
glBegin(GL_POINTS);
glVertex2f(r*cos(i * (M_PI / 180.)), r*sin(i* (M_PI / 180.)));
glEnd();
}
edit:
To get N equidistant point we have to put them (1/N) part of the circle away from each other:
for (i = 0;i < N;i += 1)
{
double angle = i * (2.0 * M_PI / N);
glBegin(GL_POINTS);
glVertex2f(r*cos(angle), r*sin(angle));
glEnd();
}

opengl code compilation issue

After drawing a shape am not been able to draw any more shapes in my display function. But it is being drawn perfectly in other methods but not in my glutidlefunction(myDispalay). Stuck here for about two days. can anyone help me out from here ?
Here is the code :
include < stdio.h>
include< math.h>
include < GL/glut.h>
define PI 3.1416
float x,y,r,y2,r2;
void drawCircle(float x, float y, float radius)
{
int i;
int triangleAmount = 1000; //# of triangles used to draw circle
float twicePi = 2.0f * PI;
glBegin(GL_TRIANGLE_FAN);
for(i = 0; i <= triangleAmount;i++)
{
glVertex2f( x + (radius * cos(i * twicePi / triangleAmount)),
y + (radius * sin(i * twicePi / triangleAmount)));
}
glEnd();
}
void drawthrower()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,1.0,0.0);
drawCircle(x,y,r);
glBegin(GL_LINES);
glVertex2i(x-12,y-28);
glVertex2i(x-12,y-70);
glVertex2i(x+12,y-28);
glVertex2i(x+12,y-70);
glEnd();
drawCircle(x,y2,r2);
glutSwapBuffers();
}
void myDisplay()
{
while ((x+r)<=1024)
{
x+=8;
drawthrower();
}
while ((x-r)>=0)
{
x-=8;
drawthrower();
}
}
void myInit()
{
glClearColor(1,1,1,1);
x=50,y=693,r=30,x=50,y2=623,r2=12;
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1024.0, 0.0, 768.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1024,768);
glutInitWindowPosition(0, 0);
glutCreateWindow("Graphics_Project");
myInit();
glutReshapeFunc(reshape);
glutIdleFunc(myDisplay);
glutMainLoop();
return 0;
}
When using GLUT drawing code should be isolated to the display callback function. You're currently have the display function registered as idle function. To make the program call the display function continuously call glutPostRedisplay from the idle function (or register glutPostRedisplay as the idle function). The reason why you should limit drawing code to the display callback is, that depending on the OS when the redraw event is sent certain special state may be set.
Also, while not technically wrong, but a stylistic issue is, that the glutSwapBuffers should be moved into the display function, so that when maintaining the program one does not go hunting for details like in which subroutine the buffer swap is carried out.

Continuous Line On Mouse Drag

I am making a basic OpenGl program which is my weekend project.
Description: If I drag the mouse on the window screen then after I release the button(left) a line should appear that shows the path of dragging the mouse and a circle should traverse that line from start to end.
My Code Works Very Well but the problem is that the line drawn is not continuous[rather its dashed] and it may be because of the mapping of OS screen to OpenGL screen.
SO is there any way to make a continous line path or correct me If I am doing something wrongHere is my code:
#include <iostream>
#include <glut.h>
#include <string.h>
#define WIDTH 600
#define HEIGHT 600
using namespace std;
double arr[5000][4];
int z=0;
int flag=0;
float radius=0.03;
int ptr=0;
int faltu_bit=1;
float color[3][3]={{1.0,1.0,1.0},{1.0,1.0,0.0},{0.0,1.0,0.0}};
void drawText(char *str,float x,float y,int id)
{
int i;
int len=strlen(str);
//glLoadIdentity();
glColor3f(color[id][0],color[id][1],color[id][2]);
glRasterPos2f(x,y);
for(i=0;i<len;i++)
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,str[i]);
}
void init()
{
glClearColor( 0.0, 0.0, 0.0, 1.0);
glMatrixMode( GL_PROJECTION);
gluOrtho2D(0.0,WIDTH,0.0,HEIGHT);
memset(arr,0,5000);
glPointSize(20.0);
}
void resetAll()
{
memset(arr,0,5000);
z=0;
}
///OPENGL MAPPING///
float getOpenGLX(int x)
{
double ox = x/ (double)WIDTH*(WIDTH);
return ox;
}
float getOpenGLY(int y)
{
double oy = (1 - y/ (double) HEIGHT)*HEIGHT;
return oy;
}
void drawPoints()
{
glBegin( GL_POINTS );
glColor3f( 0.0,1.0,0.0 );
for ( int i = 0; i < z; i++ )
{
glVertex2f( arr[i][0],arr[i][1]);
}
glEnd();
}
void drawBall(float x,float y)
{
glBegin( GL_POINTS);
glColor3f( 1.0,1.0,0.0 );
glVertex2f(x,y);
glEnd();
}
void drawLines()
{
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
for(int i=0;i<z;i++)
{
glVertex2f(arr[i][0],arr[i][1]);
}
glEnd();
}
void addValue(int x,int y)
{
arr[z][0]=getOpenGLX(x);
arr[z++][1]=getOpenGLY(y);
}
void trackBall()
{
drawPoints();
}
void myDisplay()
{
glClear( GL_COLOR_BUFFER_BIT);
if(!flag)
{
drawLines();
if(!faltu_bit)
drawBall(arr[ptr][0],arr[ptr][1]);
}
if(faltu_bit)
{
drawText("Project by: Adil Ansar [10 CSS-32]",50.0,500.0,0);
drawText("Welcome",250.0,300.0,1);
drawText("Drag the Mouse Any Where in the Window to see the Path",10.0,200.0,2);
}
glutSwapBuffers();
glutPostRedisplay();
glFlush();
}
void myMouseStat(int button,int state,int x, int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
if(!flag)
{
if(faltu_bit)
{
faltu_bit=0;
}
resetAll();
flag=1;
}
}
else if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
{
if(flag)
{
ptr=0;
flag=0;
}
}
}
void myPressedMove(int x,int y)
{
if(flag)
{
addValue(x,y);
}
}
void myTimer(int t)
{
if(ptr!=z)
{
ptr++;
}
else
{
ptr=0;
}
glutTimerFunc(100,myTimer,0);
}
int main( int argc, char ** argv)
{
glutInit( &argc, argv);
glutInitDisplayMode( GLUT_DOUBLE| GLUT_RGB);
glutInitWindowPosition( 100, 100);
glutInitWindowSize(WIDTH,HEIGHT);
glutCreateWindow( "Testing");
init();
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouseStat);
glutMotionFunc(myPressedMove);
glutTimerFunc(100,myTimer,0);
glutMainLoop();
return 0;
}
This Is What I get:
In this code
void drawLines()
{
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
for(int i=0;i<z;i++)
{
glVertex2f(arr[i][0],arr[i][1]);
}
glEnd();
}
GL_LINES is a drawing mode where two consecutive vertices make a line segment. Then the next two and so so. What you're drawing is a line strip; replacing GL_LINES with GL_LINE_STRIP will give you your expected result.
On a side note: You should abandon using immediate mode (glBegin, glVertex, glEnd). It's slow, it's cumbersome to work with and in the long term can become a major PITA. Use at least vertex arrays; they've been the recommended way of supplying geometry data for well over 15 years. Plus it makes your code much simpler. Your code above can be replaced with this:
/* vertex data comes from an array */
glEnableClientState(GL_VERTEX_ARRAY);
/* we want to use a common color for all vertices */
glDisableClientState(GL_COLOR_ARRAY);
glColor3f(1.0, 0.0, 0.0);
/* where to get the data from */
glVertexPointer(2, GL_DOUBLE, sizeof(double)*4, arr);
/* draw the whole thing */
glDrawArrays(GL_LINE_STRIP, 0, z);
/* cleanup */
glDisableClientState(GL_VERTEX_ARRAY);
As you can see it's shorter, more concise, easier to read and it avoids doing z+3 function calls, each of which taking some time to execute.
Important that OpenGL can digest that multidimensional array arr is due to the fact, that statically allocated storage of multidimensional arrays is always contiguous. It would not work if you'd allocate an array of pointers to arrays (the naive way to allocate multidimensional arrays dynamically).

Checkerboard w/ openGL glRecti

I have a pretty straightforward question. We are asked to make a checkerboard using glRecti in c++ using visual basic 2010. Here's what I have so far and was wondering if anyone can point me in the right direction.
#include <gl/glut.h>
void myInit(void)
{
glClearColor(1.0,1.0,1.0,0.0); // set white background color
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void drawChecker(int size)
{
int i = 0;
int j = 0;
for (i = 0; i < 7 ; i++) {
if((i + j)%2 == 0) // if i + j is even
glColor3f( 0.4, 0.2, 0.6);
else
glColor3f( 0.2, 0.3, 0.4);
glRecti(i*size, j*size, size, size); // draw the rectangle
j++;
}
glFlush();
}
void checkerboard(void) {
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
drawChecker(32);
}
void main(int argc, char** argv)
{
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize(640,480); // set window size
glutInitWindowPosition(100, 150); // set window position on screen
glutCreateWindow("null"); // open the screen window
glutDisplayFunc(checkerboard); // register redraw function
myInit();
glutMainLoop(); // go into a perpetual loop
}
You should try
for (i = 0; i < 8 ; ++i) {
for (j = 0; j < 8; ++j) {
if((i + j)%2 == 0) // if i + j is even
glColor3f( 0.4, 0.2, 0.6);
else
glColor3f( 0.2, 0.3, 0.4);
glRecti(i*size, j*size, (i+1)*size, (j+1)*size); // draw the rectangle
}
}
You should think if you would rather want to let i and j go to 7 and not to 6, which would make a real checkerboard. Remember that the loop is repeated as long as i is lower than 7 (therefore it is done for i from 0 to 6). Therefore I changed the 7 to 8. If the 7 was really intended, then excuse me for taking this freedom.
Furthermore are the last two arguments not the size of the rectangle, but its opposite vertex, therfore the use of i+1 and j+1.