所以我在一个显示列表中有 2 个立方体,我希望其中一个是可以选择的,这样我就可以改变他的颜色或类似的东西。
当我单击一个立方体时,屏幕变黑并且没有任何反应,控制台为我提供最近命中的输出,但屏幕变黑并且不显示任何内容。
这是我的 cpp 文件:
#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
这是没有点击一次的正常视图 http://imageshack.us/photo/my-images/233/31536776.png/
然后当点击它时,它会不断进入开始拾取并停止拾取并给出黑屏 http://imageshack.us/photo/my-images/13/14180995.png/
然后在关闭窗口后停止运行它给了我这个输出http://imageshack.us/photo/my-images/861/13486229.png/