OpenGL How to use mouse picking square and drag it? - c

This is some of my code!~~
Why I changed the colour of square, but it does not work? Can any one help me? And How can I use the mouse to move these three square?
#include <GL/glut.h>
#include <stdio.h>
const GLint pickSize = 32;
int winWidth = 400, winHeight = 300;
void Initial(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void DrawRect(GLenum mode)
{
if(mode == GL_SELECT) glPushName(1);
glColor3f(1.0f,0.0f,0.0f);
glRectf(60.0f,50.0f,150.0f,150.0f);
if(mode == GL_SELECT) glPushName(2);
glColor3f(0.0f,1.0f,0.0f);
glRectf(230.0f,50.0f,330.0f,150.0f);
if(mode == GL_SELECT) glPushName(3);
glColor3f(0.0f,0.0f,1.0f);
glRectf(140.0f,140.0f,240.0f,240.0f);
}
void ProcessPicks(GLint nPicks, GLuint pickBuffer[])
{
GLint i;
GLuint name, *ptr;
ptr=pickBuffer;
for(i=0;i<nPicks; i++){
name=*ptr;
ptr+=3;
ptr+=name-1;
Why I change the colour here, but it does not work? Can any one help me? And How can I use the mouse to move these three square?
if(*ptr==1) {glColor3f(1.0f,1.0f,1.0f);}
//printf("The color is red\n");
if(*ptr==2) printf("The colour is green.\n");
if(*ptr==3) printf("The colour is blue.\n");
ptr++;
}
printf("\n\n");
}
void ChangeSize(int w, int h)
{
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
DrawRect(GL_RENDER);
glFlush();
}
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
GLuint pickBuffer[pickSize];
GLint nPicks, vp[4];
if(button == GLUT_LEFT_BUTTON && action == GLUT_DOWN){
glSelectBuffer(pickSize,pickBuffer);
glRenderMode(GL_SELECT);
glInitNames();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT, vp);
gluPickMatrix(GLdouble(xMouse), GLdouble(vp[3]-yMouse),10.0,10.0,vp);
gluOrtho2D(0.0,winWidth,0.0,winHeight);
DrawRect(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
nPicks = glRenderMode(GL_RENDER);
ProcessPicks(nPicks, pickBuffer);
glutPostRedisplay();
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400,300);
glutInitWindowPosition(100,100);
glutCreateWindow("Picking");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutMouseFunc(MousePlot);
Initial();
glutMainLoop();
return 0;
}

OpenGL is a drawing API, not a scene graph. If you want to change something in the visible scene, you have to redraw it. Executing some random OpenGL state commands in a event handler will just set OpenGL state, but not change anything visible.
In the event handler, change a variable's value, then issue a redraw (with GLUT redrawing is issued by calling glutPostRedisplay()). In the drawing code, use the variable's value to control the drawing process, like setting the color used for the next thing drawn.
Update
Here's code of a very simple GLUT based program that cycles a quads color through white, red, green, blue, white, … when clicking into the window
/* Language: ANSI-C */
#include <GL/glut.h>
#define N_COLORS 4
static GLfloat colors[4][3] = {
{1,1,1},
{1,0,0},
{0,1,0},
{0,0,1}
};
static int colorindex = 0;
static GLfloat const quad[][2] = {
-1, -1,
1, -1,
1, 1,
-1, 1
};
static void cycle_color(void)
{
colorindex = (colorindex+1) % N_COLORS;
}
static void redraw(float width, float height)
{
float const aspect = width/height;
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0,0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.5*aspect, 1.5*aspect, -1.5, 1.5, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, quad);
glColor3fv(colors[colorindex]);
glDrawArrays(GL_QUADS, 0, 4);
}
static void onMouseClick(int btn, int state, int x, int y)
{
if( GLUT_DOWN == state ) {
cycle_color();
}
glutPostRedisplay();
}
static void onDisplay(void)
{
int const win_width = glutGet(GLUT_WINDOW_WIDTH);
int const win_height = glutGet(GLUT_WINDOW_HEIGHT);
redraw(win_width, win_height);
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("click to change color");
glutDisplayFunc(onDisplay);
glutMouseFunc(onMouseClick);
glutMainLoop();
return 0;
}

Related

Generate an object on mouse click OpenGL GLUT

I have created this code where a plane follow the mouse position.
#include <GL/freeglut_std.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>
float objX = 100;
float objY = 100;
float objSize = 50;
void motion(int x, int y) {
objX = x;
objY = y;
}
void drawRect(float x, float y, float size) {
glPushMatrix();
glTranslatef(x, y, 0.0f);
glScalef(size, size, 1.0f);
glBegin(GL_QUADS);
glColor3ub(255, 255, 255);
glVertex2f(-1, -1);
glVertex2f(1, -1);
glVertex2f(1, 1);
glVertex2f(-1, 1);
glEnd();
glPopMatrix();
}
void drawStaticRect(float x, float y, float size) {
glPushMatrix();
glTranslatef(x, y, 0.0f);
glScalef(size, size, 1.0f);
glBegin(GL_QUADS);
glColor3ub(255, 255, 255);
glVertex2f(-1, -1);
glVertex2f(1, -1);
glVertex2f(1, 1);
glVertex2f(-1, 1);
glEnd();
glPopMatrix();
}
int c = 0;
void display() {
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawRect(objX, objY, objSize);
glutSwapBuffers();
}
void mouseClicks(int button, int state, int x, int y) {
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
drawStaticRect(objX, objY, objSize);
}
glutPostRedisplay();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutCreateWindow("GLUT");
glutDisplayFunc(display);
glutMouseFunc(mouseClicks);
glutPassiveMotionFunc(motion);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
When the left mouse button is pressed i want to draw the object in the actual position, and repeat the operation as many times i want.
void drawStaticRect(float x, float y, float size) {
glPushMatrix();
glTranslatef(x, y, 0.0f);
glScalef(size, size, 1.0f);
glBegin(GL_QUADS);
glColor3ub(255, 255, 255);
glVertex2f(-1, -1);
glVertex2f(1, -1);
glVertex2f(1, 1);
glVertex2f(-1, 1);
glEnd();
glPopMatrix();
}
void mouseClicks(int button, int state, int x, int y) {
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
drawStaticRect(objX, objY, objSize);
}
glutPostRedisplay();
My idea is when the event trigger i just call a function that generate a quads under the actual mouse position and call glutPostRedisplay() to update the scene.

How to make opengl text visible/change color?

I am doing a mini project on constructive solid geometry using openGL.I am trying to create two windows ,the first one shows my name,college name and other details and the second one will show the solid geometry window.My second screen is working perfectly fine,and i am able to print text on my first screen,but as the background is black in color and text should come in different colors but it's coming in black color only so it's not visible.Below is the code,can anyone check my code and tell me where's the error.
#include<GL/glut.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<GL/gl.h>
int isMainScreen=1;
enum {
CSG_A, CSG_B, CSG_A_OR_B, CSG_A_AND_B, CSG_A_SUB_B, CSG_B_SUB_A
};
/* just draw single object */
void one(void (*a) (void))
{
glEnable(GL_DEPTH_TEST);
a();
glDisable(GL_DEPTH_TEST);
}
/* "or" is easy; simply draw both objects with depth buffering on */
void or(void (*a) (void), void (*b) (void))
{
glEnable(GL_DEPTH_TEST);
a();
b();
glDisable(GL_DEPTH_TEST);
}
/* Set stencil buffer to show the part of a (front or back face) that's inside b's volume. Requirements: GL_CULL_FACE enabled, depth func GL_LESS Side effects: depth test, stencil func, stencil op */
void
firstInsideSecond(void (*a) (void), void (*b) (void), GLenum face, GLenum test)
{
glEnable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glCullFace(face); /* controls which face of a to use */
a(); /* draw a face of a into depth buffer */
/* use stencil plane to find parts of a in b */
glDepthMask(GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glCullFace(GL_BACK);
b(); /* increment the stencil where the front face of b is drawn */
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glCullFace(GL_FRONT);
b(); /* decrement the stencil buffer where the back face of b is drawn */
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilFunc(test, 0, 1);
glDisable(GL_DEPTH_TEST);
glCullFace(face);
a(); /* draw the part of a that's in b */
}
void
fixDepth(void (*a) (void))
{
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDepthFunc(GL_ALWAYS);
a(); /* draw the front face of a, fixing the depth buffer */
glDepthFunc(GL_LESS);
}
/* "and" two objects together */
void
and(void (*a) (void), void (*b) (void))
{
firstInsideSecond(a, b, GL_BACK, GL_NOTEQUAL);
fixDepth(b);
firstInsideSecond(b, a, GL_BACK, GL_NOTEQUAL);
glDisable(GL_STENCIL_TEST); /* reset things */
}
/* subtract b from a */
void
sub(void (*a) (void), void (*b) (void))
{
firstInsideSecond(a, b, GL_FRONT, GL_NOTEQUAL);
fixDepth(b);
firstInsideSecond(b, a, GL_BACK, GL_EQUAL);
glDisable(GL_STENCIL_TEST); /* reset things */
}
enum {
SPHERE = 1, CONE
};
/* Draw a cone */
GLfloat coneX = 0.f, coneY = 0.f, coneZ = 0.f;
void
cone(void)
{
glPushMatrix();
glTranslatef(coneX, coneY, coneZ);
glTranslatef(0.f, 0.f, -30.f);
glCallList(CONE);
glPopMatrix();
}
/* Draw a sphere */
GLfloat sphereX = 0.f, sphereY = 0.f, sphereZ = 0.f;
void
sphere(void)
{
glPushMatrix();
glTranslatef(sphereX, sphereY, sphereZ);
glCallList(SPHERE);
glPopMatrix();
}
int csg_op = CSG_A;
/* add menu callback */
void
menu(int csgop)
{
csg_op = csgop;
glutPostRedisplay();
}
GLfloat viewangle;
void redraw(void)
{
/* clear stencil each time */
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glPushMatrix();
glRotatef(viewangle, 0.f, 1.f, 0.f);
switch (csg_op) {
case CSG_A: one(cone);
break;
case CSG_B: one(sphere);
break;
case CSG_A_OR_B: or(cone, sphere);
break;
case CSG_A_AND_B: and(cone, sphere);
break;
case CSG_A_SUB_B: sub(cone, sphere);
break;
case CSG_B_SUB_A: sub(sphere, cone);
break;
}
glPopMatrix();
glutSwapBuffers();
}
/* animate scene by rotating */
enum {
ANIM_LEFT, ANIM_RIGHT
};
int animDirection = ANIM_LEFT;
void
anim(void)
{
if (animDirection == ANIM_LEFT)
viewangle -= 3.f;
else
viewangle += 3.f;
glutPostRedisplay();
}
/* ARGSUSED1 */
/* special keys, like array and F keys */
void
special(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT: glutIdleFunc(anim);
animDirection = ANIM_LEFT;
break;
case GLUT_KEY_RIGHT: glutIdleFunc(anim);
animDirection = ANIM_RIGHT;
break;
case GLUT_KEY_UP:
case GLUT_KEY_DOWN:
glutIdleFunc(0);
break;
}
}
/* ARGSUSED1 */
void
key(unsigned char key, int x, int y)
{
switch (key) {
case 'a': viewangle -= 10.f;
glutPostRedisplay();
break;
case 's':
viewangle += 10.f;
glutPostRedisplay();
break;
case '\13':
isMainScreen=1;
break;
mydisplay();
case '\033':
exit(0);
}
}
int picked_object;
int xpos = 0, ypos = 0;
int newxpos, newypos;
int startx, starty;
void
mouse(int button, int state, int x, int y)
{
if (state == GLUT_UP) {
picked_object = button;
xpos += newxpos;
ypos += newypos;
newxpos = 0;
newypos = 0;
} else { /* GLUT_DOWN */
startx = x;
starty = y;
}
}
#define DEGTORAD (2 * 3.1415 / 360)
void
motion(int x, int y)
{
GLfloat r, objx, objy, objz;
newxpos = x - startx;
newypos = starty - y;
r = (newxpos + xpos) * 50.f / 512.f;
objx = r * cos(viewangle * DEGTORAD);
objy = (newypos + ypos) * 50.f / 512.f;
objz = r * sin(viewangle * DEGTORAD);
switch (picked_object) {
case CSG_A:
coneX = objx;
coneY = objy;
coneZ = objz;
break;
case CSG_B:
sphereX = objx;
sphereY = objy;
sphereZ = objz;
break;
}
glutPostRedisplay();
}
void drawString1(float x, float y, float z, char * string) {
char * c;
glRasterPos3f(x, y, z);
for (c = string; * c != '\0'; c++) {
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, * c);
}
}
double vp_width = 512.0; // update by reshape
double vp_height = 512.0; // update by reshape
void frontscreen(void)
{
glDisable(GL_LIGHTING);
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glOrtho( 0, vp_width, vp_height, 0.0, -1.0, 1.0 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glColor3f(0.7,0.0,1.0);
drawString1(200.0,50.0,0.0,"MVJ College of Engineering");
glColor3f(0.7,0.0,1.0);
drawString1(165.0,90.0,0.0,"DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING");
glColor3f(1.0,0.5,0.6);
drawString1(185.0,130.0,0.0,"A MINI PROJECT ON:COMPUTER GRAPHICS");
glColor3f(1,0,0);
drawString1(175.0,170.0,0.0,"PROJECT TITLE:CONSTRUCTIVE SOLID GEOMETRY");
glColor3f(1,0.5,0);
drawString1(20,380,0.0,"BY:");
glColor3f(0.5,0,0.5);
drawString1(10,410,0.0,"NAME: ANSHU");
glColor3f(0.5,0,0.5);
drawString1(10,425,0.0,"USN:1MJ15CS016");
glColor3f(0.5,0,0.5);
drawString1(10,440,0.0,"SEC:A");
glColor3f(0.5,0,0.5);
drawString1(10,455,0.0,"SEMESTER:VI");
glColor3f(1,0.5,0);
drawString1(420,380,0.0,"GUIDE:");
glColor3f(0.5,0,0.5);
drawString1(390,400,0.0,"NAME:Ms. Devisivashankari p");
glColor3f(1,0.1,1);
drawString1(200,480,0.0,"PRESS ENTER TO START");
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
glutSwapBuffers(); // <----- glutSwapBuffers insted of glFlush
glutPostRedisplay();
}
void mydisplay() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if (isMainScreen) {
frontscreen();
} else {
redraw();
}
}
int main(int argc, char **argv)
{
static GLfloat lightpos[] =
{25.f, 50.f, -50.f, 1.f};
static GLfloat sphere_mat[] =
{1.f, .5f, 0.f, 1.f};
static GLfloat cone_mat[] =
{0.f, .5f, 1.f, 1.f};
GLUquadricObj *sphere, *cone, *base;
glutInit(&argc, argv);
glutInitWindowSize(1024,720);
glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE);
(void) glutCreateWindow("csg");
glutDisplayFunc(frontscreen);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutCreateMenu(menu);
glutAddMenuEntry("A only", CSG_A);
glutAddMenuEntry("B only", CSG_B);
glutAddMenuEntry("A or B", CSG_A_OR_B);
glutAddMenuEntry("A and B", CSG_A_AND_B);
glutAddMenuEntry("A sub B", CSG_A_SUB_B);
glutAddMenuEntry("B sub A", CSG_B_SUB_A);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
/* make display lists for sphere and cone; for efficiency */
glNewList(SPHERE, GL_COMPILE);
sphere = gluNewQuadric();
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,sphere_mat);
gluSphere(sphere, 20.f, 64, 64);
gluDeleteQuadric(sphere);
glEndList();
glNewList(CONE, GL_COMPILE);
cone = gluNewQuadric();
base = gluNewQuadric();
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat);
gluQuadricOrientation(base, GLU_INSIDE);
gluDisk(base, 0., 15., 64, 1);
gluCylinder(cone, 15., 0., 60., 64, 64);
gluDeleteQuadric(cone);
gluDeleteQuadric(base);
glEndList();
glMatrixMode(GL_PROJECTION);
glOrtho(-50., 50., -50., 50., -50., 50.);
glMatrixMode(GL_MODELVIEW);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
frontscreen method is the first screen which should come.
i am able to print text on my first screen,but as the background is black in color and text should come in different colors but it's coming in black color only so it's not visible
When lighting (GL_LIGHTING) is enabled, then the color is taken from the material parameters (glMaterial).
If you still want to use the current color, the you have to enable GL_COLOR_MATERIAL
and to set the color material paramters (glColorMaterial):
glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
See also Basic OpenGL Lighting.
I recommend to disable lighting when you draw the text:
void frontscreen(void)
{
glDisable( GL_LIGHTING );
.....
}
But to enable lighting when you draw the scene:
void redraw(void)
{
glEnable( GL_LIGHTING );
.....
}

Draw a series of points with vertex array : nothing displayed

I'm trying for exercise to do the following: there is an array of points, expressed through couples of GLfloats.The user should click in a point in the window to make another points appear.When a point is added, the window shall be redrawn and the points shall display connected with a line.So the user shall be able to draw lines clicking on some locations of the windows.
In this code whenever there's a click I push a point in the vector, but the points is not added, so I just see the gray window (APPLE_GRAY defined in header) without the points.
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <stdio.h>
#include <stdlib.h>
#include "utility.h"
const int width=500;
const int height=500;
GLfloat* points;
size_t size=100;
int count=0;
void pushPoint(GLfloat x, GLfloat y)
{
count++;
if(count>size)
{
size+=100;
points=(GLfloat*)realloc(points,2*size*sizeof(GLfloat));
}
points[2*count-2]=x;
points[2*count-1]=y;
}
void init()
{
points=(GLfloat*)malloc(2*size*sizeof(GLfloat));
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glViewport(0, 0, 500, 500);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
}
void display()
{
glClearColor(APPLE_GRAY);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(RED);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, points);
glDrawElements(GL_LINE_LOOP,count,GL_FLOAT,points);
glFlush();
glDisableClientState(GL_VERTEX_ARRAY);
}
void mouse(int button, int state, int x, int y)
{
if(state)
{
pushPoint(x, y);
glutPostRedisplay();
}
}
void motion(int x, int y)
{
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width,height);
glutCreateWindow("Test");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
init();
glutMainLoop();
return 0;
}
Again, glutInitDisplayMode() needs to be called before glutCreateWindow().
GL_FLOAT is not a valid value for type in glDrawElements(). Also, points is not an index array.
Use glDrawArrays():
#include <GL/glut.h>
const int width=500;
const int height=500;
GLfloat* points;
size_t size=100;
int count=0;
void pushPoint(GLfloat x, GLfloat y)
{
count++;
if(count>size)
{
size+=100;
points=(GLfloat*)realloc(points,2*size*sizeof(GLfloat));
}
points[2*count-2]=x;
points[2*count-1]=y;
}
void init()
{
points=(GLfloat*)malloc(2*size*sizeof(GLfloat));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glEnable(GL_DEPTH_TEST);
}
void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3ub(255,0,0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, points);
glDrawArrays(GL_LINE_LOOP,0,count);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y)
{
if(state)
{
pushPoint(x, y);
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width,height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Test");
glutDisplayFunc(display);
glutMouseFunc(mouse);
init();
glutMainLoop();
return 0;
}

Glut Reshape Function Not Working

When I try to resize my glut window, the screen goes blank.
This is the code for the reshape callback funciton:
void Resize(int width, int height)
{
CurrentWidth = width;
CurrentHeight = height;
glViewport(0, 0, (GLsizei)CurrentWidth, (GLsizei)CurrentHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, CurrentWidth, CurrentHeight, 0, NearPlane, FarPlane);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
}
I am pretty new to the opengl world but from what I have learned this is supposed to work.
And this is all of the code put together:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <gl/glut.h>
#include "Utils.h"
int LEFT = 0;
int RIGHT = 0;
int UP = 0;
int DOWN = 0;
int CurrentWidth = 800,
CurrentHeight = 800,
WindowHandle = 0;
float NearPlane = 1.0f,
FarPlane = 100.0f;
float lightX,
lightY;
void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void Idle(void);
void Resize(int, int);
void KeyPressed(unsigned char, int, int);
void SpecialPressed(int, int, int);
void SpecialReleased(int, int, int);
void Update(void);
void Render(void);
void FillZBuffer(void);
void ClearAlpha(void);
void RenderLightAlpha(float);
void GeometryPass(void);
void Draw(void);
int main (int argc, char* argv[])
{
Initialize(argc, argv);
glutMainLoop();
exit(EXIT_SUCCESS);
}
void Initialize(int argc, char* argv[])
{
InitWindow(argc, argv);
fprintf(
stdout,
"INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION)
);
lightX = 300.0f;
lightY = 300.0f;
}
void InitWindow(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);
glutInitWindowSize (CurrentWidth, CurrentHeight);
glutInitWindowPosition (100, 100);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA);
WindowHandle = glutCreateWindow ("Shadows");
if(WindowHandle < 1) {
fprintf(
stderr,
"ERROR: Could not create a new rendering window.\n"
);
exit(EXIT_FAILURE);
}
glutDisplayFunc(Render);
glutReshapeFunc(Resize);
glutIdleFunc(Idle);
glutKeyboardFunc(KeyPressed);
glutSpecialFunc(SpecialPressed);
glutSpecialUpFunc(SpecialReleased);
}
void Update()
{
int speed = 10;
if (LEFT)
{
lightX -= speed;
}
if (RIGHT)
{
lightX += speed;
}
if (UP)
{
lightY -= speed;
}
if (DOWN)
{
lightY += speed;
}
}
void Draw()
{
float x = 200;
float y = 200;
float w = 100;
float h = 100;
float depth = 0.0f;
// floor
glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
depth = -10.0f;
glBegin(GL_QUADS);
{
glVertex3f(0, 0, depth);
glVertex3f((float)CurrentWidth, 0, depth);
glVertex3f((float)CurrentWidth, (float)CurrentHeight, depth);
glVertex3f(0, (float)CurrentHeight, depth);
}
glEnd();
// square
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
depth = -5.0;
glBegin(GL_QUADS);
{
glVertex3f( x, y, depth);
glVertex3f( x + w, y, depth);
glVertex3f(x + w, y + h, depth);
glVertex3f(x, y + h, depth);
}
glEnd();
}
void Render()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_CULL_FACE);
Update();
FillZBuffer();
ClearAlpha();
RenderLightAlpha(1.0f);
GeometryPass();
glutSwapBuffers();
glutPostRedisplay();
}
void FillZBuffer()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_TRUE);
Draw();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_FALSE);
}
void ClearAlpha()
{
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
glBegin (GL_QUADS);
{
glVertex2f(0, 0);
glVertex2f((float)CurrentWidth, 0);
glVertex2f((float)CurrentWidth, (float)CurrentHeight);
glVertex2f(0, (float)CurrentHeight);
}
glEnd ();
}
void RenderLightAlpha(float intensity)
{
float depth = -1.0f;
float radius = 300.0f;
float angle;
int numSubdivisions = 32;
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBegin(GL_TRIANGLE_FAN);
{
glColor4f(0.0f, 0.0f, 0.0f, intensity);
glVertex3f(lightX, lightY, depth);
// Set edge colour for rest of shape
glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
for (angle = 0; angle <= (float)PI * 2; angle += (((float)PI * 2) / numSubdivisions))
{
glVertex3f( radius*(float)cos(angle) + lightX, radius*(float)sin(angle) + lightY, depth);
}
glVertex3f(lightX + radius, lightY, depth);
}
glEnd();
}
void GeometryPass()
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendFunc(GL_DST_ALPHA, GL_ONE);
Draw();
}
void Idle()
{
glutPostRedisplay();
}
void Resize(int width, int height)
{
CurrentWidth = width;
CurrentHeight = height;
glViewport(0, 0, (GLsizei)CurrentWidth, (GLsizei)CurrentHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, CurrentWidth, CurrentHeight, 0, NearPlane, FarPlane);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
}
void KeyPressed(unsigned char key, int x, int y)
{
UNREFERENCED_PARAMETER(x);
UNREFERENCED_PARAMETER(y);
// escape key
if (key == 27)
{
exit(0);
}
}
void SpecialPressed(int keyCode, int x, int y)
{
UNREFERENCED_PARAMETER(x);
UNREFERENCED_PARAMETER(y);
if (keyCode == GLUT_KEY_LEFT)
{
LEFT = 1;
}
else if (keyCode == GLUT_KEY_RIGHT)
{
RIGHT = 1;
}
else if (keyCode == GLUT_KEY_UP)
{
UP = 1;
}
else if (keyCode == GLUT_KEY_DOWN)
{
DOWN = 1;
}
}
void SpecialReleased(int keyCode, int x, int y)
{
UNREFERENCED_PARAMETER(x);
UNREFERENCED_PARAMETER(y);
if (keyCode == GLUT_KEY_LEFT)
{
LEFT = 0;
}
else if (keyCode == GLUT_KEY_RIGHT)
{
RIGHT = 0;
}
else if (keyCode == GLUT_KEY_UP)
{
UP = 0;
}
else if (keyCode == GLUT_KEY_DOWN)
{
DOWN = 0;
}
}
Let me know if you need anymore information.
In the FillZBuffer function the depth mask is disabled at the end and only re-enabled at the beginning of the same function. So when Render is called again, the call to clear the depth buffer bit does nothing because the depth mask is disabled.
To fix this the depth mask must be re-enabled before the call to clear the depth buffer bit.
So this is what Render should look like.
void Render()
{
glDepthMask(GL_TRUE); // insert this line
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_CULL_FACE);
Update();
FillZBuffer();
ClearAlpha();
RenderLightAlpha(1.0f);
GeometryPass();
glutSwapBuffers();
glutPostRedisplay();
}

Problems resizing GLUT window

I have the following code and I can't resize the window. Any suggestions?
GLsizei width = 600;
GLsizei height = 600;
GLfloat AspectRatio;
int max = 500;
double xmax = 2.0;
double xmin = -2.0;
double ymax = 2.0;
double ymin = -2.0;
using namespace std;
void display()
{
gluOrtho2D(-2, width, -2, height);
AspectRatio=1.0*width/height;
mandelbrot();
glutSwapBuffers();
}
void reshize(GLsizei w, GLsizei h) {
GLsizei vsize;
if(w<h) vsize=w; else vsize=h;
glViewport(0,0,AspectRatio*vsize,vsize);
}
void mandelbrot()
{
...
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(600, 600);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("mandelbrot Set");
glutDisplayFunc(display);
glutReshapeFunc(reshize);
glutMainLoop();
return 0;
}
EDITED
I changed to following and now it's OK.
void display()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-2, width, -2, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT );
mandelbrot();
glutSwapBuffers();
}
void reshize(GLsizei w, GLsizei h) {
width=w; height=h;
glViewport(0,0,width,height);
glutPostRedisplay();
}

Resources