GLUTesslator 网格图形 Qt

来源:互联网 发布:数据挖掘在的应用 编辑:程序博客网 时间:2024/06/08 18:16

Griding.pro

#-------------------------------------------------## Project created by QtCreator 2015-02-04T10:28:19##-------------------------------------------------QT       += core gui openglgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = GridingTEMPLATE = appSOURCES += main.cpp\        griding.cppHEADERS  += griding.h \    grid.hFORMS    += griding.ui

grid.h

#ifndef GRID_H#define GRID_H#include <GL/GLUT.h>#ifndef CALLBACK#define CALLBACK __stdcall#endifstatic GLdouble graphics0[5][4][3] = //左上角图形{{{10.0, 10.0, 0.0}, {-10.0, 10.0, 0.0}, {-10.0, -10.0, 0.0}, {10.0, -10.0, 0.0}},{{7.0,  7.0,  0.0}, {-7.0,  7.0,  0.0}, {-7.0,  -7.0,  0.0}, {7.0,  -7.0,  0.0}},{{4.0,  4.0,  0.0}, {-4.0,  4.0,  0.0}, {-4.0,  -4.0,  0.0}, {4.0,  -4.0,  0.0}},{{2.0,  2.0,  0.0}, {-2.0,  2.0,  0.0}, {-2.0,  -2.0,  0.0}, {2.0,  -2.0,  0.0}},{{1.0,  1.0,  0.0}, {-1.0,  1.0,  0.0}, {-1.0,  -1.0,  0.0}, {1.0,  -1.0,  0.0}}};static GLdouble TessProperty[5] =                //环绕规则{        GLU_TESS_WINDING_ODD,              //环绕数为奇数        GLU_TESS_WINDING_NONZERO,          //环绕数为非0        GLU_TESS_WINDING_POSITIVE,         //环绕数为正数        GLU_TESS_WINDING_NEGATIVE,         //环绕数为负数        GLU_TESS_WINDING_ABS_GEQ_TWO       //环绕数绝对值大于等于2};static void CALLBACK vertexCallback(GLvoid* vertex){    GLdouble* pt;    GLubyte red, green, blue;    //    int numb;    pt = (GLdouble*)vertex;    //    numb = rand();    red = (GLubyte)rand()&0xff;         //(numb>>16) & 0xff;    green = (GLubyte)rand()&0xff;       //(numb>>8) & 0xff;    blue = (GLubyte)rand()&0xff;        //numb & 0xff;    glColor3ub(red, green, blue);    glVertex3dv(pt);}static void CALLBACK beginCallback(GLenum type){    glBegin(type);}static void CALLBACK endCallback(){    glEnd();}static void CALLBACK errorCallback(GLenum errorCode){    const GLubyte * estring;    //打印错误类型    estring = gluErrorString(errorCode);    fprintf(stderr, "Tessellation Error: %s/n", estring);    exit(0);}//用于处理检测轮廓线交点,并决定是否合并顶点,//新创建的顶点最多可以是4个已有顶点线性组合,这些定点坐标存储在data中//其中weight为权重,weight[i]的总合为1.0static void CALLBACK combineCallback(GLdouble coords[3],GLdouble* data[4],GLfloat weight[4],GLdouble ** dataout){    GLdouble *vertex;    int i;    vertex = (GLdouble*)malloc(6*sizeof(GLdouble));    vertex[0] = coords[0];    vertex[1] = coords[1];    vertex[2] = coords[2];    for(i=3; i<6; i++)      //新顶点的颜色为4个顶点的线型组合    {        vertex[i] = weight[0]*data[0][i]+weight[1]*data[1][i]+                weight[2]*data[2][i]+weight[3]*data[3][i];    }    *dataout = vertex;}static void drawGraphics(GLint ngraphic, GLint nproperty){    //    int i;    GLUtesselator *tessobj;    tessobj = gluNewTess();    //注册回调函数    gluTessCallback(tessobj, GLU_TESS_VERTEX, (GLvoid(CALLBACK*)())vertexCallback);    gluTessCallback(tessobj, GLU_TESS_BEGIN,  (GLvoid(CALLBACK*)())beginCallback);    gluTessCallback(tessobj, GLU_TESS_END,    (GLvoid(CALLBACK*)())endCallback);    gluTessCallback(tessobj, GLU_TESS_ERROR,  (GLvoid(CALLBACK*)())errorCallback);    //设置环绕规则    gluTessProperty(tessobj, GLU_TESS_WINDING_RULE, TessProperty[nproperty]);    if(2==ngraphic || 3==ngraphic)    {        gluTessCallback(tessobj, GLU_TESS_COMBINE, (GLvoid(CALLBACK*)())combineCallback);//多边型边自相交的情况下回调用回调函数    }    gluTessBeginPolygon(tessobj, NULL);    switch(ngraphic)    {    case 0:        gluTessBeginContour(tessobj);       //定义轮廓线1 逆时针矩形        gluTessVertex(tessobj, graphics0[0][0], graphics0[0][0]);        gluTessVertex(tessobj, graphics0[0][1], graphics0[0][1]);        gluTessVertex(tessobj, graphics0[0][2], graphics0[0][2]);        gluTessVertex(tessobj, graphics0[0][3], graphics0[0][3]);        gluTessEndContour(tessobj);        gluTessBeginContour(tessobj);       //定义轮廓线2 逆时针矩形        gluTessVertex(tessobj, graphics0[1][0], graphics0[1][0]);        gluTessVertex(tessobj, graphics0[1][1], graphics0[1][1]);        gluTessVertex(tessobj, graphics0[1][2], graphics0[1][2]);        gluTessVertex(tessobj, graphics0[1][3], graphics0[1][3]);        gluTessEndContour(tessobj);        gluTessBeginContour(tessobj);       //定义轮廓线3 逆时针矩形        gluTessVertex(tessobj, graphics0[2][0], graphics0[2][0]);        gluTessVertex(tessobj, graphics0[2][1], graphics0[2][1]);        gluTessVertex(tessobj, graphics0[2][2], graphics0[2][2]);        gluTessVertex(tessobj, graphics0[2][3], graphics0[2][3]);        gluTessEndContour(tessobj);        gluTessBeginContour(tessobj);       //定义轮廓线4 逆时针矩形        gluTessVertex(tessobj, graphics0[3][0], graphics0[3][0]);        gluTessVertex(tessobj, graphics0[3][1], graphics0[3][1]);        gluTessVertex(tessobj, graphics0[3][2], graphics0[3][2]);        gluTessVertex(tessobj, graphics0[3][3], graphics0[3][3]);        gluTessEndContour(tessobj);        gluTessBeginContour(tessobj);       //定义轮廓线5 逆时针矩形        gluTessVertex(tessobj, graphics0[4][0], graphics0[4][0]);        gluTessVertex(tessobj, graphics0[4][1], graphics0[4][1]);        gluTessVertex(tessobj, graphics0[4][2], graphics0[4][2]);        gluTessVertex(tessobj, graphics0[4][3], graphics0[4][3]);        gluTessEndContour(tessobj);        break;    }    gluTessEndPolygon(tessobj);}#endif // GRID_H

griding.h

#ifndef GRIDING_H#define GRIDING_H#include <QWidget>#include <QtOpenGL>#include <GL/glu.h>#include <GL/GLUT.h>#include <GL/gl.h>#include "grid.h"namespace Ui {class Griding;}class Griding : public QGLWidget{    Q_OBJECTpublic:    explicit Griding(QGLWidget *parent = 0);    ~Griding();protected:    void initializeGL();    void resizeGL(GLint width, GLint height);    void paintGL();    void keyPressEvent(QKeyEvent *event); //    void CALLBACK vertexCallback(GLvoid* vertex);//    void CALLBACK beginCallback(GLenum type);//    void CALLBACK endCallback();//    void CALLBACK errorCallback(GLenum errorCode);//    void CALLBACK combineCallback(GLdouble coords[3],GLdouble* data[4],//                                  GLfloat weight[4],GLdouble ** dataout);private:    bool fullscreen;    GLint nProperty;private:    Ui::Griding *ui;};#endif // GRIDING_H

griding.cpp

#include "griding.h"#include "ui_griding.h"#include <GL/glu.h>#include <GL/gl.h>#include <grid.h>Griding::Griding(QGLWidget *parent) :    QGLWidget(parent),    ui(new Ui::Griding){    ui->setupUi(this);    fullscreen = false;    nProperty = 0;}void Griding::initializeGL(){    setGeometry(300, 150, 640, 480);//设置窗口初始位置和大小    glShadeModel(GL_FLAT);//设置阴影平滑模式    glClearColor(0.0, 0.0, 0.0, 0);//改变窗口的背景颜色,不过我这里貌似设置后并没有什么效果    glClearDepth(1.0);//设置深度缓存    glEnable(GL_DEPTH_TEST);//允许深度测试    glDepthFunc(GL_LEQUAL);//设置深度测试类型    glMatrixMode(GL_PROJECTION);    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//进行透视校正//    glLoadIdentity();}void Griding::paintGL(){    //glClear()函数在这里就是对initializeGL()函数中设置的颜色和缓存深度等起作用    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();   //重置当前的模型观察矩阵?不是很理解!//    glBegin(GL_LINE_LOOP);//    glVertex3f(0.0f, 0.0f, 0.0f);//    glVertex3f(1.0f, 1.0f, 1.0f);//    glEnd();//    glBegin(GL_LINE_LOOP);//    glVertex3f(0.0f, 0.0f, 0.0f);//    glVertex3f(-0.5f, -0.5f, 0.0f);//    glEnd();//    glBegin(GL_POINT);//    glPointSize(5.0f);//    glColor3f(1.0f, 0.0f, 0.0f);//    glVertex3f(0.0f, 0.0f, 0.0f);//    glEnd();    glPushMatrix();    glScaled(0.5, 0.5, 1.0);    drawGraphics(0, nProperty);    glPopMatrix();}void Griding::resizeGL(GLint width, GLint height){    if(0 == height)    {        height = 1;//防止一条边为0    }    glViewport(0, 0, (GLint)width, (GLint)height);  //重置当前视口,本身不是重置窗口的,只不过是这里被Qt给封装好了    glMatrixMode(GL_PROJECTION);  //选择投影矩阵    glLoadIdentity();  //重置选择好的投影矩阵    if(width > height)    {        glOrtho(-20, 20, -20, 20, -500 ,500);//        gluPerspective(40.0, (GLfloat)width/(GLfloat)height, 100, 100.0);    }    else    {        glOrtho(-20, 20, -20, 20, -500 ,500);//        gluPerspective(40.0*(GLfloat)height/(GLfloat)width, (GLfloat)height/(GLfloat)width, 100, 100.0);    }//    gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);  //建立透视投影矩阵    glMatrixMode(GL_MODELVIEW);  //以下2句和上面出现的解释一样    glLoadIdentity();}void Griding::keyPressEvent(QKeyEvent *event){    switch(event->key())    {    //F1键为全屏和普通屏显示切换键    case Qt::Key_F1:        fullscreen = !fullscreen;        if(fullscreen)        {            showFullScreen();        }        else        {            setGeometry(300, 150, 640, 480);            showNormal();        }        updateGL();        break;        //Ese为退出程序键    case Qt::Key_Escape:        close();    }}Griding::~Griding(){    delete ui;}

main.cpp

#include "griding.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    Griding w;    w.show();    return a.exec();}
0 0