creating a grids of squares (2D) in opengl using c++ - c++

I want to make a square (2D) by using several smaller squares(like a grid). I need to do this because I want to texture an image on the main square and divide the picture into several pixels(the said smaller squares).
Here's the program:-
int h=1,w=1;
int res=25;// res is the number of smaller squares I want
float hratio=h/res;
float wratio=w/res;
void Draw()
{
float x,y;
for(y=-.5;y<=h;y+=h/res)
{
for(x=-.5;x<=w;x+=w/res)
{
glColor3f(1,1,1);
glBegin(GL_QUADS);
glVertex3f(x,y+(h/res),0);
glVertex3f(x+(w/res),y+(h/res),0);
glVertex3f(x+(w/res),y,0);
glVertex3f(x,y,0);
glEnd();
}
}
glFlush();
glutPostRedisplay();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Draw();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int iArgc, char** cppArgv)
{
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutInitWindowPosition(200, 200);
glutCreateWindow("PIXELS");
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
when I run this program, all I get is a black screen.

Try this display function:
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
//set viewport
glViewport(0, 0, screen.width, screen.height);
//set projection matrix using intrinsic camera params
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = screen.width*1.0/screen.height;
//gluPerspective is arbitrarily set, you will have to determine these values based
//on the intrinsic camera parameters
gluPerspective(60.0f, aspect, 0.1f, 100.0f);
//you will have to set modelview matrix using extrinsic camera params
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
Draw();
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
gluPostRedisplay();
}
In your case screen.width is 600 and screen.height is 600.

Related

Wrong display when using glutReshapeFunc to change window size

I have know that glutReshapeFunc can be used to react to window resize, so I used it to reset projection matrix and render shape to match the window. The code is as the following:
#include <GLUT/glut.h>
GLsizei wndWidth = 400;
GLsizei wndHeight = 300;
void init() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 400, 0, 300);
}
void drawSegment() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex2i(10, 10);
glVertex2i(wndWidth-10, wndHeight-10);
glVertex2i(wndWidth-10, 10);
glEnd();
glFlush();
}
void reshapeFunc(int width, int height) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, GLdouble(width), 0, GLdouble(height));
glClear(GL_COLOR_BUFFER_BIT);
wndWidth = width;
wndHeight = height;
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(400, 300);
glutInitWindowPosition(0, 0);
glutCreateWindow("Draw Window");
init();
glutDisplayFunc(drawSegment);
glutReshapeFunc(reshapeFunc);
glutMainLoop();
}
In my opinion, After window resize, the triangle should always take up half of the window. But in fact, the triangle remains its size after window resize, as if wndWidth and wndHeight does not change in drawSegment.
So why i get the wrong result and how can i fix it?
The projection matrix transforms the view coordinates to clip coordinates and clip coordinates are transformed to normalized device coordinates (at orthographic projection clip coordinates and normalized device coordinates are equal).
How the normalized device coordinates are mapped to window coordinates is specified by glViewport.
After the size of the window has changed you have to respecify the mapping:
void reshapeFunc(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, GLdouble(width), 0, GLdouble(height));
wndWidth = width;
wndHeight = height;
}

need help moving a camera in OpenGL

I am working on a simple OpenGL project.
I want to get a simple camera to move in perspective mode.
I keep reading about the projection matrix, gluLookAt, and the model view matrix. I keep reading that all I should do are my perspective calls in the projection matrix and then all of my transformations and camera movement in the model view matrix.
#include "GLheaders.h"
void drawWorldAxis() {
glLoadIdentity();
glBegin(GL_LINES);
glNormal3f(0, 0, 1);
glColor3ub(255, 0, 0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3ub(0, 255, 0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3ub(0, 0, 255);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
}
void keyboard(unsigned char key, int x, int y) {
glutPostRedisplay();
}
static float eye[3] = {.5, .5, .5};
#include <stdio.h>
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, .1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawWorldAxis();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
eye[0] += .1;
eye[1] += .1;
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, -1, 10000);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Tiny Test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return EXIT_SUCCESS;
}
I am expecting this code to display three lines representing the world coordinate system's x, y, and z axises, and as keys are pressed the camera should move and start to look at the origin/coordinate axises from more and more drastic angles.
What is going wrong here? I've been bashing my head into a wall trying to figure out why nothing is moving. It only changes if I put the gluLookAt call in the projection matrix which I keep being told is a terrible idea.
The coordinate cross is drawn before you set the lookAt matrix, thus the matrix has no effect.
You have to change the order such that the matrix is already present when drawing:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
Then there is a second problem: You are resetting the model matrix in the first line of drawWorldAxis. Here, you can either remove the glLoadIdentity call or push the previous matrix to the stack first:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
glPushMatrix();
drawWorldAxis();
glPopMatrix();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
thanks to #BDL for helping fix this! This is the correct code that I wanted
#include "GLheaders.h"
void drawWorldAxis() {
glBegin(GL_LINES);
glNormal3f(0, 0, 1);
glColor3ub(255, 0, 0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3ub(0, 255, 0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3ub(0, 0, 255);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
}
void keyboard(unsigned char key, int x, int y) {
glutPostRedisplay();
}
static float eye[3] = {-.1, -.1, 1};
#include <stdio.h>
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, .1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
eye[0] += .1;
eye[1] += .1;
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, -1, 10000);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Tiny Test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return EXIT_SUCCESS;
}

How to make the background of my texture transparent? (My image is already backgroundless)

I have a backgroundless image of a gun. I am trying to build a first person shooter game with the help of this 2D image of a gun. I have loaded the texture in my program but I am unable to make the background of the gun transparent. Moreover, why should I even have to do that when my image is already backgroundless. I used clippingmagic.com to remove the background of my image. The code is:
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
#include<SOIL/SOIL.h>
//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
using namespace std;
const float A = 1366.0; //width of the computer screen
const float B = 768.0; //height of the computer screen
//Called when a key is pressed
void handleKeypress(unsigned char key, //The key that was pressed
int x, int y) { //The current mouse coordinates
switch (key) {
case 27: //Escape key
exit(0); //Exit the program
}
}
//Initializes 3D rendering
void initRendering() {
//Makes 3D drawing work when something is in front of something else
glEnable(GL_DEPTH_TEST);
}
//Called when the window is resized
void handleResize(int w, int h) {
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //Reset the camera
gluPerspective(45.0, //The camera angle
(double)w / (double)h, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0); //The far z clipping coordinate
}
//Draws the 3D scene
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0,0.0,-10.0);
//DRAW WALL OF ROOM
glBegin(GL_QUADS);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(-100.0, -100.0, -100.0);
glVertex3f(-100.0, 100.0, -100.0);
glVertex3f( 100.0, 100.0, -100.0);
glVertex3f( 100.0, -100.0, -100.0);
glEnd();
//DRAW GUN
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLuint gun_tex_id = SOIL_load_OGL_texture
(
"GUN.png",
SOIL_LOAD_RGB, //I even tried SOIL_LOAD_AUTO and SOIL_LOAD_RGBA but it didn't help
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_MULTIPLY_ALPHA
);
glBindTexture(GL_TEXTURE_2D, gun_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTranslatef(2.0,0.0,0.0);
glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-4.1,-4.15, 0.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 3.0,-4.15, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 3.0, 1.2, 0.0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-4.1, 1.2, 0.0);
glEnd();
glDisable(GL_BLEND);
glutSwapBuffers(); //Send the 3D scene to the screen
}
void myinit(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); /* gray background */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( -A/2, A/2, -B/2, B/2, -200, 200);
/* In World coordinates:position the "clipping rectangle" at -A/2, its right edge at +A/2, its bottom edge at -B/2 and its top edge at +B/2 */
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(A, B); //Set the window size
//Create the window
glutCreateWindow("My shooting game");
initRendering(); //Initialize rendering
//Set handler functions for drawing, keypresses, and window resizes
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
myinit();
glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
return 0; //This line is never reached
}
You can do it using glBlendFunc function.
Try adding the following code snippet before you bind texture to the object.
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Read this for more information.

My display() function only displays when it enters it the first time. Then it shows a blank window

void init(void)
{
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
void display(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glScalef(1.0,1.0,1.0);
glColor3f(0.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd();
glutSwapBuffers();
}
void reshape(int w, int h)
{
int height = h;
int width = w;
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char* argv[])
{
Complex c(0,0);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutInitWindowPosition(100, 100);
winID = glutCreateWindow("Fractal");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
// Compute the update rate here...
glutMainLoop();
return 0;
}
I get a square if I put the code in display(), except the glutSwapBuffers() in if condition which checks whether the code has entered display the first time. If I remove the if, I get a white window
Put an extra glTranslatef(0.0f, 0.0f, -5.0f) in your display function, to push everything 5 units back into the scene, otherwise you wont see what you're drawing at the origin.
Btw, the line glScalef(1.0,1.0,1.0) doesn't do anything, remove it to avoid unnecessary calculations.
EDIT:
There is no "eye" in OpenGL. More specifically, it is always fixed at (0,0,0) looking down at the negative z-axis. You have to move the whole scene with the inverse of the eye transformations. You can either move the scene manually so your eye can see it, or use gluLookAt, where you can specify the "eye", but in the background it just transforms the scene so the fixed "eye" can see it.
Further reading: http://www.opengl.org/archives/resources/faq/technical/viewing.htm

3D Scrolling Scene - OpenGL

I'm trying to draw clouds in the window and animate them towards the camera. The problem I'm having is that I want to do this continuously without anything being abruptly redrawn. Can someone tell me what I'm missing here?
Here is the code:
#include <gl/glut.h>
int width = 800, height = 600;
float theta = 0, distance1 = -600, distance2 = -600;
void drawCloud()
{
glPushMatrix();
glTranslated(1,0,-2);
glutSolidSphere(4,10,10);
glTranslated(-2,0,-5);
glutSolidSphere(4,10,10);
glTranslated(-1,0,3);
glutSolidSphere(4,10,10);
glPopMatrix();
}
void drawCloudFormation()
{
glPushMatrix();
glTranslated(-60,30,-300);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(15,3,-150);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(50,30,-200);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(-15,-15,-250);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(25,-25,-100);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(-30,0,-50);
drawCloud();
glPopMatrix();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glPushMatrix();
glTranslated(0,0,distance1);
drawCloudFormation();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,distance1-200);
glScaled(-1,1,1);
drawCloudFormation();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,distance2-400);
glScaled(1,1,-1);
drawCloudFormation();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,distance2-600);
glScaled(-1,1,1);
glScaled(1,1,-1);
drawCloudFormation();
glPopMatrix();
glutSwapBuffers();
}
void idle()
{
theta += 0.2;
if (theta == 360) theta = 360;
distance1 += 1;
if (distance1 > 200) distance1 = -600;
distance2 += 1;
if (distance2 > 600) distance2 = -600;
glutPostRedisplay();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 200);
glutCreateWindow("Space Ship");
glClearColor(0, 0, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(120, 1, 0.1, 600);
//glOrtho(-2, 2, -2, 2, 0.1, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0, 0, -200, 0, 0, -600, 0, 1, 0);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMainLoop();
}
Look into particle systems.
You essentially want a rectangular emitter on the far side of your scene spewing clouds (particles) with a fixed velocity toward the camera. When the clouds move behind the camera mark them as inactive and the particle system will spawn a new ones back at the emitter.