I'm trying to recognize a drawn object on a mousPressEvent in OpenGL in Qt with picking.
I did some research but wasn't able to find the problem.
Clearly it recognizes something (because the return value of glRenderMode(GL_RENDER) is often an integer > 0), but not necessarily when I click on an object.
I think gluPerspective is the problem right here, but i just don't know how to resolve it.
mousePressEvent:
void WorldView::mousePressEvent(QMouseEvent *e)
{
GLuint buff[256];
GLint hits;
GLint view[4];
//Buffer to store selection data
glSelectBuffer(256, buff);
//Viewport information
glGetIntegerv(GL_VIEWPORT, view);
//Switch to select mode
glRenderMode(GL_SELECT);
//Clear the name stack!
glInitNames();
//Restric viewing volume
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//Restrict draw area
gluPickMatrix(e->x(), e->y(), 1.0, 1.0, view);
gluPerspective(40.0f, (GLfloat)view[2]/(GLfloat)view[3], 1.0, 100.0);
//Draw the objects onto the screen
glMatrixMode(GL_MODELVIEW);
//Draw only the names in the stack
paintGL();
//Back into projection mode to push the matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
hits = glRenderMode(GL_RENDER);//number of recognized objects
printf("\n%d\n",hits);
//Back to modelview mode
glMatrixMode(GL_MODELVIEW);
}
Draw function:
void WorldView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
//Draw objects we want to pick
glPushName(0);
glBegin(GL_TRIANGLES);
glVertex3d(1,1,1);
glVertex3d(2,3,2);
glVertex3d(5,2,2);
glEnd();
glPopName();
glPushName(1);
glBegin(GL_TRIANGLES);
glVertex3d(7,-5,1);
glVertex3d(10,3,2);
glVertex3d(10,2,2);
glEnd();
glPopName();
glPushName(2);
glBegin(GL_TRIANGLES);
glVertex3d(1,-5,7);
glVertex3d(2,3,9);
glVertex3d(5,2,9);
glEnd();
glPopName();
}
EDIT1: Maybe completing the code could help?
Initializer:
void WorldView::initializeGL ()
{
this->dayOfYear = 0;
this->hourOfDay = 0;
// Initialize QGLWidget (parent)
QGLWidget::initializeGL();
glShadeModel(GL_SMOOTH);
// Black canvas
glClearColor(0.0f,0.0f,0.0f,0.0f);
// Place light
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable(GL_DEPTH_TEST);
GLfloat light0_position [] = {0.1f, 0.1f, 0.1f, 0.1f};
GLfloat light_diffuse []={ 1.0, 1.0, 1.0, 1.0 };
glLightfv ( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
}
resizer:
void WorldView::resizeGL ( int width, int height )
{
if ((width<=0) || (height<=0))
return;
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
//change the next line order to have a different perspective
GLdouble aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(40.0f, aspect_ratio, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Use bullet raycast and not gl_Select which is way too slow and unwieldy. This will also make you get away from calling paintGL manually and other glCalls...in qt mousepressevent. Dont do this!
Related
I have create a custom qt designer widget which inherit from QOpenGLWidget. Everything is fine except I cannot get the widget background transparent.
Is there a way to fix this issue?
void MyOpenGl::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0,0,0,0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
}
void MyOpenGl::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45, (float)w/h, 0.01, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0,0,5,0,0,0,0,1,0);
}
void MyOpenGl::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f( 0.5, -0.5, 0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f( 0.0, 0.5, 0);
glEnd();
}
Do not call glClear() in your MyOpenGL::paintGL() function with GL_COLOR_BUFFER_BIT, that will make to rewrite the entire color buffer to the color set by glClearColor(). You can even omit it completely.
I am trying to learn how to use a spot light in OpenGL. I wish to shine a spot (torch) light from a point marked (lighpos), and shown as grey dot, onto the side of a GLUT teapot centered at (possph) in 3D space. I have attached an example where I have tried to do this but I cannot get the light to focus on the teapot. I am expecting a almost touch light focus based on the parameters I have tried to use.
Could someone point out what I have missed / mistake I have made.
Thanks
Stuart
#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>
GLfloat lighpos[] = { -300., 200., 250., 1.0 }; // Location of light
GLfloat possph[] = { -50., 350., 150. }; // Position of teapot
GLfloat ligdir[] = { 250., 150., -100. }; // Direction from light to teapot
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
glLightfv(GL_LIGHT0, GL_POSITION, lighpos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, ligdir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 10.0);
GLfloat ambientLight0[] = { 0.25, 0.25, 0.25, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight0);
GLfloat diffuseLight0[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight0);
GLfloat specularLight0[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight0);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 128.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void drawAxis() {
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0); glVertex3f(-500., 0.0, 0.0); glVertex3f(500., 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, -500., 0.0); glVertex3f(0.0, 500., 0.0);
glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.0, -500.); glVertex3f(0.0, 0.0, 500.);
glEnd();
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
drawAxis();
glPushMatrix();
glPointSize(10);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POINTS);
glVertex3d(lighpos[0], lighpos[1], lighpos[2]);
glEnd();
glPopMatrix();
glColor3f(1., 0., 0.);
glPushMatrix();
glTranslated(possph[0], possph[1], possph[2]);
glutSolidTeapot(100.);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 4, 3000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1500.0, 1500.0, 1500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(0.0, 0.0);
glutInitWindowSize(800, 800);
glutCreateWindow("spotlight");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Fixed function pipeline illumination, which is what you are using in your code, performs lighting calculations only at the vertices. If your spotlight illuminates only a few or a single vertex you'll not get a pleasing spotlight effect. One possible solution would be to highly refine your models' meshes. The better, much more efficient and elegant solution is to drop using the fixed function pipeline and implement a illumination fragment shader, so that lighting is calculated for each pixel.
I'm trying to show a texture in Qt with opengl but it just doesn't show the texture when i run.
I did some research and found out I needed to make the height and width of the texture as a power of 2. my texture is now (1024x1024).
I also added a lot of glTexParameterf's that could resolve my problem, but still no luck.
void WorldView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
//load texture
QImage img;
if(!img.load(":/files/FloorsCheckerboardSmall.bmp"))
printf("could not open image");
//try showing texture
glEnable( GL_LIGHTING );
glEnable( GL_COLOR_MATERIAL );
glEnable(GL_TEXTURE_2D);
unsigned int m_textureID;
glGenTextures(1, &m_textureID);
glBindTexture(GL_TEXTURE_2D,m_textureID);
glTexImage2D(GL_TEXTURE_2D,0,(GLint)img.depth(),(GLsizei)img.width(),(GLsizei)img.height(),0,GL_RGB,GL_UNSIGNED_BYTE,img.bits());
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glColor3d(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glTexCoord2d(0.0,5.0);
glVertex2d(0.0,3.0);
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(5.0,0.0);
glVertex2d(3.0,0.0);
glTexCoord2d(5.0,5.0);
glVertex2d(3.0,3.0);
glEnd();
}
EDIT1: Could it be my texture is too big?
EDIT2: glBindTexture(GL_TEXTURE_2D,m_textureID); placed before glBindTexture instead of before glColor3d
SOLVED: My img.depth() returned an invalid internalFormat value. I replaced this GLint with the valid interalFormat value GL_RGBA. I also changed the format from GL_RGB to GL_RGBA (see genpfaults answer)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,(GLsizei)img.width(),(GLsizei)img.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,img.bits());
You have to call
glBindTexture(GL_TEXTURE_2D,m_textureID);
before calling glTexImage2D(...). Or OpenGL won't know where the data you send it belongs.
vvvvvvvvvvvvvvvvvv
glTexImage2D(GL_TEXTURE_2D,0,(GLint)img.depth(),(GLsizei)img.width(),(GLsizei)img.height(),0,GL_RGB,GL_UNSIGNED_BYTE,img.bits());
img.depth() returns 32
Then you need to pass in a valid internalFormat value, not img.depth(). Try GL_RGBA.
You should also set format to GL_RGBA since img.bits() is actually four-component.
I am working on a background texture. What I want to do is that I want to set a background image. For that in my code I used switch to ortho, draw a square full of window size, texture it. Then switch back to 3d and draw 3d images. It draw the background texture and snowman but they all disappear in a sec. I have no idea where the error code is. gotta have something to do with pushing and popping the matrix I think. Below is the code of my InitGl, draw() and drawsnowman(), main and reshape(). I think the problem is in draw() function during the swithc between 3D to 2d. Advice?
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
glutKeyboardFunc(key);
if( !initGL() ) { // NEW (16)
printf( "Unable to initialize graphics library!\n" );
return 1;
}
glutDisplayFunc (display);
// glutIdleFunc (display);
glutIdleFunc(idle);
glutReshapeFunc (reshape);
//Load our texture
texture = LoadTexture( "texture.bmp", 256, 256 );
glutMainLoop ();
//Free our texture
FreeTexture( texture );
return 0;
}
void drawSnowMan(void)
{
GLUquadricObj *pObj;
//glDisable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// save the world matrix
glPushMatrix();
glTranslatef(xpos, -0.5, -5.0);
glRotated(rotX,1,0,0); // ******** NEW (11)
glRotated(rotY,0,1,0);
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
//glRotated(rotZ,0,0,1);
glPushMatrix();
//setting up light effect for base, mid and head spheres. all red!
ambient[0] = 1.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glTranslatef(0.0 ,0.75f, 0.0f);
//bottom sphere. dont need to gltranslate again because it will use the previous gltranslate
//which is declared outside
glutSolidSphere(0.70f,20,20);
//mid sphere
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.45f,20,20);
//top sphere
glTranslatef(0.0f, 0.6f, 0.0f);
glutSolidSphere(0.30f,20,20);
//eyes
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
//drawing hat
glPushMatrix();
//black color. move it 1.85 in y position because thats where the head is
//rotate the cylinder and draw cylinder
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(0.0f, 1.85f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.17f, 0.17f, 0.4f, 26, 13);
//drawing brim. disable cull_face. draw disk, so front part. disabl
glDisable(GL_CULL_FACE);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glEnable(GL_CULL_FACE);
glTranslatef(0.0f, 0.0f, 0.40f);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glPopMatrix();
glPushMatrix();
glPushMatrix();
glColor3f(1.0,1.0,1.0);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(90.0,0.0, 0.0,-5.0);
glScalef (0.01, 0.2, 0.06); /* modeling transformation */
//glutSolidCone(0.1, 0.1, 10.0, 14.0);
glutSolidCube(1.5);
glPopMatrix();
glPushMatrix();
glTranslatef(2.0f, 0.8f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.04f, 0.04f, 0.2f, 26, 13);
glPopMatrix();
//blade
glPushMatrix();
ambient[0] = 0.0; ambient[1] = 1.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.03f, 0.03f, 1.1f, 26, 13);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
glPopMatrix();
//big push matrix for eyes, and nose
glPushMatrix();
//eyes color = black light. set defuse all 0, ambient = black. turns the eyes black
/*ambient[0] = 0.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 0.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);*/
glColor3f(0.0, 0.0, 0.0);
//left eye
glPushMatrix();
glTranslatef(-0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//right eye
glPushMatrix();
glTranslatef(0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//drawing nose
glPushMatrix();
glTranslatef(0.0, 1.6, 0.25 );
glutSolidCone(0.08f,0.5f,10,2);
glPopMatrix();
glPopMatrix(); // end big push matrix for eyes and nose
glPopMatrix();
} // end of drawsnowman()
void display (void) {
glClearColor(0.25f, 0.25f, 0.50f, 1.0f ); // blueish color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glLoadIdentity();
// MODEL VIEW is set up in IniitGL
//so save it
glPushMatrix();
//switch to projection matrix
//swithc to ortho.
//draw texture
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glPopMatrix();// pop the 3d model view
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
// You can ignore this. just a different of way drawing texture and still does not work
/* glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glDepthMask( false );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
/*glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, 800 / 600, 1.0, 100.0);;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0.0, 0.0, 0.0, // Where would the camera be?
0.0, 0.0,-1.0, // Where would it be looking?
0.0, 1.0, 0.0); // What would be the "up" vector?fa*/
/* glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//gluPerspective (45, SCREEN_WIDTH / SCREEN_HEIGHT, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();*/
drawSnowMan(); // draw snow man
glutSwapBuffers();
angle ++;
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
bool initGL (void) {
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Switch to the "camera" mode
glMatrixMode(GL_PROJECTION); // Camera
glLoadIdentity();
// Change the camera to a 3D view
glFrustum( -1 * (float) SCREEN_WIDTH / SCREEN_HEIGHT,
(float) SCREEN_WIDTH / SCREEN_HEIGHT,
-1.0,
1.0,
1.5,
1000.0);
glClearColor(0.25f, 0.25f, 0.50f, 1.0f );
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // NEW (5)
glEnable(GL_LINE_SMOOTH); // NEW (6)
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // NEW (7)
glEnable(GL_POLYGON_SMOOTH); // NEW (8)
// this is a specular light
GLfloat mat_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 }; // Color of a "shiny material
GLfloat mat_shininess[] = { 50.0 }; // How shiny is it?
// GLfloat mat_ambient_and_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; // Infinitely far away. Direction light
GLfloat light_position1[] = {2.0,1.5,0.0,1.0}; // saber light
// How to calculate the surface normal for pixels
glShadeModel(GL_SMOOTH); // Try this as well GL_FLAT
// Setup up some material reflective properties
// glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
// glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_and_diffuse);
//glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_ambient_and_diffuse);
// Finally actually make the light
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
//Check for error
GLenum error = glGetError(); // NEW (9)
if( error != GL_NO_ERROR ) {
printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
return false;
}
return true;
}
void idle(void) {
glutPostRedisplay();
}
Reoccuring newbie misconception: OpenGL "initialization".
OpenGL is not initialized! All the code you have in initGL and reshape belongs into display.
In the case of calls glLight… those must be placed in display, after setting the modelview matrix into the space you want the lights to be in. Also OpenGL is not a library; yes originally the 'L' in OpenGL did mean library, but I backronymed it to Layer, because that's what it is on most modern graphics systems: A layer between a end user program and the GPU and its drivers.
I think once you moved the code from initGL and reshape to display, the solution should become clear: You can change, reset and modify the projection and modelview matrix whenever you like. To have the window width and height available in display either store them in global variables in reshape, or, the preferred solution, use glutGet(GLUT_WINDOW_WIDTH) and glutGet(GLUT_WINDOW_HEIGHT) to query the window dimensions in the display function.
You want to draw things in a orthographic projection? Then setup projection and modelview appropriately. Switching to a perspective? Just do it.
I think I kinda figure out why my background texture keep disappearing. I had Cullface and depth something turned on. I turned it off befor popping the last matrix and it works.
However, there is one problem. The texture image is snowy background, but it turns into all red. So first I thought it was due to the reflection of the lighting from the snowgirl. I turned off all the light and still red. Can't figure out why. Could it be, the texture color blending in with the original color of the snowman?
I made a program written in OpenGL and when ever I run It the program fills up all the ram and then closes at approximately 3300/4000 Mb of ram. Here is my program:
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <windows.h>
#include <gl/gl.h>
#include <gl/glut.h>
#include <gl/GLU.h>
#include <gl/glaux.h>
using namespace std;
GLuint texture;
AUX_RGBImageRec* LoadImage (char* file) {
return auxDIBImageLoad (file);
}
int LoadTexture (char* file) {
AUX_RGBImageRec* Textureimage;
Textureimage = LoadImage (file);
glGenTextures (1, &texture);
glBindTexture (GL_TEXTURE_2D, texture);
glTexImage2D (GL_TEXTURE_2D,
0,
GL_RGB,
Textureimage->sizeX,
Textureimage->sizeY,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
Textureimage->data
);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
delete Textureimage;
return 0;
}
void exitkey (unsigned char key, int x, int y) {
switch (key) {
case 27:
exit (0);
}
}
void Render3d () {
glEnable (GL_DEPTH_TEST);
glEnable (GL_NORMALIZE);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHT1);
glEnable (GL_TEXTURE_2D);
}
void incaseofresize (int w, int h) {
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (90.0, (double)w / (double)h, 0.7, 300.0);
}
double theangle = 30.0;
void draw () {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.0, 0.0, -6.0);
glPushMatrix ();
glRotatef (theangle, 0.0, 1.0, 0.0);
GLfloat ambientlightcolor [] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light0color [] = { 0.5, 0.5, 0.0, 1.0 };
GLfloat light1color [] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat light0position [] = { 2.0, 0.0, 3.0, 1.0 };
GLfloat light1position [] = { -2.0, 0.0, 3.0, 1.0 };
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, ambientlightcolor);
glLightfv (GL_LIGHT0, GL_DIFFUSE, light0color);
glLightfv (GL_LIGHT0, GL_POSITION, light0position);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light1color);
glLightfv (GL_LIGHT1, GL_POSITION, light1position);
LoadTexture ("me.bmp");
glBegin (GL_QUADS);
//Drawing shape
glColor3f (1.0, 1.0, 1.0);
//Left side
glNormal3f (0.0, 0.0, 1.0);
glTexCoord2f (0.0, 0.0);
glVertex3f (-1.5, -1.0, -1.5);
glTexCoord2f (1.0, 0.0);
glVertex3f (0.0, -1.0, 1.5);
glTexCoord2f (1.0, 1.0);
glVertex3f (0.0, 1.0, 1.5);
glTexCoord2f (0.0, 1.0);
glVertex3f (-1.5, 1.0, -1.5);
glEnd ();
LoadTexture ("mom.bmp");
glBegin(GL_QUADS);
//Right side
glNormal3f (0.0, 1.0, 1.0);
glTexCoord2f (0.0, 0.0);
glVertex3f (0.0, -1.0, 1.5);
glTexCoord2f (1.0, 0.0);
glVertex3f (1.5, -1.0, -1.5);
glTexCoord2f (1.0, 1.0);
glVertex3f (1.5, 1.0, -1.5);
glTexCoord2f (0.0, 1.0);
glVertex3f (0.0, 1.0, 1.5);
glEnd ();
glBegin (GL_QUADS);
//Back right side
glNormal3f (0.0, 1.0, 0.0);
glVertex3f (1.5, -1.0, -1.5);
glVertex3f (0.0, -1.0, -4.5);
glVertex3f (0.0, 1.0, -4.5);
glVertex3f (1.5, 1.0, -1.5);
glEnd ();
glBegin (GL_QUADS);
glNormal3f (0.0, 1.0, 0.0);
glVertex3f (0.0, -1.0, -4.5);
glVertex3f (-1.5, -1.0, -1.5);
glVertex3f (-1.5, 1.0, -1.5);
glVertex3f (0.0, 1.0, -4.5);
glEnd ();
glutSwapBuffers ();
}
void rotate (int value) {
theangle += 1.5;
if (theangle > 360) {
theangle -=360;
}
glutPostRedisplay ();
glutTimerFunc (50, rotate, 0);
}
int main (int argcpp, char** argv) {
glutInit (&argcpp, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (720, 480);
glutCreateWindow ("OpenGL");
Render3d ();
glutDisplayFunc (draw);
glutKeyboardFunc (exitkey);
glutReshapeFunc (incaseofresize);
glutTimerFunc (50, rotate, 0);
glutMainLoop ();
return 0;
}
I think its the LoadTexture function reloading the image over and over again each loop and I cant find a way to delete the image data after each loop.
Every time your program iterates through the display function it will load images into a new texture object, not freeing the previously created ones.
The canonical way is to load textures only once. OpenGL organizes textures in so called texture objects, identified by a so called name ID. LoadTexture does return this ID. You use such a texture by calling glBindTexture(GL_TEXTURE_2D, theTextureID);