glRotatef

今天费了好大的牛劲,总算能在MFC下让OpenGL画出的对象转动了.最后逼的我差点重写MFC的消息循环函数,总算没走到那步.
还是参考别人的代码,照搬还是不行.还是把OpenGL的作图指令单独写成一个函数,然后在OnPaint函数里调用.

这里最关键的地方就是OpenGL作图函数的编写.我参考了多套代码,写出来的都不一样.别人写的代码都或多或少的有一两个OpenGL作图函数非要单独放到OnPaint或其它地方,这样就变的有点零散,我把所有的转动需要的OpenGL作图函数都整合到一个函数中.我写的MFC还不是SDI单文档程序,SDI的MFC是在OnDraw函数中调用OpenGl作图函数.

1函数开头要定义一到两个static float型的变量,用作转动对象时glRotatef函数的参数,并且这个变量在函数结尾要做+=或-=运算,这样对象才能动起来.

2随意使用各种作图命令,关键要用glRotatef,好让做出来的图能动.

3作图命令用完后,函数的结尾要用SwapBuffers显示图像,然后把函数开头声明的static float变量做+=或-=运算,数值越大转动速度越快.最后最关键的一步,要写Invalidate(FALSE);

头文件:

// smotri.h
// smotri - Simple MFC, C++, OpenGL Tutorial Program
// by:   Joel Parris
// date: 10/9/2000

#include // MFC Windows include file
#include // OpenGL include file
#include // OpenGL Utilities include file
#include
#include
#include

class CSmotri: public CWinApp
{
public:
virtual BOOL InitInstance();

};

class COpenGLWindow: public CFrameWnd
{
public:

COpenGLWindow();   // COpenGLWindow Class Constructor

~COpenGLWindow();   // COpenGLWindow Class Constructor

HDC   m_hgldc;   // GDI Device Context
    HGLRC m_hglRC;   // Rendering Context

BOOL SetPixelformat(HDC hdc);
void GetGLInfo();
int DrawGLScene(void);
int InitGL(void);
void ReSizeGLScene(int width, int height);

virtual BOOL PreCreateWindow( CREATESTRUCT& cs );

protected:

afx_msg void OnPaint();
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnSize(UINT nType, int cx, int cy );
    afx_msg BOOL OnEraseBkgnd( CDC* pDC );
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

DECLARE_MESSAGE_MAP()

};

源文件:

// smotri - Simple MFC, C++, OpenGL Tutorial Program
// by:   Joel Parris
// date: 1/21/2001

#include "smotri.h"
//#include "timer.h"

CSmotri Smotri; // Instantiate the Smotri application

// CMyApp Member Function
BOOL CSmotri::InitInstance() // Initialize Smotri
{
m_pMainWnd = new COpenGLWindow;
// m_nCmdShow = SW_SHOWMAXIMIZED; // Comment to UnMaximize the Window
m_pMainWnd -> ShowWindow(m_nCmdShow);
m_pMainWnd -> UpdateWindow();

return true;
}

// COpenGLWindow message map and Member functions

BEGIN_MESSAGE_MAP(COpenGLWindow, CFrameWnd)
ON_WM_PAINT()
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_WM_ERASEBKGND()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()

COpenGLWindow::COpenGLWindow()
{
Create( NULL, _T("Smotri - a Simple MFC OpenGL Application"),
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_OWNDC);
//ModifyStyle(WS_CAPTION,   0,   SWP_FRAMECHANGED);
}

COpenGLWindow::~COpenGLWindow()
{
    wglMakeCurrent(NULL,NULL);
    wglDeleteContext(m_hglRC);
}

BOOL COpenGLWindow::PreCreateWindow( CREATESTRUCT& cs )
{
    if(!CFrameWnd::PreCreateWindow(cs))
return FALSE;

// Set the initial size of the window
cs.cx = 800;
cs.cy = 600;

return TRUE;
}

BOOL COpenGLWindow::OnEraseBkgnd( CDC* pDC )
{
/* This overrides the MFC Message Loop's OnEraseBkgnd(), which
keeps the OpenGL window from flashing. I shouldn't tell you
this but contrary to popular opinion it doesn't matter what this
override returns TRUE or FALSE. If you don't believe me, try it
    for yourself.
*/

return TRUE;
}

void COpenGLWindow::OnSize(UINT nType, int cx, int cy )
{

ReSizeGLScene( cx, cy );

}

void COpenGLWindow::OnPaint()
{
    CPaintDC dc(this); // Needed

//QueryPerformanceFrequency(&timerFrequency); // Initialize timer
//QueryPerformanceCounter(&startCount);   // Start timer

// process block
//int imax = 100;
//for (int i = 1; i <= imax; i++) // Draw the scene 100 times
//{

DrawGLScene(); // Render the OpenGL scene
//}
// end, process block

//QueryPerformanceCounter(&endCount); // Stop timer
//double time = interval_time( startCount, endCount );
//output_time( time );

}

BOOL COpenGLWindow::SetPixelformat(HDC hdc)
{

PIXELFORMATDESCRIPTOR *ppfd;
    int pixelformat;

PIXELFORMATDESCRIPTOR pfd = {
    sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
    1,                     // version number
    PFD_DRAW_TO_WINDOW |   // support window
    PFD_SUPPORT_OPENGL |   // support OpenGL
    PFD_GENERIC_FORMAT |
    PFD_DOUBLEBUFFER,      // double buffered
    PFD_TYPE_RGBA,         // RGBA type
    32,                    // 32-bit color depth
    0, 0, 0, 0, 0, 0,      // color bits ignored
    8,                     // no alpha buffer
    0,                     // shift bit ignored
    8,                     // no accumulation buffer
    0, 0, 0, 0,            // accum bits ignored
    64,                    // 64-bit z-buffer
    8,                     // stencil buffer
    8,                     // auxiliary buffer
    PFD_MAIN_PLANE,        // main layer
    0,                     // reserved
    0, 0, 0                // layer masks ignored
    };

ppfd = &pfd;

if ( (pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0 )
    {
        ::MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE)
    {
        ::MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

return TRUE;

}

int COpenGLWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{

m_hgldc = ::GetDC(m_hWnd);   // Get a device context for OpenGL

if(!SetPixelformat(m_hgldc)) // set pixel format
    {
::MessageBox(::GetFocus(),"SetPixelformat Failed!","Error",MB_OK);
return -1;
    }

m_hglRC = wglCreateContext(m_hgldc); // Create an OpenGL rendering context
    int i= wglMakeCurrent(m_hgldc,m_hglRC); // Make rendering context current
GetGLInfo(); // Get OpenGL information

InitGL();   // Initialize OpenGL

return 0;
}

void COpenGLWindow::GetGLInfo() // Get OpenGL Information
{

CString oglinfo;

oglinfo = "OpenGL Information/n/nWho: ";
oglinfo += ::glGetString( GL_VENDOR );
oglinfo += "/nWhich: ";
oglinfo += ::glGetString( GL_RENDERER );
oglinfo += "/nVersion: ";
oglinfo += ::glGetString( GL_VERSION );
oglinfo += "/nExtensions: ";
oglinfo += ::glGetString( GL_EXTENSIONS );

AfxMessageBox(oglinfo,MB_ICONINFORMATION); // Display OpenGL Information

}

void COpenGLWindow::ReSizeGLScene( int width, int height) // Resize And Initialize The GL Window
{
// from NeHe's Tutorial 3
if (height==0)           // Prevent A Divide By Zero By
{
   height=1;           // Making Height Equal One
}

glViewport(0,0,width,height);       // Reset The Current Viewport

glMatrixMode(GL_PROJECTION);       // Select The Projection Matrix
glLoadIdentity();          // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0,(float)width/(float)height,0.1,100.0);

glMatrixMode(GL_MODELVIEW);        // Select The Modelview Matrix
glLoadIdentity();          // Reset The Modelview Matrix

}

int COpenGLWindow::InitGL(void)        // Intitialize OpenGl     // All Setup For OpenGL Goes Here
{
// from NeHe's Tutorial 3
glShadeModel(GL_SMOOTH);        // Enable Smooth Shading
glClearColor(0.0, 0.0, 0.0, 0.5);      // Black Background
glClearDepth(1.0);          // Depth Buffer Setup
glEnable(GL_DEPTH_TEST);        // Enables Depth Testing
glDepthFunc(GL_LEQUAL);         // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE;           // Initialization Went OK
}

int COpenGLWindow::DrawGLScene(void)      // Here's Where We Do All The Drawing
{
/*static float rrr;
glClearColor(0.0f, 0.0f, 0.6f, 1.0f);    // 设置刷新背景色
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// 刷新背景
glLoadIdentity();  
glPushMatrix();
glPointSize(4);
glTranslatef (-5, 4,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(1.0f, 0.0f, 0.0f);glBegin(GL_POINTS);//
   glVertex3f( 0.0f, 1.0f,-1.0f);//a点
   glVertex3f(-1.0f,-1.0f, 0.0f);//b点
   glVertex3f( 1.0f,-1.0f, 0.0f);//c点
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef ( 0, 4,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(0.0f, 1.0f, 0.0f);glBegin(GL_LINE_LOOP); //
   glVertex3f( 0.0f, 1.0f,-1.0f);//a点
   glVertex3f(-1.0f,-1.0f, 0.0f);//b点
   glVertex3f( 1.0f,-1.0f, 0.0f);//c点
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef ( 5, 4,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(0.0f, 0.0f, 1.0f);glBegin(GL_POLYGON);//
glVertex3f( 0.0f, 1.0f,-1.0f);//a点
glVertex3f(-1.0f,-1.0f, 0.0f);//b点
glVertex3f( 1.0f,-1.0f, 0.0f);//c点
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef (-5, 0,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(1.0f, 1.0f, 0.0f);glBegin(GL_POLYGON);//
glVertex3f(0.0f,0.0f ,0.0f);//a点
glVertex3f(1.0f,0.0f, 0.0f);//b点
glVertex3f(1.0f,0.0f,-1.0f);//c点
glVertex3f(0.0f,0.0f,-1.0f);//d点
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef ( 0, 0,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(0.0f, 1.0f, 1.0f);glBegin(GL_QUAD_STRIP);//
    glVertex3f(0.0f,0.0f ,0.0f);//a0点
    glVertex3f(0.0f,1.0f ,0.0f);//a1点
    glVertex3f(1.0f,0.0f, 0.0f);//b0点
    glVertex3f(1.0f,1.0f, 0.0f);//b1点
    glVertex3f(1.0f,0.0f,-1.0f);//c0点
    glVertex3f(1.0f,1.0f,-1.0f);//c1点
    glVertex3f(0.0f,0.0f,-1.0f);//d0点
    glVertex3f(0.0f,1.0f,-1.0f);//d1点
    glVertex3f(0.0f,0.0f ,0.0f);//a0点
    glVertex3f(0.0f,1.0f ,0.0f);//a1点
glEnd();

glBegin(GL_POLYGON);//
glVertex3f(0.0f,0.0f ,0.0f);//a0点
glVertex3f(1.0f,0.0f, 0.0f);//b0点
glVertex3f(1.0f,0.0f,-1.0f);//c0点
glVertex3f(0.0f,0.0f,-1.0f);//d0点
glVertex3f(0.0f,1.0f ,0.0f);//a1点
glVertex3f(1.0f,1.0f, 0.0f);//b1点
glVertex3f(1.0f,1.0f,-1.0f);//c1点
glVertex3f(0.0f,1.0f,-1.0f);//d1点
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef ( 5, 0,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(1.0f, 0.0f, 1.0f);glBegin(GL_TRIANGLE_FAN);//
   glVertex3f(0,0,0.0f );  
   for(int i=0;i<=390;i+=30)
   {float p=(float)(i*3.14/180);
    glVertex3f((float)sin(p),(float)cos(p),0.0f );
   }
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef (-5,-4,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(1.0f, 1.0f, 1.0f);glBegin(GL_QUAD_STRIP);//
   for(int i2=0;i2<=390;i2+=30)
   { float p=(float)(i2*3.14/180);
glVertex3f((float)sin(p)/2,(float)cos(p)/2,1.0f );
glVertex3f((float)sin(p)/2,(float)cos(p)/2,0.0f );
   }
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef ( 0, -4,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(0.7f, 0.7f, 0.7f);auxSolidCone(1,1);
glPopMatrix();
glPushMatrix();
glTranslatef ( 5,-4,-13);glRotatef(rrr,1.0,1.0,1.0);
glColor3f(0.4f, 0.4f, 0.4f);auxWireTeapot(1);
glPopMatrix();*/
static float rtri,rquad;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转三角形 ( 新增 )
glBegin(GL_TRIANGLES); // 绘制三角形
glColor3f(1.0f,0.0f,0.0f); //设置当前色为红色
glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点
glColor3f(0.0f,1.0f,0.0f);//设置当前色为绿色
glVertex3f(-1.0f,-1.0f, 0.0f); // 左下
glColor3f(0.0f,0.0f,1.0f);//设置当前色为蓝色
glVertex3f( 1.0f,-1.0f, 0.0f); // 右下
glEnd(); // 三角形绘制结束
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(1.5f,0.0f,-6.0f); // 右移1.5单位,并移入屏幕 6.0
glRotatef(rquad,1.0f,0.0f,0.0f); // 绕X轴旋转四边形 ( 新增 )
//下一段代码保持不变。在屏幕的右侧画一个蓝色的正方形。
glColor3f(0.5f,0.5f,1.0f); // 一次性将当前色设置为蓝色
glBegin(GL_QUADS); // 绘制正方形
glVertex3f(-1.0f, 1.0f, 0.0f); // 左上
glVertex3f( 1.0f, 1.0f, 0.0f); // 右上
glVertex3f( 1.0f,-1.0f, 0.0f); // 左下
glVertex3f(-1.0f,-1.0f, 0.0f); // 右下
glEnd(); // 正方形绘制结束

glFlush();           // 更新窗口
SwapBuffers(m_hgldc);         // 切换缓冲区
//rrr+=1;if(rrr>360) rrr=0;

rtri+=0.2f; // 增加三角形的旋转变量(新增)
rquad-=0.15f; // 减少四边形的旋转变量(新增)

Invalidate(FALSE);
return TRUE;

}

void COpenGLWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{

switch (nChar)
{
case VK_ESCAPE:
   exit(0);
   break;
default:
   break;
}

}

本文转自
http://hi.baidu.com/lmhopen/blog/item/c570f44314cab0159313c6e2.html

用glRotatef函数转动对象相关推荐

  1. JavaScript如何声明对象、函数以及对象中的函数(即方法)

    目录 声明对象的2种最常见方法 声明函数的2种最常见方法 在对象中声明函数 声明对象的2种最常见方法 1) var Zhihuijun = {name:'彭志辉',age:28,upName:'稚晖君 ...

  2. R语言union函数计算数据对象(vector、list、dataframe)的并集:union函数计算两个vector向量、dataframe、列表list的并集

    R语言union函数计算数据对象(vector.list.dataframe)的并集:union函数计算两个vector向量.dataframe.列表list的并集 目录

  3. R语言unique函数计算数据对象(vector、dataframe)的unique独特值:unique函数从vector向量、dataframe中删除重复项、删除dataframe重复行

    R语言unique函数计算数据对象(vector.dataframe)的unique独特值:unique函数从vector向量.dataframe中删除重复项.删除dataframe重复行 目录

  4. R语言sample函数数据对象采样实战

    R语言sample函数数据对象采样实战 目录 R语言sample函数数据对象采样实战 #基本语法 #仿真数据

  5. jquery jQuery的入口函数 $函数 dom对象和jquery对象

    文章目录 jquery jQuery的入口函数 $函数 dom对象和jquery对象 jQuery的入口函数 视频 代码 $函数 视频 代码 dom对象和jquery对象 视频 代码 jquery j ...

  6. 一张图说明 函数, 实例(对象), 原型之间的关系

    前言 很多初学者都对函数,实例(对象), 原型之间的关系理不清楚. 网上五花八门的文章很多,要么不知所云,要么是晦涩难懂. 本文意在用最简洁的语言跟示例让初学者理清楚这三者之间的关系,无需理会其内部原 ...

  7. python3调用函数len结果不返回字符串长度_Python通过len函数返回对象长度

    英文文档: len(s) Return the length (the number of items) of an object. The argument may be a sequence (s ...

  8. C++_向函数传递对象

    向函数传递对象 1. 使用对象作为函数参数 对象可以作为参数传递给函数,其方法与传递其他类型的数据相同. 在向函数传递对象时,是通过传值调用传递给函数的. 因此,函数中对对象的任何修改均不影响调用该函 ...

  9. [轉]子窗口和父窗口的函数或对象能否相互访问

    子窗口和父窗口的函数或对象能否相互访问 解决思路:        每一个窗口其实也是一个对象,窗口内的对象或函数就相当于对象内的对象或方法,问题的关键是如何取得窗口对象的控制句柄,不同的窗口的控件句柄 ...

最新文章

  1. 【NOIP2016】愤怒的小鸟
  2. Sql2005自动备份并邮件通知状态之二创建维护计划
  3. C# WPF抽屉效果实现
  4. 一步一步学Silverlight 2系列(25):综合实例之Live Search
  5. linux下amd超频工具,AMD锐龙自动超频工具ClockTuner for Ryzen
  6. 可能是最好的单例模式
  7. 中jsp加载不出来layui_Maven+JSP+SSM+Mysql实现的学生选课系统
  8. js实现二级联动菜单
  9. MyCat分片规则之一致性hash分片
  10. 不会写代码也可以, 手把手教你制作炫酷生日祝福网页(程序员专属情人节表白网站)
  11. 系统的性能与压力测试
  12. 世界坐标系和相机坐标系,图像坐标系的关系
  13. css html5布局方式_创建新HTML5 / CSS3单页布局–艺术主题
  14. 【157天】尚学堂高琪Java300集视频精华笔记(126)
  15. 公司上市几轮投资分别是什么
  16. 思科实验-生成树协议STP
  17. 猫眼api html,python爬取动态数据实战---猫眼专业版-实时票房(二)
  18. 茄子用水泡过10分钟后变成蓝色
  19. [PTA]习题9-3 平面向量加法
  20. 关于jeecg 项目的莫名其妙的问题

热门文章

  1. 用指向指针的指针方法对n个整数排序输出
  2. inner join和outer join的区别
  3. MPAndroidChart的详细使用——BarChart条形图(二)
  4. 计算机键盘重复,电脑怎么设置键盘重复延迟和重复速度?
  5. 什么是 Android Jetpack?
  6. 常见物联网近距离无线通信技术解析
  7. 计算机视觉——KNN算法以及手势识别应用
  8. 计算机网络实验三——IP网络规划与路由设计
  9. YOLOV5:在本地电脑训练模型
  10. English digest