GLUTesslator 网格图形 Qt

10 篇文章 0 订阅

Griding.pro

#-------------------------------------------------
#
# Project created by QtCreator 2015-02-04T10:28:19
#
#-------------------------------------------------

QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Griding
TEMPLATE = app


SOURCES += main.cpp\
        griding.cpp

HEADERS  += griding.h \
    grid.h

FORMS    += griding.ui

grid.h

#ifndef GRID_H
#define GRID_H

#include <GL/GLUT.h>

#ifndef CALLBACK
#define CALLBACK __stdcall
#endif

static 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.0
static 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_OBJECT

public:
    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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值