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();
}
原文:http://blog.csdn.net/duxingheiying1041/article/details/44044389