Related
I'm trying to move these tow auto-rotating polygons to the Right-Left , Up-Down and Front-Back using these keys :
for the pyramid its the keys ('a','w','s','d','+','-')
for the cube its the keys ('←','↑','→','↓','PAGE UP','PAGE DOWN')
the polygons do actually move but they are moving in a weird way not as I wanted them to be moved especially when I try to move them Up-Down and Front-Back
I want to know why they moves like and what should I change to make them moves normal .
this is the code :
#include <GL\glew.h>
#include <SOIL.h>
#include <GL/glut.h>
float pyramid_x = 0, pyramid_y = 0, pyramid_z = 0;
float cube_x = 0, cube_y = 0, cube_z = 0;
float pyramid_angle = 0.0;
float cube_angle = 0.0;
int refresh = 10;//ms
float degree = 0;
void cube_right(void)
{
glLoadIdentity();
cube_x += 0.1;
}
void cube_left(void)
{
glLoadIdentity();
cube_x -= 0.1;
}
void cube_up(void)
{
glLoadIdentity();
cube_y += 0.1;
}
void cube_down(void)
{
glLoadIdentity();
cube_y -= 0.1;
}
void cube_front(void)
{
glLoadIdentity();
cube_z -= 0.1;
}
void cube_back(void)
{
glLoadIdentity();
cube_z += 0.1;
}
void pyramid_right(void)
{
glLoadIdentity();
pyramid_x += 0.1;
}
void pyramid_left(void)
{
glLoadIdentity();
pyramid_x -= 0.1;
}
void pyramid_up(void)
{
glLoadIdentity();
pyramid_y += 0.1;
}
void pyramid_down(void)
{
glLoadIdentity();
pyramid_y -= 0.1;
}
void pyramid_front(void)
{
glLoadIdentity();
pyramid_z -= 0.1;
}
void pyramid_back(void)
{
glLoadIdentity();
pyramid_z += 0.1;
}
void keyboard(int buttons, int x, int y)
{
switch (buttons)
{
case GLUT_KEY_LEFT:cube_left(); break;
case GLUT_KEY_RIGHT:cube_right(); break;
case GLUT_KEY_UP:cube_up(); break;
case GLUT_KEY_DOWN:cube_down(); break;
case GLUT_KEY_PAGE_UP:cube_front(); break;
case GLUT_KEY_PAGE_DOWN:cube_back(); break;
}
glutPostRedisplay();
}
void keyboard(unsigned char buttons, int x, int y)
{
switch (buttons)
{
case 'w':pyramid_front(); break;
case'a':pyramid_left(); break;
case's':pyramid_down(); break;
case'd':pyramid_right(); break;
case '+':pyramid_front(); break;
case'-':pyramid_back(); break;
}
glutPostRedisplay();
}
void settings()
{
glClearColor(1, 1, 1, 0);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void drawing_function()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //reset
glTranslatef(2.0f, 0.0f, -7.0f);
glRotatef(pyramid_angle, 1.0f, 0.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0);
glTranslatef(pyramid_x, pyramid_y, pyramid_z);
glBegin(GL_TRIANGLES);
// front
glTexCoord3f(1, 0, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(1.0f, -1.0f, 1.0f);
// right
glTexCoord3f(0, 0, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(1.0f, -1.0f, -1.0f);
// back
glTexCoord3f(0, 1, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(-1.0f, -1.0f, -1.0f);
// left
glTexCoord3f(1, 1, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
glLoadIdentity();//(Reset model-view matrix)
glTranslatef(-2.0f, 0.0f, -7.0f);
glRotatef(cube_angle, 1.0f, 0.0f, 0.0f);
glTranslatef(cube_x, cube_y, cube_z);
glBegin(GL_QUADS); //cube
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glColor3f(1.0f, 0.5f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd();
glutSwapBuffers();
pyramid_angle += 1.0f;
cube_angle -= 0.2f;
}
void timer(int deger)
{
glutPostRedisplay();
glutTimerFunc(refresh, timer, 0);
}
void view_setting(GLsizei x, GLsizei y)
{
if (y == 0) y = 1;
GLfloat aspect = (GLfloat)x / (GLfloat)y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0f, aspect, 1.0f, 20.0f);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowPosition(50, 50);
glutInitWindowSize(800, 600);
glutCreateWindow("3d");
glutDisplayFunc(drawing_function);
glutReshapeFunc(view_setting);
glutSpecialFunc(keyboard);
glutKeyboardFunc(keyboard);
settings();
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
Change the order of the transformations. Do the rotation then the translation:
glTranslatef(2.0f, 0.0f, -7.0f);
glTranslatef(pyramid_x, pyramid_y, pyramid_z);
glRotatef(pyramid_angle, 1.0f, 0.0f, 0.0f);
glTranslatef(-2.0f, 0.0f, -7.0f);
glTranslatef(cube_x, cube_y, cube_z);
glRotatef(cube_angle, 1.0f, 0.0f, 0.0f);
Matrix multiplication is not Commutative. Operations like glRotate and glTranslate setup a new matrix and multiply the current matrix by the new matrix. Therefore, the transformation that needs to be done first must be the last in code.
Further more there is a mistake in keyboard. When w is pressed the the pyramid has to move up rather than to move to the front:
case 'w':pyramid_front(); break;
case 'w':pyramid_up(); break;
I want to make my shapes to keep rotating by time while I can move them (Left-Right , Down-Up , Front-Back) using keyboard I added a function called timer() that should change the angles of the cube and pyramid by time.
The problem is the code keeps breaking at glutPostOverlayRedisplay(); function and it says :
Exception thrown at 0x10004813 (glut32.dll) in Opengl.exe: 0xC0000005:
Access violation reading location 0x00000020.
how can I fix this problem and why its happening ?
this is the code :
#include <GL/glut.h>
int object = 0;
float xLeftRight[]{ 0, 0 };
float yDownUp[]{ 0, 0 };
float zFrontBack[]{ 0, 0 };
float PyramidAngle = 0.0;
float CupeAngle = 0.0;
int t_refresh = 20;//ms
float degree = 0;
float xscale = 1, yscale = 1, zscale = 1;
void Keyboard(int buttons, int x, int y)
{
switch (buttons)
{
case GLUT_KEY_F1: object = 0; break;
case GLUT_KEY_F2: object = 1; break;
case GLUT_KEY_LEFT: xLeftRight[object] -= 0.1; break;
case GLUT_KEY_RIGHT: xLeftRight[object] += 0.1; break;
case GLUT_KEY_DOWN: yDownUp[object] -= 0.1; break;
case GLUT_KEY_UP: yDownUp[object] += 0.1; break;
case GLUT_KEY_PAGE_UP: zFrontBack[object] -= 0.1; break;
case GLUT_KEY_PAGE_DOWN: zFrontBack[object] += 0.1; break;
}
glutPostRedisplay();
}
void Settings()
{
glClearColor(1, 1, 1, 0);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void DrawingFunction()//painting
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //reset
glTranslatef(1.5f, 0.0f, -6.0f); // rotate left and back by time
glRotatef(PyramidAngle, 1.0f, 1.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0);
glScalef(xscale, yscale, zscale);
glTranslatef(xLeftRight[0], yDownUp[0], zFrontBack[0]); //move the pyramid (if object = 0)
glBegin(GL_TRIANGLES);
// front
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(1.0f, -1.0f, 1.0f);
// right
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(1.0f, -1.0f, -1.0f);
// back
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(-1.0f, -1.0f, -1.0f);
// left
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
glPopMatrix();
glPushMatrix();
glLoadIdentity();//(Reset model-view matrix)
glTranslatef(-2.0f, 0.0f, -7.0f); // rotate the cube right and back by time
glRotatef(CupeAngle, 1.0f, 0.0f, 0.0f);
glTranslatef(xLeftRight[1], yDownUp[1], zFrontBack[1]); //move the cube (if object = 1)
glBegin(GL_QUADS); //cube
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glColor3f(1.0f, 0.5f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd();
glutSwapBuffers();
PyramidAngle += 1.0f; //changing the angle
CupeAngle -= 0.2f; //changing the angle
glPopMatrix();
}
void timer(int value)
{
glutPostOverlayRedisplay();
glutTimerFunc(t_refresh, timer, 0);
}
void ViewSetting(int x, int y)
{
int aspect = x / y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 0.1, 20);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowPosition(50, 50);
glutInitWindowSize(800, 600);
glutCreateWindow("3d shapes");
glutDisplayFunc(DrawingFunction);
glutReshapeFunc(ViewSetting);
glutSpecialFunc(Keyboard);
Settings();
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
glutPostOverlayRedisplay marks the overlay of the current window as needing to be redisplayed (See Overlay Management).
You have to use glutPostRedisplay:
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(t_refresh, timer, 0);
}
I was working with OpenGL C++ drawing shapes, specifically cubes. In my current project, I managed to draw a cube correctly, but only the side of the cube that gets drawn last doesn't go transparent when the camera is directly on it. The first two sides of the cube go completely transparent when viewed head-on. Is there a way to fix this? Here is the picture. As you can see, the first two sides don't get displayed. Here is my code:
Main.cpp:
#include "Render.h"
#include <stdlib.h>
int screenHeight = 500;
int screenWidth = 500;
int screenFPS = 60;
void MainLoop(int val);
int main(int argc, char* args[])
{
glutInit(&argc, args);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(screenWidth, screenHeight);
glutInitWindowPosition(350, 80);
glutCreateWindow("Cube");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glOrtho(0.0f, screenWidth, screenHeight, 0.0f, 0.0f, 1.0f);
gluPerspective(40, 1, 0.5, 20);
glutDisplayFunc(Render);
glViewport(0, 0, screenWidth, screenHeight);
glutKeyboardFunc(HandleKeys);
glutIdleFunc(Animation);
glutTimerFunc(1000 / screenFPS, MainLoop, 0);
glutMainLoop();
return 0;
}
void MainLoop(int val)
{
Render();
glutTimerFunc( 1000 / screenFPS, MainLoop, val );
}
Render.cpp:
#include "Render.h"
#include <iostream>
#include <stdlib.h>
#include <windows.h>
GLfloat xRot, yRot, zRot;
void Render()
{
std::cout << xRot << " " << yRot << " " << zRot << "\n";
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,0.0,-10.5);
glRotatef(yRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glRotatef(zRot, 0.0, 0.0, 1.0);
glBegin(GL_QUADS);
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glColor4f(1.0f, 0.5f, 0.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd();
glutSwapBuffers();
}
void Animation()
{
yRot += 0.03;
xRot += 0.08;
Render();
}
void HandleKeys(unsigned char key, int x, int y)
{
if(key == 27)
exit(0);
else if(key == 'w')
yRot += 0.55;
else if(key == 'a')
xRot -= 0.55;
else if(key == 's')
yRot -= 0.55;
else if(key == 'd')
xRot += 0.55;
}
Render.h
#include "GLLib.h"
extern int screenHeight;
extern int screenWidth;
extern int screenFPS;
void Render();
void Animation();
void HandleKeys(unsigned char key, int x, int y);
And finally my librarys, GLLib.h:
#ifndef GLLIB_H
#define GLLIB_H
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif
Chances are that all sides are drawn just fine. The problem is that you don't have a depth buffer. Therefore, everything that is drawn replaces what was drawn previously, no matter if it's in front or behind the previously drawn geometry.
To use a depth buffer, you have to request it during initialization:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
and enable depth testing before you start rendering:
glEnable(GL_DEPTH_TEST);
Then, at the start of rendering each frame, you need to clear the depth buffer in addition to the color buffer:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
This will make sure that the front most faces are visible, and the faces behind them are hidden, independent of the drawing order.
im creating a simple textured cube but im have a problem with the my keyboard functions i do not seem to interact,i want the cube to move in the x and y direction but its not moving,i used this function
void specialKeys( int key, int x, int y ) {
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
glutPostRedisplay();
}
and in my main function i used this code
glutSpecialFunc(specialKeys);
this is my whole code
#include <stdlib.h>
#include <GL/glut.h>
#include "RgbImage.h"
void specialKeys();
double rotate_y=0;
double rotate_x=0;
GLfloat xRotated, yRotated, zRotated;
GLuint texture[1]; // Storage For One Texture ( NEW )
void loadTextureFromFile(char *filename)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
RgbImage theTexMap( filename );
glGenTextures(1, &texture[0]); // Create The Texture
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Typical Texture Generation Using Data From The Bitmap
glTexImage2D(GL_TEXTURE_2D, 0, 3, theTexMap.GetNumCols(), theTexMap.GetNumRows(), 0, GL_RGB, GL_UNSIGNED_BYTE, theTexMap.ImageData() );
}
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glLoadIdentity();
glTranslatef(0.0,0.0,-5);
glRotatef(yRotated, 0, 1, 0);
glRotatef(zRotated, 0, 0, 1);
glBegin(GL_QUADS);
// Front Face
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
void resizeWindow(int x, int y)
{
if (y == 0 || x == 0) return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,x,y);
}
void specialKeys( int key, int x, int y ) {
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
glutPostRedisplay();
}
char* filename = "./salt_on_spoon.bmp";
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(240, 240);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
loadTextureFromFile( filename );
glutDisplayFunc(drawScene);
glutSpecialFunc(specialKeys);
glutReshapeFunc(resizeWindow);
glutMainLoop();
return 0;
}
Your callback is modifying rotate_x and rotate_y, but you're using different variables for the rotations:
glRotatef(yRotated, 0, 1, 0);
glRotatef(zRotated, 0, 0, 1);
Try this:
#include <GL/glut.h>
GLfloat pos_x = 0, pos_y = 0;
void specialKeys( int key, int x, int y )
{
const float step = 0.01;
if (key == GLUT_KEY_RIGHT)
pos_x += step;
else if (key == GLUT_KEY_LEFT)
pos_x -= step;
else if (key == GLUT_KEY_UP)
pos_y += step;
else if (key == GLUT_KEY_DOWN)
pos_y -= step;
glutPostRedisplay();
}
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double x = glutGet( GLUT_WINDOW_WIDTH );
double y = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(40.0,x/y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-5);
glTranslatef( pos_x, pos_y, 0 );
glBegin(GL_QUADS);
// Front Face
// Back Face
glColor3ub(255,0,0);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
// Bottom Face
glColor3ub(0,255,0);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glColor3ub(0,0,255);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glColor3ub(255,255,255);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(240, 240);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glutDisplayFunc(drawScene);
glutSpecialFunc(specialKeys);
glutMainLoop();
return 0;
}
So I have 2 cubes in a display list and I want one of them be pickable so I can maybe change his color or something like that.
When I click on a cube then the screen turns black and nothing happens, the console gives me output of the closest hit but the screen turns black and doesn't show anything.
Here is my cpp file:
#include "glwidget.h"
#include <QDomDocument>
#include <QDebug>
#include <QFile>
#include <math.h>
#include <QString>
#include <stdlib.h>
GLWidget::GLWidget(QWidget *parent):QGLWidget(parent)
{
camPosx = 0.0, camPosy = 0.0, camPosz = 1.0;
camViewx = 0.0, camViewy = 0.0, camViewz = 0.0;
camUpx = 0.0, camUpy = 1.0, camUpz = 0.0;
camAngle = 0.0;
camViewz = -cos(camAngle);
camViewx = sin(camAngle);
mode = 1;
timer = new QTimer();
connect( timer, SIGNAL(timeout()), this, SLOT(updateGL()) );
}
void GLWidget::initializeGL() {
loadGLTextures();
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glEnable(GL_LIGHT0); // Quick And Dirty Lighting (Assumes Light0 Is Set Up)
glEnable(GL_LIGHTING); // Enable Lighting
glEnable(GL_COLOR_MATERIAL); // Enable Material Coloring
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Perspective Calculations
buildLists(2); // Creating displaylist #
glLoadIdentity();
timer->start(50);
}
void GLWidget::resizeGL(int width, int height) {
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
//change the next line order to have a different perspective
aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(45.0f, aspect_ratio, 0.1 , 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void GLWidget::paintGL() {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camPosx + camViewx,camViewy,camPosz + camViewz,
camUpx, camUpy, camUpz );
if (mode == 2) {
startPicking();
}
glColor3f(1.0f,0.0f,0.0f);
glCallList(displayList[0]);
glTranslatef(5.0,0.0,0.0);
glColor3f(0.0f,1.0f,1.0f);
glCallList(displayList[0]);
if (mode == 2)
stopPicking();
// glEnable( GL_LIGHTING );
// glEnable( GL_LIGHT0 );
// glScalef(10.0,10.0,10.0);
// glBindTexture(GL_TEXTURE_2D, texture[0]);
// glBegin(GL_QUADS);
// // Front Face
// glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// // Back Face
// glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// // Top Face
// glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// // Bottom Face
// glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// // Right face
// glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// // Left Face
// glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
// glEnd();
// // XML
// QDomDocument doc( "AdBookML" );
// QDomNode n;
// QDomElement e;
// QFile file( "test2.xml" );
// QString s;
// QStringList sl;
//// if( !file.open(QIODevice::ReadOnly))
//// qDebug("probleem bij het openen");
// if( !doc.setContent( &file ) )
// {
// file.close();
// }
// file.close();
// QDomElement root = doc.documentElement();
// if( root.tagName() != "playlist" )
// // qDebug("root is different");
// //qDebug( root.tagName() );
// // doorheen u boom lopen
// n = root;
// float f1, f2, f3;
// glDisable( GL_LIGHTING );
// glBegin(GL_TRIANGLES);
// for(int i = 0; i< n.childNodes().length(); i++) // voor alle triangles
// {
// if(n.childNodes().at(i).toElement().tagName() == "triangle")
// {
// for(int j =0; j < 4; j++) // voor alle punten
// {
// e = n.childNodes().at(i).childNodes().at(j).toElement(); // e is een punt
// //qDebug(e.tagName());
// s = e.text();
// sl = s.split(" "); // opsplitsen naar het x, y , z coordinaat;
// f1 = sl.at(0).toFloat();
// f2 = sl.at(1).toFloat();
// f3 = sl.at(2).toFloat();
// if( j > 0)
// glVertex3f(f1, f2, f3); // de vertex tekenen
// if(j == 0)
// glColor3f(f1,f2,f3);
// }
// }
// }
// glEnd();
// glEnable(GL_LIGHTING);
// restore current matrix
glMatrixMode( GL_MODELVIEW );
glPopMatrix( );
}
void GLWidget::loadGLTextures()
{
QImage t;
QImage b;
if ( !b.load( "images/redbrick.png" ) )
{
qDebug("Didn't found the image.");
b = QImage( 16, 16, QImage::Format_RGB32 );
b.fill( 1 );
}
t = QGLWidget::convertToGLFormat( b );
glGenTextures( 1, &texture[0] );
glBindTexture( GL_TEXTURE_2D, texture[0] );
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
//Functie die display lists kan aanmaken, het aantal ( is het aantal displaylists )
GLvoid GLWidget::buildLists(int aantal)
{
displayList = new GLuint[aantal];
for(int i = 0; i < aantal; i++)
{
displayList[i]=glGenLists(aantal); // Maak x Aantal displaylists
glNewList(displayList[i],GL_COMPILE); //start met de eerste display list te compile
//Hieronder moet er xml worden ingeladen
glBegin(GL_QUADS);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glEndList();
}
}
//functie die zorgt dat we renderen in selectiemode
void GLWidget::renderInSelectionMode() {
glInitNames(); //Creates empty stack
glPushName(1); //Push a name on the stack
//draw something
glColor3f(1.0f,0.0f,0.0f);
glCallList(displayList[0]);
glPopName(); //pop a name from the stack
glPushName(2); //Push a name on the stack
//draw something
glTranslatef(5.0,0.0,0.0);
glColor3f(0.0f,1.0f,1.0f);
glCallList(displayList[0]);
glPopName(); //Pops a name from the stack
}
void GLWidget::startPicking() {
GLint viewport[4];
glSelectBuffer(BUFSIZE,selectBuf);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT,viewport);
gluPickMatrix(cursorX,viewport[3]-cursorY,5,5,viewport);
gluPerspective(45,aspect_ratio,0.1,1000);
glMatrixMode(GL_MODELVIEW);
glInitNames();
}
void GLWidget::stopPicking() {
int hits;
// restoring the original projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
// returning to normal rendering mode
hits = glRenderMode(GL_RENDER);
// if there are hits process them
if (hits != 0)
processHits(hits,selectBuf);
}
void GLWidget::processHits (GLint hits, GLuint buffer[])
{
unsigned int i, j;
GLuint names, *ptr, minZ,*ptrNames, numberOfNames;
printf ("hits = %d\n", hits);
ptr = (GLuint *) buffer;
minZ = 0xffffffff;
for (i = 0; i < hits; i++) {
names = *ptr;
ptr++;
if (*ptr < minZ) {
numberOfNames = names;
minZ = *ptr;
ptrNames = ptr+2;
}
ptr += names+2;
}
printf ("The closest hit names are ");
ptr = ptrNames;
for (j = 0; j < numberOfNames; j++,ptr++) {
printf ("%d ", *ptr);
}
printf ("\n");
}
void GLWidget::mousePressEvent(QMouseEvent * e)
{
if(e->button() == Qt::LeftButton)
{
qDebug("mouse");
qDebug("%d",QCursor::pos().x());
this->cursorX = QCursor::pos().x();
this->cursorY = QCursor::pos().y();
this->mode = 2;
}
}
void GLWidget::keyPressEvent( QKeyEvent * e ) {
double fraction = 0.1f;
if(e->key() == Qt::Key_Up)
{
camPosz += camViewz * fraction;
camPosx += camViewx * fraction ;
}
if(e->key() == Qt::Key_Down)
{
camPosz -= camViewz * fraction;
camPosx -= camViewx * fraction ;
}
if(e->key() == Qt::Key_Left)
{
camAngle -= 0.05f;
camViewz = -cos(camAngle);
camViewx = sin(camAngle);
}
if(e->key() == Qt::Key_Right)
{
qDebug("cam angle is %f", camAngle);
camAngle +=0.05f;
camViewz = -cos(camAngle);
camViewx = sin(camAngle);
}
}
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QtOpenGL/QGLWidget>
#include <gl/GLU.h>
#include <QImage>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QTimer>
#define BUFSIZE 512
class GLWidget: public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget *parent = NULL);
private:
double camPosx,camPosy,camPosz;
double camUpx,camUpy,camUpz;
double camViewx,camViewy,camViewz;
double camAngle;
protected:
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void keyPressEvent(QKeyEvent * e);
void mousePressEvent(QMouseEvent * e);
QTimer* timer;
void loadGLTextures();
GLuint texture[1];
GLuint * displayList;
void renderInSelectionMode();
GLvoid buildLists(int aantal);
void startPicking();
void stopPicking();
void processHits (GLint hits, GLuint buffer[]);
GLuint selectBuf[BUFSIZE];
GLdouble aspect_ratio;
int cursorY;
int cursorX;
int mode;
};
#endif // GLWIDGET_H
this is the normal view without clicking once
http://imageshack.us/photo/my-images/233/31536776.png/
then when clicked it keeps getting in startpicking and stop picking and gives a black screen
http://imageshack.us/photo/my-images/13/14180995.png/
and then after closing the window so it stops running it gives me this output http://imageshack.us/photo/my-images/861/13486229.png/
Could be wrong, but it looks like you aren't resetting your mode-variable back to 1 after the first mouseclick anywhere, so the start- & stopPicking-methods are called on each frame from the first click onwards. If that's not the case, then you probably have some problem with gl-states/matrices not all being reset correctly after the picking.