How to make 2d Chess Board in OpenGl - c++

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.

Related

OpenGl glutIdleFunc Animation

My problem
I am still learning opengl and I was working on a game similar to chicken invaders. What I am trying to do is to have a background similar to that of chicken invaders with some stars and galaxy. I did that using a quad with the size of the screen that I added texture to. Up until now all is good but I am now trying to translate this galaxy background downward so that the spaceship and the chicken seem as if they are moving forward through space. My idea is to used glutIdleFunc() function and on every iteration, I should sleep first for 30 milliseconds then update the galaxy background so that every row of pixels is moved downward by 1 row and the last row is copied to the first row. The problem is that this approach works fine for the about 15 seconds then the program stops completely and my computer hangs and freezes to the extent that I need to restart my pc. I think my approach requires ridiculously many operations every time glutIdleFunc() is called. I searched for people who faced similar situations online but I found no similar post.
code:
main function
int main(int argc, char** argr) {
glutInit(&argc, argr);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_WIDTH);
// background is a global variable that contains the bitmap array
int err = load_image("Art/background.bmp", &background);
if(err)
{
fprintf(stderr, "%d\n", err);
exit(1);
}
glutCreateWindow("OpenGL - 2D Template");
glutDisplayFunc(Display);
glutMotionFunc(mo);
glutMouseFunc(mou);
glutIdleFunc(Animate);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
gluOrtho2D(0.0, 1000, 0.0, 600);
glutMainLoop();
}
Animation
void Animate(void)
{
msleep(300);
translate_image(&background, 30);
glutPostRedisplay();
}
void translate_image(image_t* img, const int c)
{
uint32_t copy[img->height][img->width];
for(int i = 0; i < img->height; i++)
{
for(int j = 0; j < img->width; j++)
{
copy[i][j] = img->data[i * img->width + j];
}
}
for(int i = 0; i < img->height; i++)
{
for(int j = 0; j < img->width; j++)
{
int index = (i + c) % img->height;
img->data[index * img->width + j] = copy[i][j];
}
}
}
Display Function
void Display() {
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
texture = glInitTexture(background);
drawImage(texture, 0.0f, 0.0f, background.width, background.height);
glDisable(GL_TEXTURE_2D);
drawSpaceShip();
glFlush();
}
Main question
is There a more efficient way to do the same thing I am trying to do with freezing my computer every time I run it ?
You don't have to copy around the picture contents. It suffices to animate the texture coordinates, which you use to map the picture to the quad.
Also you must call glutInitDisplayMode before glutCreateWindow for it to have an effect. Also you don't want a single buffered framebuffer, but a double buffered one GLUT_DOUBLE instead of GLUT_SINGLE and call glutSwapBuffers instead of glFinish.

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, ...);

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.

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);

Opengl,C++ : Large number of points

I'm currently working on a program, that will be able to visualize the evolution of point on the plane that are flowing along a vectorfield. I've finished the first version which I've pasted below. When running the program with a large number of points it seems that only the last say 30000 points gets drawn into the window. I'd like to be able to draw about 1000000 points, so I'm way off.
I've tried lovering the number if iterations (the Iteration variable - controlling the number of points), and here it acts just fine. However when increasing it substantially the first part is no longer drawn.
#include <iostream>
#include <stdio.h>
#include <math.h>
//#include <gsl/gsl_math.h>
//#include <gsl/gsl_sf.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
using namespace std;
//Initial iterations to make the system settle:
int initIter=0;
//Iterations once system has settled:
int Iterations = 100000;
/**Starting point in time-phase-space (t,x,y,vx,vy).
For mathematical reasons the last two components should
always be 0**/
float TPS[5]={0,0.00,0.100,0.00,0.000};
//Timestep:
float dt=0.001;
/**The Step function make one Picard
iteration **/
float * Step(float * Arr){
static float NewTPS[5];
NewTPS[0] = Arr[0]+dt;
NewTPS[1] = Arr[1]+Arr[3]*dt;
NewTPS[2] = Arr[2]+Arr[4]*dt;
//This is the dynamical functions:
NewTPS[3] = -Arr[2];
NewTPS[4] = Arr[1];
return NewTPS;
}
/** This function sets up GLUT plotting
window: **/
void myInit(){
// set the background color
glClearColor(0.0f, 0.0f, 0.0f, 1.00f);
// set the foreground (pen) color
glColor4f(1.0f, 1.0f, 1.0f, 0.04f);
// set up the viewport
glViewport(0, 0, 800, 800);
// set up the projection matrix (the camera)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-2.0f, 2.0f, -2.0f, 2.0f);
// set up the modelview matrix (the objects)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Computing initial iterations:
for (int i=0;i<initIter;i++){
//cout << TPS[1]<<" " << TPS[2] << endl;
float * newTPS2;
newTPS2 = Step(TPS);
//Assigning the values of newTPS2 to TPS:
for (int j=0; j<5;j++){
TPS[j]=*(newTPS2+j);
}
}
// enable blending
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// enable point smoothing
//glEnable(GL_POINT_SMOOTH);
//glPointSize(1.0f);
}
/** This function draws a the point that
is passed to it: **/
void Draw(){
// clear the screen
glClear(GL_COLOR_BUFFER_BIT);
// draw some points
glBegin(GL_POINTS);
for (int i = 0; i <Iterations ; i++) {
float * newTPS2;
//cout << TPS[0]<< " " << TPS[1] << " " << TPS[2]<< endl;
newTPS2 = Step(TPS);
//Assigning the values of newTPS to TPS:
for (int j=0; j<5;j++){
TPS[j]=*(newTPS2+j);
}
// draw the new point
glVertex2f(TPS[1], TPS[2]);
}
glEnd();
// swap the buffers
glutSwapBuffers();
//glFlush();
}
int main(int argc, char** argv){
// initialize GLUT
glutInit(&argc, argv);
// set up our display mode for color with alpha and double buffering
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(800, 800);
glutCreateWindow("Trace of 2D-dynamics");
myInit();
// register our callback functions
glutDisplayFunc(Draw);
// glutKeyboardFunc(mykey);
// start the program
glutMainLoop();
return 0;
}
If you want to just color specific pixels on the screen, you should't be using glVertex at all. Put them all in a contiguos memory block, create a texture from it and render a quad covering the whole screen. That might be faster than calculating their positions inside OpenGL.
Probably in your implementation the size of a primitive is limited to a signed short, that is 32768 points. If that is the case you have to do glEnd/glBegin for each group of 32768 points or so:
for (int i = 0, x = 0; i <Iterations ; i++, x++) {
//...
if (x >= 32768)
{
x = 0;
glEnd();
glBegin(GL_POINTS);
}
//...
}
BTW, you may consider using vertex buffer objects (VBO). This limitation is likely the same, but are quite faster to draw.