大佬們幫我看看為什么繪制不出來啊,不知道時那里的問題。困擾我一天了,希望大佬們留步幫我看看問題所在。
struct BEZIER_PATCH //貝塞爾曲面結構體
{
Point_3D anchors[4][4]; //控制點坐標
GLuint dlBPatch; //儲存顯示串列地址
GLuint texture; //儲存繪制的紋理
} m_Mybezier; //儲存要繪制的貝塞爾曲面資料
class Point_3D
{
public:
Point_3D();
Point_3D(double x, double y, double z);
double x()const;
double y()const;
double z()const;
Point_3D operator +(const Point_3D &a);
Point_3D operator *(double c);
private:
double m_x,m_y,m_z;
};
void GLWidget::initializeGL()
{
//initializeOpenGLFunctions(); //啟用紋理映射
QPixmap *a=new QPixmap();
if(!a->load("G:/WorkSpace/Qt/My3D_4/asd.bmp"))
{
qDebug("圖片未加載成功");
}
m_Mybezier.texture = bindTexture(*a);
m_Mybezier.dlBPatch = genBezier();
glEnable( GL_TEXTURE_2D );// 啟用2D紋理
glClearColor(0.1f, 0.1f, 0.4f, 0.1f); //背景
glShadeModel(GL_SMOOTH); //啟用陰影平滑
glClearDepth(1.0); //設定深度快取
glEnable(GL_DEPTH_TEST); //啟用深度測驗
glEnable(GL_CULL_FACE); //開啟剔除操作
glDepthFunc(GL_LEQUAL); //所作深度測驗的型別
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //告訴系統對透視進行修正
}
Point_3D GLWidget::bernstein(float u, Point_3D *p)
{
Point_3D a = p[0] * pow(u, 3);
Point_3D b = p[1] * (3*pow(u, 2)*(1-u));
Point_3D c = p[2] * (3*u*pow(1-u, 2));
Point_3D d = p[3] * pow(1-u, 3);
Point_3D r = a + b + c + d;
return r;
}
GLuint GLWidget::genBezier()
{
GLuint drawlist = glGenLists(1); //分配1個顯示串列的空間
Point_3D temp[4];
//根據每一條曲線的細分數,分配相應的記憶體
Point_3D *last = (Point_3D*)malloc(sizeof(Point_3D)*(m_Divs+1));
if (m_Mybezier.dlBPatch != 0) //如果顯示串列存在,則洗掉
{
glDeleteLists(m_Mybezier.dlBPatch, 1);
}
temp[0] = m_Mybezier.anchors[0][3]; //獲得u方向的四個控制點
temp[1] = m_Mybezier.anchors[1][3];
temp[2] = m_Mybezier.anchors[2][3];
temp[3] = m_Mybezier.anchors[3][3];
for (int v=0; v<=m_Divs; v++) //根據細分數,創建各個分割點的引數
{
float py = ((float)v)/((float)m_Divs);
last[v] = bernstein(py, temp); //使用bernstein函式求得分割點坐標
}
glNewList(drawlist, GL_COMPILE); //繪制一個新的顯示串列
glBindTexture(GL_TEXTURE_2D, m_Mybezier.texture); //系結紋理
for (int u=1; u<=m_Divs; u++)
{
float px = ((float)u)/((float)m_Divs); //計算v方向上的細分點的引數
float pxold = ((float)u-1.0f)/((float)m_Divs); //上一個v方向的細分點的引數
temp[0] = bernstein(px, m_Mybezier.anchors[0]); //計算每個細分點v方向上貝塞爾曲面的控制點
temp[1] = bernstein(px, m_Mybezier.anchors[1]);
temp[2] = bernstein(px, m_Mybezier.anchors[2]);
temp[3] = bernstein(px, m_Mybezier.anchors[3]);
glBegin(GL_TRIANGLE_STRIP); //開始繪制三角形帶
for (int v=0; v<=m_Divs; v++)
{
float py = ((float)v)/((float)m_Divs); //沿著u方向順序繪制
glTexCoord2f(pxold, py); //設定紋理坐標并繪制一個頂點
glVertex3d(last[v].x(), last[v].y(), last[v].z());
last[v] = bernstein(py, temp); //計算下一個頂點
glTexCoord2f(px, py); //設定紋理坐標并繪制新的頂點
glVertex3d(last[v].x(), last[v].y(), last[v].z());
}
glEnd(); //結束三角形帶的繪制
}
glEndList(); //顯示串列繪制結束
free(last); //釋放分配的記憶體
return drawlist; //回傳創建的顯示串列
}
void GLWidget::initBezier()
{
m_Mybezier.anchors[0][0] = Point_3D(-0.75, -0.75, -0.50);
m_Mybezier.anchors[0][1] = Point_3D(-0.25, -0.75, 0.00);
m_Mybezier.anchors[0][2] = Point_3D( 0.25, -0.75, 0.00);
m_Mybezier.anchors[0][3] = Point_3D( 0.75, -0.75, -0.50);
m_Mybezier.anchors[1][0] = Point_3D(-0.75, -0.25, -0.75);
m_Mybezier.anchors[1][1] = Point_3D(-0.25, -0.25, 0.50);
m_Mybezier.anchors[1][2] = Point_3D( 0.25, -0.25, 0.50);
m_Mybezier.anchors[1][3] = Point_3D( 0.75, -0.25, -0.75);
m_Mybezier.anchors[2][0] = Point_3D(-0.75, 0.25, 0.00);
m_Mybezier.anchors[2][1] = Point_3D(-0.25, 0.25, -0.50);
m_Mybezier.anchors[2][2] = Point_3D( 0.25, 0.25, -0.50);
m_Mybezier.anchors[2][3] = Point_3D( 0.75, 0.25, 0.00);
m_Mybezier.anchors[3][0] = Point_3D(-0.75, 0.75, -0.50);
m_Mybezier.anchors[3][1] = Point_3D(-0.25, 0.75, -1.00);
m_Mybezier.anchors[3][2] = Point_3D( 0.25, 0.75, -1.00);
m_Mybezier.anchors[3][3] = Point_3D( 0.75, 0.75, -0.50);
m_Mybezier.dlBPatch = 0; //默認的顯示串列為0
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除螢屏和深度快取
glLoadIdentity(); //重置模型觀察矩陣
glTranslatef(0.0f, 0.2f, -3.0f);
glRotatef(-75.0f, 1.0f, 0.0f, 0.0f);
glRotatef(m_Rot, 0.0f, 0.0f, 1.0f); //繞z軸旋轉
glCallList(m_Mybezier.dlBPatch); //呼叫顯示串列,繪制貝塞爾曲面
glDisable(GL_TEXTURE_2D); //禁用紋理貼圖
glColor3f(1.0f, 0.0f, 0.0f); //設定顏色為紅色
for (int i=0; i<4; i++) //繪制水平線
{
glBegin(GL_LINE_STRIP);
for (int j=0; j<4; j++)
{
glVertex3d(m_Mybezier.anchors[i][j].x(),m_Mybezier.anchors[i][j].y(),m_Mybezier.anchors[i][j].z());
}
glEnd();
}
for (int i=0; i<4; i++) //繪制垂直線
{
glBegin(GL_LINE_STRIP);
for (int j=0; j<4; j++)
{
glVertex3d(m_Mybezier.anchors[j][i].x(),m_Mybezier.anchors[j][i].y(),m_Mybezier.anchors[j][i].z());
}
glEnd();
}
glColor3f(1.0f, 1.0f, 1.0f); //恢復OpenGL屬性
glEnable(GL_TEXTURE_2D);
}
void GLWidget::resizeGL(int w, int h)
{
m_proj.setToIdentity();
m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/144517.html
標籤:Qt
下一篇:個人定位
