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.
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 am currently rendering a solar system of planets in my 3d space but every single planet is black even when light hits the sphere. The spheres are rendered last in my render function. Had the colors working when the spheres were being rendered on their own but now i've added my sky box and other quads all the spheres refuse to be colored.
#include "Scene.h"
float rotation;
float rotation2;
int direction;
int speed;
Scene::Scene(Input *in)
{
// Initialise variables
rotation = 20;
rotation2 = 0;
direction = 1;
speed = 5;
myTexture = 0;
skyBox = 0;
// Store pointer for input class
input = in;
// OpenGL settings
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.39f, 0.58f, 93.0f, 1.0f); // Cornflour Blue Background
glClearDepth(1.0f); // Depth Buffer Setup
glClearStencil(0); // Clear stencil buffer
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable(GL_LIGHTING); // Enables Lighting
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
// Other OpenGL / render setting should be applied here.
myTexture = SOIL_load_OGL_texture
(
"gfx/neongrid.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
skyBox = SOIL_load_OGL_texture
(
"gfx/starField.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
camera = new Camera();
}
void Scene::update(float dt)
{
// Update camera position
camera->update(input, dt);
// Handle user input
if (input->isKeyDown(43))
{
direction = 1;
input->SetKeyUp(43);
}
else if (input->isKeyDown(45))
{
direction = -1;
input->SetKeyUp(45);
}
// Update scene related variables
rotation += speed * dt;
rotation2 += (speed *2) * dt;
if (input->isKeyDown('p') && WF == false)
{
WF = true;
input->SetKeyUp('p');
glPolygonMode(GL_FRONT, GL_LINE);
}
if (input->isKeyDown('p') && WF == true)
{
WF = false;
input->SetKeyUp('p');
glPolygonMode(GL_FRONT, GL_FILL);
}
// Calculate FPS for output
calculateFPS();
}
void Scene::render() {
// Clear Color and Depth Buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(camera->getPosition().x, camera->getPosition().y, camera->getPosition().z,
camera->getLookAt().x, camera->getLookAt().y, camera->getLookAt().z,
camera->getUp().x, camera->getUp().y, camera->getUp().z);
glutWarpPointer(400, 300);
glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR);
// Lighting
GLfloat Light_Ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat Light_Diffuse[] = { 9.0f, 9.0f, 9.0f, 1.0f };
GLfloat Light_Position[] = { 2.0f, 2.0f, 2.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, Light_Ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, Light_Diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, Light_Position);
glEnable(GL_LIGHT0);
glDisable(GL_DEPTH_TEST);
#pragma region skybox
glPushMatrix();
glTranslatef(camera->getPosition().x, camera->getPosition().y, camera->getPosition().z);
glBindTexture(GL_TEXTURE_2D, skyBox);
glBegin(GL_QUADS);
//Back
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
//Right
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
//front
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
//left
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
//top
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
//bottom
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
#pragma endregion
glEnable(GL_DEPTH_TEST);
glPopMatrix();
glPushMatrix();
#pragma region wall
glBindTexture(GL_TEXTURE_2D, myTexture);
glTranslatef(0.0, 0.0, 0.0);
glScalef(5.0f, 5.0f, 5.0f);
glBegin(GL_QUADS);
// first face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// second face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
// third face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
// fourth face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, myTexture);
glScalef(5.0f, 5.0f, 5.0f);
glBegin(GL_QUADS);
// first face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
// second face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
// third face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 0.0f, -1.0f);
// fourth face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, -1.0f);
glEnd();
#pragma endregion
glPopMatrix();
glPushMatrix();
// Render sun
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f, 1.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, NULL);
glTranslatef(0.5, 0.5, -0.5);
glColor3f(1.0f, 0.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPushMatrix(); // Push for default matrix
// Render Planet 1
glRotatef(rotation, 0.5, 0.5, 0);
glTranslatef(0, 0, 1);
glScalef(1, 1, 1);
glColor3f(0.0f, 2.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 10, 10);
glPopMatrix(); // Pop off stack back to sun matrix
glPushMatrix(); // Push for default matrix
// Render Planet 2
glRotatef(rotation2, 0, 1, 0);
glTranslatef(2, 0, 0);
glScalef(0.5, 0.5, 0.5);
glColor3f(0.0f, 0.0f, 1.0f);
gluSphere(gluNewQuadric(), 0.20, 5, 5);
glPushMatrix(); // Pop back to sun
// Render a moon around Planet 2
glRotatef((rotation*2.0), 0, 1, 0);
glTranslatef(1.5, 0, 0);
glScalef(0.3, 0.3, 0.3);
glColor3f(0.0f, 0.0f, 1.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPopMatrix(); // Pop to planet 2
glPushMatrix(); // Push for default matrix
// Render a SECOND moon around Planet 2
glRotatef((rotation * 2), 0, 0, 1);
glTranslatef(1.5, 0, 0);
glScalef(0.3, 0.3, 0.3);
glColor3f(0.0f, 0.0f, 1.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPopMatrix();
//glPopMatrix();
glPopMatrix(); // Go back to sun!
glPushMatrix();
glTranslatef(2, 2, 2);
glColor3f(1, 0, 0);
gluSphere(gluNewQuadric(), 0.5, 20, 20);
glPopMatrix();
// End render geometry --------------------------------------
// Render text, should be last object rendered.
renderTextOutput();
// Swap buffers, after all objects are rendered.
glutSwapBuffers();
}
// Handles the resize of the window. If the window changes size the perspective matrix requires re-calculation to match new window size.
void Scene::resize(int w, int h)
{
width = w;
height = h;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if (h == 0)
h = 1;
float ratio = (float)w / (float)h;
fov = 45.0f;
nearPlane = 0.1f;
farPlane = 100.0f;
// Use the Projection Matrix
glMatrixMode(GL_PROJECTION);
// Reset Matrix
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(fov, ratio, nearPlane, farPlane);
// Get Back to the Modelview
glMatrixMode(GL_MODELVIEW);
}
// Calculates FPS
void Scene::calculateFPS()
{
frame++;
time = glutGet(GLUT_ELAPSED_TIME);
if (time - timebase > 1000) {
sprintf_s(fps, "FPS: %4.2f", frame*1000.0 / (time - timebase));
timebase = time;
frame = 0;
}
}
// Compiles standard output text including FPS and current mouse position.
void Scene::renderTextOutput()
{
// Render current mouse position and frames per second.
sprintf_s(mouseText, "Mouse: %i, %i", input->getMouseX(), input->getMouseY());
displayText(-1.f, 0.96f, 1.f, 0.f, 0.f, mouseText);
displayText(-1.f, 0.90f, 1.f, 0.f, 0.f, fps);
}
// Renders text to screen. Must be called last in render function (before swap buffers)
void Scene::displayText(float x, float y, float r, float g, float b, char* string) {
// Get Lenth of string
int j = strlen(string);
// Swap to 2D rendering
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, 5, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Orthographic lookAt (along the z-axis).
gluLookAt(0.0f, 0.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// Set text colour and position.
glColor3f(r, g, b);
glRasterPos2f(x, y);
// Render text.
for (int i = 0; i < j; i++) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]);
}
// Reset colour to white.
glColor3f(1.f, 1.f, 1.f);
// Swap back to 3D rendering.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, ((float)width/(float)height), nearPlane, farPlane);
glMatrixMode(GL_MODELVIEW);
}
Updated sun code :
// Render sun
glTranslatef(0.5, 0.5, -0.5);
glColor3f(1.0f, 0.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPushMatrix(); // Push for default matrix
// Render Planet 1
glRotatef(rotation, 0.5, 0.5, 0);
glTranslatef(0, 0, 1);
glScalef(1, 1, 1);
glColor3f(0.0f, 2.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 10, 10);
glPopMatrix(); // Pop off stack back to sun matrix
glPushMatrix(); // Push for default matrix
Found out i was missing a OpenGL setting
glEnable(GL_COLOR_MATERIAL);
Inserted at the start of Scene
Try to end glEnable(GL_TEXTURE_2D); with glDisable(GL_TEXTURE_2D); after you render sun.
If problem appeared after you added skybox. Check if vertices are in right order.
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;
}
I want to render outline font near playing area, but these two parts are in conflict. If I render only outline font, it's ok. When I render also playing area, textures of cubes have defect and light is changed also. When I render only playing area, it's ok. Here are some pictures:
http://img.obrazok.com/Untitled.usdh.png
Outline font part:
//Display-lists
GLuint fontBase;
GLYPHMETRICSFLOAT gmf[256];
//********************************
//3D Font
//********************************
GLvoid BuildFont(GLvoid) // Build Our Bitmap Font
{
HFONT font; // Windows Font ID
fontBase = glGenLists(256); // Storage For 256 Characters
font = CreateFont( -12, // Height Of Font
0, // Width Of Font
0, // Angle Of Escapement
0, // Orientation Angle
FW_BOLD, // Font Weight
FALSE, // Italic
FALSE, // Underline
FALSE, // Strikeout
ANSI_CHARSET, // Character Set Identifier
OUT_TT_PRECIS, // Output Precision
CLIP_DEFAULT_PRECIS, // Clipping Precision
ANTIALIASED_QUALITY, // Output Quality
FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch
"Comic Sans MS"); // Font Name
HDC hDC = GetDC(GetActiveWindow());
SelectObject(hDC, font); // Selects The Font We Created
wglUseFontOutlines( hDC, // Select The Current DC
0, // Starting Character
255, // Number Of Display Lists To Build
fontBase, // Starting Display Lists
0.0f, // Deviation From The True Outlines
0.2f, // Font Thickness In The Z Direction
WGL_FONT_POLYGONS, // Use Polygons, Not Lines
gmf); // Address Of Buffer To Recieve Data
}
GLvoid KillFont(GLvoid) // Delete The Font
{
glDeleteLists(fontBase, 256); // Delete All 256 Characters
}
void printString(const char *string, float x, float y, float z) // Custom GL "Print" Routine
{
float length=0; // Used To Find The Length Of The Text
for (unsigned int loop=0;loop<(strlen(string));loop++) // Loop To Find Text Length
{
length+=gmf[string[loop]].gmfCellIncX; // Increase Length By Each Characters Width
}
glPushMatrix();
glRotatef(90,0.0,0.0,1.0);
glRotatef(90,1.0,0.0,0.0);
glTranslatef(x,y,z);
glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits
glListBase(fontBase); // Sets The Base Character to 0
glCallLists(strlen(string), GL_UNSIGNED_BYTE, string); // Draws The Display List Text
glPopAttrib(); // Pops The Display List Bits
glPopMatrix();
}
Render playing area:
//Display-lists
GLuint ls_mapWalls;
void renderWalls() {
for (int x = 0; x < mapSize; x++) {
for (int y = 0; y < mapSize; y++) {
glPushMatrix();
glTranslatef(x*2.0f,y*2.0f,0.0f);
if (map[x][y] == 'X') {
renderWall();
}
glPopMatrix();
}
}
}
void renderWall() {
glPushMatrix();
renderTexturedCube(1); //1 or 2
glPopMatrix();
}
void renderTexturedCube(int color) {
glEnable(GL_TEXTURE_2D);
switch (color) {
case 1 :
//normal wall
setMaterialColor(1.0f, 1.0f, 1.0f, 0.2f);
break;
case 2 :
//red wall
setMaterialColor(1.0f, 0.0f, 0.0f, 1.0f);
break;
}
glBindTexture(GL_TEXTURE_2D, texid[0]);
glBegin(GL_QUADS);
// Front Face
glNormal3f(0.0,0.0,1.0);
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.0,0.0,-1.0);
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
glNormal3f(0.0,1.0,0.0);
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);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glNormal3f(0.0,-1.0,0.0);
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
glNormal3f(1.0,0.0,0.0);
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.0,0.0,0.0);
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();
setMaterialColor(1.0f, 1.0f, 1.0f, 1.0f);
glDisable(GL_TEXTURE_2D);
}
Render part:
void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
GLdouble ex = vzd*cos(fi)*cos(xi);
GLdouble ey = vzd*sin(fi)*cos(xi);
GLdouble ez = vzd*sin(xi);
gluLookAt( ex, ey, ez, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f );
printString("Dyna Blaster Beta", 10, 10, 10, 1.0, 0.0, 0.0);
glCallList(ls_mapWalls);
glutSwapBuffers();
}
Init part:
bool init(void)
{
//setup OpenGL
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_CULL_FACE);
//files load
loadMap();
loadTextures();
//next init
ls_mapWalls = glGenLists(1);
glNewList(ls_mapWalls, GL_COMPILE);
renderWalls();
glEndList();
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0);
GLfloat light_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 10.0, 10.0, 10.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
BuildFont();
fi = 0.385f; xi = 0.515f; vzd = 69.2f;
return true;
}
If you have some question or want see another part of code, just ask. Thank you.
The documentation for wglUseFontOutlines at MSDN says this:
With WGL_FONT_POLYGONS, the created display lists call glFrontFace( GL_CW )
or glFrontFace( GL_CCW ); thus the current front-face value might be altered.
OpenGL defults to GL_CCW; so chances are, if you set it back with
glFrontFace( GL_CCW );
after drawing the text, your playing area will render correctly.