OpenGL drawing a grid - opengl

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.

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;

GLUT individual pixel manipulation produces unexpected result

For the sake of learning, I'm accessing individual pixel data using GLUT and manually setting pixel color by going through all pixels in the window, like this (some non-related code omitted):
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, WIDTH, 0.0, HEIGHT);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
glPointSize(1.0f);
glColor3f(255, 0, 0);
glBegin(GL_POINTS);
glVertex2i(i, j);
glEnd();
}
}
glutSwapBuffers();
}
void timer(int obsolete) {
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("GLUT Test");
init();
glutDisplayFunc(display);
timer(0);
glutMainLoop();
return 0;
}
I'm expecting to get a fully red pixels window, but I'm getting something different - a window with black vertical stripes, as if horizontal for loop suddenly skipped some lines.
Any ideas what am I doing wrong here? I have a suspicion it might be related to float to int conversion somewhere "inside", but I'm not sure what to search for.
Edit: I've found out that if I resize the window in runtime to be one pixel less in width, then these black stripe tears disappear.
You set up the projection such that the left edge is at 0, and the right one at WIDTH. Note that your pixels are small squares with an area, and this means that 0.0 maps to the left edge ot the left-most pixel, and WIDTH maps to the right edge of the right-most pixel. Integer coordinates will lie exactly in the middle between two pixels. And with some numerical precision loss during transformation, you might end up with two neighboring points beeing rounded to the same pixel.
You can either add 0.5 to x and y when drawing your points, or just shift your orth projection by half a pixel so that integers are mapped to pixel centers:
Ortho(-0.5f, WIDTH-0.5f, -0.5f, HEIGHT-0.5f, ...);

How to make 2d Chess Board in OpenGl

I have to make a 2d Chess Board of 8 * 8 blocks in OpenGL with VisualC++. I have the following code that i tried .
But I have a problem in this code .
I can't reduce the board size. e.g. 5*5.
When i click on the window it redraws the board.
I want to make this code to just work with loops. Except If , Else.
#include<GL\glut.h>
int black=0,white=1,color=0;
GLint a1=10,b1=10,a2=30,b2=30;
void init (void)
{
glClearColor (0.0, 0.0,1.0,0.0);
glMatrixMode (GL_PROJECTION);
glClear (GL_COLOR_BUFFER_BIT);
gluOrtho2D (0.0,120.0,0.0,140.0);
}
void lineSegment ()
{
for(int i=0;i<3;i++)
{
if(b2<120)
{
a1=10;b1=b2;
a2=30;b2=b2+20;
}
for(int j=0;j<5;j++)
{
if(a2<120)
{
if(color==black)
{
glColor3f(0,0,0);
glRecti(a1,b1,a2,b2);
color=1;
a1=a2;
a2=a2+20;
}
else
{
glColor3f(1,1,1);
glRecti(a1,b1,a2,b2);
color=0;
a1=a2;
a2=a2+20;
}
}
}
//GLint a1=10,b1=10,a2=30,b2=30;
}
glFlush();
}
void main (int argc, char** argv)
{
glutInit(&argc,argv); //Initialize GLUT.
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // Set display mode.
glutInitWindowPosition (50,100); //Set top-left display-window position.
glutInitWindowSize (400,300); //Set display-window width and height.
glutCreateWindow ("An Example OpenGL Program"); //Create display window.
init(); // Execute initialization procedure.
glutDisplayFunc(lineSegment); //send graphics to display window.
glutMainLoop(); //display everything and wait.
}
Im going to suggest you significantly reduce the code you are working with. Define a width and height for the board and the number of divisions per side of the board.
Lets define width and height as w and h respectively and the number of divisions n and m respectively. w.l.o.g. assume n and m divide w and h evenly.
void DrawBoard(int w, int h, int n, int m) {
bool color = true;
int sw = w/n, sh = h/m; //square width and height respectively
//for each width and height draw a rectangle with a specific color
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
//oscillate the color per square of the board
if(color)
glColor3f(1, 1, 1);
else
glColor3f(0, 0, 0);
color = !color;
//draw a rectangle in the ith row and jth column
glRecti(i*sw, j*sh, (i+1)*sw, (j+1)*sh);
}
if(m % 2 == 0) color = !color; //switch color order at end of row if necessary
}
}
This should give the basic idea, though I might have hessed up an index or two. But essentially, iterate over the grid cells and draw a rectangle per board square.
This code will also draw the board starting at coordinate (0, 0) and finishing at (w, h). However if you would like it in an arbitrary position you can either add an (x, y) to eaxh corresponding coordinate in the glRecti call, or learn about transforms in openGL and use glTranslatef.

Draw a rectangle with mouse in GLUT

I am fairly new to using GLUT, and I have been attempting to compile a program (which I found here, first response) that uses the mouse to draw a rectangle by recording the starting and ending points of a click-and-drag.
As a clean copy/paste, it will compile but not draw anything. It just displays a white screen, even after changing the background color to black (in the setup() function). I've read several sources to verify that this program doesn't miss anything in its draw and reshape functions, and it's all there.
I create a window, set the viewport to the window dimensions, and then use the gluOrtho2D function to set the mapping (since the window and viewport are the same dimensions, I set the mapping to the window dimensions). The mouse callback records where I left-click, and where I release left-click, then calls the glutPostRedisplay() function to redraw the window with the new coordinates. After a bit of debugging, I discovered the coordinates are recorded and saved appropriately, and are measured in pixels (x and y are integers between 0 and window dimension), so I should be able to draw a rectangle from one vertex to the other vertex using the coordinates. But, like I said, it only displays a white screen.
So, is there something wrong with the way I am drawing the rectangle? Am I mapping the window incorrectly? I am seriously lost, and any feedback would be greatly appreciated.
EDIT2: I changed the glutInitDisplayMode from GLUT_SINGLE to GLUT_DOUBLE, and that fixed the whole non-interactive white screen thing. Now it will draw a rectangle with the mouse with a flipped y-coordinate (which I fixed), and it works great now. Thank you very much for the suggestion.
Here is my program (EDIT1: added comments):
#include <cstdlib>
#include <GL/glut.h>
using namespace std;
GLsizei width, height;
struct Position
{
Position() : x(0), y(0) {}
float x;
float y;
};
Position start; // Records left-click location
Position finish; // Records left-click release location
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // clear window
glColor3ub(rand()%256, rand()%256, rand()%256); // generates random color
glBegin(GL_QUADS);
glVertex2f(start.x,start.y);
glVertex2f(finish.x,start.y);
glVertex2f(finish.x,finish.y);
glVertex2f(start.x,finish.y);
glEnd();
glutSwapBuffers(); // display newly drawn image in window
}
void reshape( int w, int h )
{
glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); // set to size of window
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, (float)w, 0.0, (float)h );
width = w; // records width globally
height = h; // records height globally
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state==GLUT_DOWN)
{
start.x = x; //x1
start.y = y; //y1
}
if(state==GLUT_UP)
{
finish.x = x; //x2
finish.y = y; //y2
}
break;
glutPostRedisplay();
}
}
void motion( int x, int y )
{
finish.x = x;
finish.y = y;
glutPostRedisplay();
}
void setup()
{
glClearColor(0.0, 0.0, 0.0, 1.0); // *should* display black background
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,100);
glutCreateWindow("");
setup();
// initializing callbacks
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}
As my comment suggested:
change:
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
to:
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

opengGL drawing a line

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?