OpenGL作圖非常方便
下面介紹如何在 VC++ 上進行 OpenGL 編程
下面以畫一條 Bezier 曲線為例
一
New Project | MFC Application Wizard (EXE) |
*注* : 加
二
用下面方法產生 BezierCurve
WorkSpace | ClassView | Test Classes| <右擊彈出> New Class | Generic Class(不用MFC類) |
三
寫好下面兩個文件
BezierCurve
四
#include <GL/gl
#include <GL/glu
#include <GL/glaux
Project | Settings | Link | Object/library module |
五
cs
OpenGL 繪圖的機制是: 先用 OpenGL 的繪圖上下文 Rendering Context (簡稱為 RC )把圖畫好
int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) ==
return
myInitOpenGL();
return
}
void CTestView::myInitOpenGL()
{
m_pDC = new CClientDC(this); //創建 DC
ASSERT(m_pDC != NULL);
if (!mySetupPixelFormat()) //設定繪圖的位圖格式
return;
m_hRC = wglCreateContext(m_pDC
wglMakeCurrent(m_pDC
} //CClient * m_pDC; HGLRC m_hRC; 是 CTestView 的成員變量
BOOL CTestView::mySetupPixelFormat()
{//我們暫時不管格式的具體內容是什麼
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR)
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER
PFD_TYPE_RGBA
PFD_MAIN_PLANE
};
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(m_pDC
{
MessageBox(
return FALSE;
}
if (SetPixelFormat(m_pDC
{
MessageBox(
return FALSE;
}
return TRUE;
}
void CTestView::OnDestroy()
{
wglMakeCurrent(m_pDC
wglDeleteContext(m_hRC); //刪除 RC
if (m_pDC)
delete m_pDC; //刪除當前 View 擁有的 DC
CView::OnDestroy();
}
BOOL CTestView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
// return CView::OnEraseBkgnd(pDC);
//把這句話注釋掉
//會用白色北景來刷新
return TRUE;//只要空返回即可
}
void CTestView::OnDraw(CDC* pDC)
{
wglMakeCurrent(m_pDC
myDrawScene( ); //具體的繪圖函數
SwapBuffers(m_pDC
//在屏幕上顯示
wglMakeCurrent(m_pDC
}
void CTestView::myDrawScene( )
{
glClearColor(
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslated(
//以便投影時可見
//物體才能可見
//本例是為了演示平面 Bezier 曲線的
//變換
//下面畫一條 Bezier 曲線
bezier_curve
bezier_curve
//是 CTestView 的成員變量
//具體的函數見附錄
glPopMatrix();
glFlush(); //結束 RC 繪圖
return;
}
void CTestView::OnSize(UINT nType
{
CView::OnSize(nType
VERIFY(wglMakeCurrent(m_pDC
w=cx;
h=cy;
VERIFY(wglMakeCurrent(NULL
}
void CTestView::OnLButtonDown(UINT nFlags
{
CView::OnLButtonDown(nFlags
if(bezier_curve
{
MessageBox(
return;
}
//以下為坐標變換作准備
GetClientRect(&m_ClientRect);//獲取視口區域大小
w=m_ClientRect
h=m_ClientRect
//w
centerx=(m_ClientRect
centery=(m_ClientRect
//centerx
GLdouble tmpx
tmpx=scrx
tmpy=scry
bezier_curve
bezier_curve
bezier_curve
InvalidateRect(NULL
}
double CTestView::scrx
{
return (double)(scrx
}
double CTestView::scry
{
}
附錄
class CBezierCurve
{
public:
myPOINT
//myPOINT
//成員為Gldouble x
int m_N; //控制頂點的個數
public:
CBezierCurve();
virtual ~CBezierCurve();
void bezier_generation(myPOINT
//算法的具體實現
void myDraw();//畫曲線函數
void myPolygon(); //畫控制多邊形
};
CBezierCurve::CBezierCurve()
{
m_N=
m_Vertex[
m_Vertex[
m_Vertex[
m_Vertex[
m_Vertex[
m_Vertex[
m_Vertex[
m_Vertex[
}
CBezierCurve::~CBezierCurve()
{
}
void CBezierCurve::myDraw()
{
bezier_generation(m_Vertex
}
void CBezierCurve::bezier_generation(myPOINT
{ //算法的具體描述
int i
level
if(level<
if(level==
{
glColor
glBegin(GL_LINES); //畫出線段
glVertex
glVertex
glEnd();//結束畫線段
return; //遞歸到了最底層
}
myPOINT
for(i=
Q[i]
Q[i]
}
for(i=
{
R[m_N
R[m_N
for(j=m_N
{
Q[j]
Q[j]
}
}
R[
R[
bezier_generation(Q
bezier_generation(R
}
void CBezierCurve::myPolygon()
{
glBegin(GL_LINE_STRIP); //畫出連線段
glColor
for(int i=
{
glVertex
}
glEnd();//結束畫連線段
}
From:http://tw.wingwit.com/Article/program/net/201311/11388.html