五、设置 OpenGL 工作环境:(下面各个操作,均针对 TestView.cpp ) 1. 处理 PreCreateWindow(): 设置 OpenGL 绘图窗口的风格 cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC; 2. 处理 OnCreate():创建 OpenGL 的绘图设备。 OpenGL 绘图的机制 是: 先用 OpenGL 的绘图上下文 Rendering Context (简称为 RC ) 把图画好,再把所绘结果通过 SwapBuffer() 函数传给 Window 的 绘图上下文 Device Context (简记为 DC).要注意的是,程序运行 过程中,可以有多个 DC,但只能有一个 RC。因此当一个 DC 画完图 后,要立即释放 RC,以便其它的 DC 也使用。在后面的代码中,将有 详细注释。 int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; Init(); return 0; } void CTestView::Init() { m_pDC = new CClientDC(this); //创建 DC ASSERT(m_pDC != NULL); if (!bSetupPixelFormat()) //设定绘图的位图格式,函数下面列出 return; m_hRC = wglCreateContext(m_pDC->m_hDC);//创建 RC wglMakeCurrent(m_pDC->m_hDC, m_hRC); //RC 与当前 DC 相关联 } //CClient * m_pDC; HGLRC m_hRC; 是 CTestView 的成员变量 BOOL CTestView::bSetupPixelFormat() { static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 32, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; int pixelformat; if ( (pixelformat = ChoosePixelFormat(m_pDC->m_hDC, &pfd)) == 0 ) { MessageBox("ChoosePixelFormat failed"); return FALSE; } if (SetPixelFormat(m_pDC->m_hDC, pixelformat, &pfd) == FALSE) { MessageBox("SetPixelFormat failed"); return FALSE; } return TRUE; }
我有空再帮你看看吧~冲星星ing...
发了一个,你自己看吧,别人的,我没有调过
我在做opengl,很容易入门,但要做好还是不容易的,
vc做这方面的东西有固定的框架
建议你多看看这个网站的:http://nehe.gamedev.net/
还有 :http://www.opengl.org
csdn的个人专栏里有nehe的中文译本
1、
// BezierCurve.h: interface for the CBezierCurve class.
//
//////////////////////////////////////////////////////////////////////#if !defined(AFX_BEZIERCURVE_H__2DBEDF7C_A5E9_48E8_A0B4_8F462FDC3572__INCLUDED_)
#define AFX_BEZIERCURVE_H__2DBEDF7C_A5E9_48E8_A0B4_8F462FDC3572__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#define MAX 50
#include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h>
struct myPOINT2D{
GLdouble x,y;
};class CBezierCurve
{ public: CBezierCurve(); virtual ~CBezierCurve(); void bezier_generation(myPOINT2D P[MAX],int level); //算法的具体实现 void myDraw();//画曲线函数 public: void myPolygon(); //画控制多边形 myPOINT2D m_Vertex[MAX];//控制顶点,以数组存储 //myPOINT2D 是一个存二维点的结构 //成员为Gldouble x,y int m_N; //控制顶点的个数 }; #endif // !defined(AFX_BEZIERCURVE_H__2DBEDF7C_A5E9_48E8_A0B4_8F462FDC3572__INCLUDED_)
// BezierCurve.cpp: implementation of the CBezierCurve class.
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"
#include "test.h"
#include "BezierCurve.h"
#define LEVEL 7#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CBezierCurve::CBezierCurve() { m_N=4; m_Vertex[0].x=-0.5f; m_Vertex[0].y=-0.5f; m_Vertex[1].x=-0.5f; m_Vertex[1].y=0.5f; m_Vertex[2].x=0.5f; m_Vertex[2].y=0.5f; m_Vertex[3].x=0.5f; m_Vertex[3].y=-0.5f; } CBezierCurve::~CBezierCurve() { } void CBezierCurve::myDraw() { bezier_generation(m_Vertex,LEVEL); } void CBezierCurve::bezier_generation(myPOINT2D P[MAX], int level) { //算法的具体描述,请参考相关书本 int i,j; level--; if(level<0)return; if(level==0) //不要写成level=0!!! { glColor3f(1.0f,1.0f,1.0f); glBegin(GL_LINES); //画出线段 glVertex2d(P[0].x,P[0].y); glVertex2d(P[m_N-1].x,P[m_N-1].y); glEnd();//结束画线段 return; //递归到了最底层,跳出递归 } myPOINT2D Q[MAX],R[MAX]; for(i=0;i<m_N;i++) { Q[i].x=P[i].x; Q[i].y=P[i].y; } for(i=1;i<m_N;i++) { R[m_N-i].x=Q[m_N-1].x; R[m_N-i].y=Q[m_N-1].y; for(j=m_N-1;j>=i;j--) { Q[j].x=(Q[j-1].x+Q[j].x)/double(2); Q[j].y=(Q[j-1].y+Q[j].y)/double(2); } } R[0].x=Q[m_N-1].x; R[0].y=Q[m_N-1].y; bezier_generation(Q,level); bezier_generation(R,level); } void CBezierCurve::myPolygon() { glBegin(GL_LINE_STRIP); //画出连线段 glColor3f(0.2f,0.4f,0.4f); for(int i=0;i<m_N;i++) { glVertex2d(m_Vertex[i].x,m_Vertex[i].y); } glEnd();//结束画连线段 }
但是我没有做过OPenGL,所以啊,没有办法。
不过调试程序要有耐心喔,要仔细反复的想办法,主动的去搞定
这样才能取得长足的进步!
另:你发给我短消息我收到了,但是很遗憾帮不了你!
// testView.h : interface of the CTestView class
//
/////////////////////////////////////////////////////////////////////////////#if !defined(AFX_TESTVIEW_H__DD4F062D_0936_4E53_BD15_C1AC31EE948E__INCLUDED_)
#define AFX_TESTVIEW_H__DD4F062D_0936_4E53_BD15_C1AC31EE948E__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h>
#include "BezierCurve.h" // Added by ClassView
class CTestView : public CView
{
protected: // create from serialization only
CTestView();
DECLARE_DYNCREATE(CTestView)// Attributes
public:
CTestDoc* GetDocument();// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTestView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL// Implementation
public:
long centery;
long centerx;
long h;
long w;
CRect m_ClientRect;
CBezierCurve bezier_curve;
double scry2gly(int scry);
double scrx2glx(int scrx);
void DrawScene();
HGLRC m_hRC;
CDC *m_pDC;
BOOL bSetupPixelFormat();
void Init();
virtual ~CTestView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endifprotected:// Generated message map functions
protected:
//{{AFX_MSG(CTestView)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};#ifndef _DEBUG // debug version in testView.cpp
inline CTestDoc* CTestView::GetDocument()
{ return (CTestDoc*)m_pDocument; }
#endif///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_TESTVIEW_H__DD4F062D_0936_4E53_BD15_C1AC31EE948E__INCLUDED_)
// testView.cpp : implementation of the CTestView class
//#include "stdafx.h"
#include "test.h"#include "testDoc.h"
#include "testView.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void GLResize(GLsizei w, GLsizei h) //GLResize() 是一个全局函数 { // Prevent a divide by zero if(h == 0) h = 1; glViewport(0, 0, w, h); //设置视口 glMatrixMode(GL_PROJECTION);//进入投影变换状态 glLoadIdentity(); //重新进行投影变换 gluPerspective (20.0f, (GLdouble)w/(GLdouble)h, 1.0, 40.0f); glMatrixMode(GL_MODELVIEW);//结束投影变换 glLoadIdentity(); } /////////////////////////////////////////////////////////////////////////////
// CTestViewIMPLEMENT_DYNCREATE(CTestView, CView)BEGIN_MESSAGE_MAP(CTestView, CView)
//{{AFX_MSG_MAP(CTestView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CTestView construction/destructionCTestView::CTestView()
{
// TODO: add construction code here}CTestView::~CTestView()
{
}BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;
return CView::PreCreateWindow(cs);
}/////////////////////////////////////////////////////////////////////////////
// CTestView drawingvoid CTestView::OnDraw(CDC* pDC)
{
wglMakeCurrent(m_pDC->m_hDC,m_hRC);//使 RC 与当前 DC 相关联 DrawScene( ); //具体的绘图函数,在 RC 中绘制 SwapBuffers(m_pDC->m_hDC);//把 RC 中所绘传到当前的 DC 上,从而 //在屏幕上显示 wglMakeCurrent(m_pDC->m_hDC,NULL);//释放 RC,以便其它 DC 进行绘图 }
}
/////////////////////////////////////////////////////////////////////////////
// CTestView printingBOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}/////////////////////////////////////////////////////////////////////////////
// CTestView diagnostics#ifdef _DEBUG
void CTestView::AssertValid() const
{
CView::AssertValid();
}void CTestView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}CTestDoc* CTestView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc)));
return (CTestDoc*)m_pDocument;
}
#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
// CTestView message handlersint CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
Init(); return 0;
}void CTestView::Init()
{
m_pDC = new CClientDC(this); //创建 DC ASSERT(m_pDC != NULL); if (!bSetupPixelFormat()) //设定绘图的位图格式,函数下面列出 return; m_hRC = wglCreateContext(m_pDC->m_hDC);//创建 RC wglMakeCurrent(m_pDC->m_hDC, m_hRC); //RC 与当前 DC 相关联 } //CClient * m_pDC; HGLRC m_hRC; 是 CTestView 的成员变量 BOOL CTestView::bSetupPixelFormat() { static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 32, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; int pixelformat; if ( (pixelformat = ChoosePixelFormat(m_pDC->m_hDC, &pfd)) == 0 ) { MessageBox("ChoosePixelFormat failed"); return FALSE; } if (SetPixelFormat(m_pDC->m_hDC, pixelformat, &pfd) == FALSE) { MessageBox("SetPixelFormat failed"); return FALSE; } return TRUE; }
void CTestView::OnDestroy()
{
wglMakeCurrent(m_pDC->m_hDC,NULL); //释放与m_hDC 对应的 RC 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::DrawScene()
{
glClearColor(0.0f,0.0f,0.0f,1.0f);//设置背景颜色为黑色 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslated(0.0f,0.0f,-3.0f);//把物体沿(0,0,-1)方向平移 //以便投影时可见。因为缺省的视点在(0,0,0),只有移开 //物体才能可见。 //本例是为了演示平面 Bezier 曲线的,只要作一个旋转 //变换,可更清楚的看到其 3D 效果。 //如?glRotated(30,1.0f,0.0f,0.0f); //绕 X 轴转 30 度 // glRotated(30,0.0f,1.0f,0.0f); //绕 Y 轴转 30 度 glBegin(GL_LINES);//画坐标系,由三条线段组成 glColor3f(1,0,0); glVertex3f(0,0,0); glVertex3f(1,0,0);//X坐标 glColor3f(0,1,0); glVertex3f(0,0,0); glVertex3f(0,1,0);//Y坐标 glColor3f(0,0,1); glVertex3f(0,0,0); glVertex3f(0,0,1);//Z坐标 glEnd();//end draw the 3D axis //下面画一条 Bezier 曲线 bezier_curve.myPolygon();//画Bezier曲线的控制多边形 bezier_curve.myDraw(); //CBezierCurve bezier_curve //是 CTestView 的成员变量 //具体的函数见附录 glPopMatrix(); glFinish(); //结束 RC 绘图 return; }void CTestView::OnSize(UINT nType, int cx, int cy)
{ CView::OnSize(nType, cx, cy); VERIFY(wglMakeCurrent(m_pDC->m_hDC,m_hRC));//确认RC与当前DC关联 GLResize(cx, cy);//具体的响应 WM_SIZE 消息,对投影进行修正 VERIFY(wglMakeCurrent(NULL,NULL));//确认DC释放RC
}void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
{ CView::OnLButtonDown(nFlags, point); if(bezier_curve.m_N>MAX-1) { MessageBox("顶点个数超过了最大数MAX=50"); return; } //以下为坐标变换作准备, //说明:OpenGL 有一个更有力处理方式,即用 gluUnProject() //这里为了证券交易起见,自己处理。 GetClientRect(&m_ClientRect);//获取视口区域大小 w=m_ClientRect.right-m_ClientRect.left;//视口宽度 w h=m_ClientRect.bottom-m_ClientRect.top;//视口高度 h //w,h 是CTestView的成员变量 centerx=(m_ClientRect.left+m_ClientRect.right)/2;//中心位置, centery=(m_ClientRect.top+m_ClientRect.bottom)/2;//取之作原点 //centerx,centery 是 CTestView 的成员变量 GLdouble tmpx,tmpy; tmpx=scrx2glx(point.x);//屏幕上点坐标转化为OpenGL画图的规范坐标 tmpy=scry2gly(point.y); bezier_curve.m_Vertex[bezier_curve.m_N].x=tmpx;//加一个顶点 bezier_curve.m_Vertex[bezier_curve.m_N].y=tmpy; bezier_curve.m_N++;//顶点数加一 InvalidateRect(NULL,TRUE);//发送刷新重绘消息
}double CTestView::scrx2glx(int scrx)
{
return (double)(scrx-centerx)/double(h);
}double CTestView::scry2gly(int scry)
{
return (double)(centery-scry)/double(h);
}