Phinecos(洞庭散人) 专注于开源技术的研究与应用 Nehe的OpenGL框架(MFC版)

Screenshot_2026-11-03-16-23-09-34.jpg 立即下载

原文链接:http://www.cnblogs.com/phinecos/archive/2007/07/29/835386.html

SwapBuffers参考内容链接:http://blog.sina.com.cn/s/blog_4e6f376d0100c0o2.html


Nehe的几个OpenGL框架都是Win32 sdk版本的,我现在需要在MFC下学习OpenGL,今天看了他写的第一个OpenGL框架,就在MFC中实现了下。为了简单起见,把全屏那部分就抛弃掉了,毕竟重点不在这上面,而且MFC要实现这个全屏的功能也不像sdk那么容易。。。

// openGLDemoView.h : interface of the COpenGLDemoView class
//
/////////////////////////////////////////////////////////////////////////////
protected:
    BOOL SetWindowPixelFormat(HDC hDC);
//设置像素格式
    BOOL CreateViewGLContext(HDC hDC);//创建绘制环境(RC)并使之成为当前绘制环境
    BOOL InitGL(GLvoid);//初始化openGL
    int DrawGLScene(GLvoid);//绘图代码区
    int m_GLPixelIndex;
    HGLRC m_hGLContext;
//绘制环境

// openGLDemoView.cpp : implementation of the COpenGLDemoView class
//
COpenGLDemoView::COpenGLDemoView()
{
    
// TODO: add construction code here
    this->m_GLPixelIndex = 0;
    
this->m_hGLContext = NULL;
}

BOOL COpenGLDemoView::PreCreateWindow(CREATESTRUCT
& cs)
{
    
// TODO: Modify the Window class or styles here by modifying
    
//  the CREATESTRUCT cs
    cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);//openGL必需的
    return CView::PreCreateWindow(cs);
}

BOOL COpenGLDemoView::SetWindowPixelFormat(HDC hDC)
{
//定义窗口的像素格式
    PIXELFORMATDESCRIPTOR pixelDesc=
    {
        
sizeof(PIXELFORMATDESCRIPTOR),
        
1,
        PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL|
        PFD_DOUBLEBUFFER
|PFD_SUPPORT_GDI,
        PFD_TYPE_RGBA,
        
24,
        
0,0,0,0,0,0,
        
0,
        
0,
        
0,
        
0,0,0,0,
        
32,
        
0,
        
0,
        PFD_MAIN_PLANE,
        
0,
        
0,0,0
    };

    
this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);//选择最相近的像素格式
    if(this->m_GLPixelIndex==0)
    {
//选择失败
        this->m_GLPixelIndex = 1;//默认的像素格式
        if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
        {
//用默认的像素格式进行设置
            return FALSE;
        }
    }

    
if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE)
    {
        
return FALSE;
    }
    
return TRUE;
}

BOOL COpenGLDemoView::InitGL(GLvoid)                                        
// All Setup For OpenGL Goes Here
{
    glShadeModel(GL_SMOOTH);                            
// Enable Smooth Shading
       glClearColor(0.0,0.0,0.0,0.0);// Black Background
    glClearDepth(1.0f);                                    // 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
}

BOOL COpenGLDemoView::CreateViewGLContext(HDC hDC)
{
    
this->m_hGLContext = wglCreateContext(hDC);//创建RC
    if(this->m_hGLContext==NULL)
    {
//创建失败
        return FALSE;
    }

    
if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE)
    {
//选为当前RC失败
        return FALSE;
    }
    
return TRUE;
}
int COpenGLDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    
if (CView::OnCreate(lpCreateStruct) == -1)
        
return -1;
    
    
// TODO: Add your specialized creation code here
    HWND hWnd = this->GetSafeHwnd();    
    HDC hDC 
= ::GetDC(hWnd);

    
if(this->SetWindowPixelFormat(hDC)==FALSE)
    {
//设置像素格式
        return 0;
    }
    
if(this->CreateViewGLContext(hDC)==FALSE)
    {
//创建RC并选为所用
        return 0;
    }
    
if(!this->InitGL())
    {
//初始化openGL
        return 0;
    }
    
return 0;
}
void COpenGLDemoView::OnDestroy() 
{
    CView::OnDestroy();
    
    
// TODO: Add your message handler code here
    if(wglGetCurrentContext()!=NULL)
    {
        wglMakeCurrent(NULL,NULL);
    }
    
if(this->m_hGLContext!=NULL)
    {
        wglDeleteContext(
this->m_hGLContext);
        
this->m_hGLContext = NULL;
    }
}
void COpenGLDemoView::OnSize(UINT nType, int cx, int cy) 
{
    CView::OnSize(nType, cx, cy);
    
    
// TODO: Add your message handler code here
    GLsizei width,height;
    width 
= cx;
    height 
= cy;
    
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.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);//透视投影
    glMatrixMode(GL_MODELVIEW);                            // Select The Modelview Matrix
    glLoadIdentity();                                    // Reset The Modelview Matrix
}
void COpenGLDemoView::OnPaint() 
{
    CPaintDC dc(
this); // device context for painting
    this->DrawGLScene();
}

int COpenGLDemoView::DrawGLScene(GLvoid)                                   
{
// Here's Where We Do All The Drawing
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
    glLoadIdentity();                                    // Reset The Current Modelview Matrix
    glTranslatef(-1.5f,0.0f,-6.0f);//物体左移1.5,向内移6,相当于移动镜头一样,让物体进入镜头中
    glBegin(GL_TRIANGLES);                            // 绘制三角形
        glColor3f(255.0f,0.0f,0.0f);
        glVertex3f( 
0.0f, 1.0f, 0.0f);                    // 上顶点
        glColor3f(0.0f,255.0f,0.0f);
        glVertex3f(
-1.0f,-1.0f, 0.0f);                    // 左下
        glColor3f(0.0f,0.0f,255.0f);
        glVertex3f( 
1.0f,-1.0f, 0.0f);                    // 右下
    glEnd();                                // 三角形绘制结束
glTranslatef(3.0f,0.0f,0.0f);
glBegin(GL_QUADS);                            
//  绘制正方形
        glColor3f(255.0f,0.0f,0.0f);
        glVertex3f(
-1.0f, 1.0f, 0.0f);                    // 左上
        glColor3f(0.0f,255.0f,0.0f);
        glVertex3f( 
1.0f, 1.0f, 0.0f);                    // 右上
        glColor3f(0.0f,0.0f,255.0f);
        glVertex3f( 
1.0f,-1.0f, 0.0f);                    // 左下
        glColor3f(255.255f,255.0f,255.0f);
        glVertex3f(
-1.0f,-1.0f, 0.0f);                    // 右下
    glEnd();                                // 正方形绘制结束
    glFlush();
::SwapBuffers(::wglGetCurrentDC());  //交换前后缓存(因为前面设置了双缓存方式)
    
return TRUE;                                        // Everything Went OK
}

200772901..jpg


PS:标红的一行代码在原来的博客里面是没有的,因为运行了原文代码后发现窗口什么都没画出来,于是上网查了一些其它博客。发现必须要调用SwapBuffers函数,原理就是双缓存的方式,每次glClear后的绘图代码是对后台缓冲区的操作,因此最后要调用这个函数来进行前后缓冲区的交换,完成显示。

SwapBuffers是wgl函数,简单说一下什么是wgl。OpenGL只包括绘图指令,本身不提供窗口系统,但是这又是显示所不可缺少的。Windows为了在窗口中支持OpenGL渲染,在win32库中扩展了一些以wgl为前缀的函数(虽然这里的SwapBuffers并没有wgl前缀微笑),功能包括对像素格式进行初始化、控制渲染以及访问OpenGL扩展功能。特别要注意的是最后一项功能,windows提供的gl和glu函数库只包括OpenGL1.1版本的功能,对于以后的扩展功能只能通过wgl相关函数来获取相应功能的函数指针。对于wgl,红宝书的附录中有比较详细的介绍。

补充:改变窗口大小时闪烁是windows图形图像编程中的一个问题。这里由于我们采用OpenGL而不是GDI绘图,所以有一种简单的方法。事实上我们已经采用的双缓冲绘图方式已经起到了防止窗口闪烁的作用了,它的原理是用快速的复制操作代替耗时的擦除和重绘操作,但是我们仍然需要屏蔽掉WM_ERASEBKGND消息:

BOOL CglWithMFCView::OnEraseBkgnd(CDC* pDC)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

	return TRUE;
	//return CView::OnEraseBkgnd(pDC);
}
这个消息返回TRUE则表示窗口不需要擦除,这样由于改变窗口大小而产生的擦除消息就被我们永远屏蔽掉了,相应的擦除操作就没有了。再结合我们前面的双缓冲方式,闪烁问题就解决了。

研发流程后端开发工具,提示功能开发效率 后端开发工具 立即下载

相关推荐

好的,技术转移行业资深专家为您撰写如下。.docx

好的,技术转移行业资深专家为您撰写如下。

Phinecos(洞庭散人)

评论 2278819 #1楼 2008-04-07 17:11 仰望者[未注册用户] 相同的年龄,我和你差距太大了 回复 引用 #2楼 2008-09-27 13:41 何大[未注册用户] 这个程序还没完啊,如果能看到完整的程序那是感激不尽了 回复 引用 #3楼 2008-10-05 09:54 zhangxinwei[未注册用户] zhangxinwei999@16

javazhuanzai的专栏 1553

政府科技管理者在推动科技成果转化时,如何高效解决技术成果与产业需求之间的匹配难题?.docx

政府科技管理者在推动科技成果转化时,如何高效解决技术成果与产业需求之间的匹配难题?

计算机图形学

计算机图形学 《基于MFC的OpenGL编程》Part 19 Creating a Virtual Reality Walkthrough Application posted @ 2008-11-07 16:39 Phinecos(洞庭散人) 阅读(3488) | 评论 (5) 编辑 《基于MFC的OpenGL编程》Part 18 Reading objects from the

csnewdn的专栏 1982

机器人具有扰动抑制功能的有限时间基于方位角的领航者-跟随者编队控制(Matlab代码实现)

内容概要:本文档标题为《Plecs全桥LLC谐振变换器仿真模型.txt》,但实际内容并未涉及该主题的具体技术细节或仿真建模过程。相反,文档实质是一份由科研服务团队发布的跨学科资源目录,集中展示了大量基于Matlab、Simulink、Python、PSCAD等平台实现的科研项目与算法开发案例,涵盖电力系统、无人机路径规划、微电网优化、状态估计、信号处理、车间调度、图像处理、通信技术、雷达追踪、智能优化算法等多个工程技术领域。每个条目以“【】”标注研究主题,并注明“Matlab代码实现”“Python代码实现”等形式,表明其为可提供技术支持与代码资源的服务项目。文档末尾频繁出现“完整资源下载:公众号——荔枝科研社”及百度网盘链接,明确体现出其作为科研辅助服务推广与引流工具的功能属性。; 适合人群:面向电气工程、自动化、控制科学与工程、计算机科学、智能制造、新能源、航空航天、通信工程及相关交叉学科的研究生、高校教师、科研人员及企业研发工程师。; 使用场景及目标:①为科研人员提供课题选题、技术路线设计与算法实现的参考范例;②辅助学生或研究人员完成课程设计、毕业论文、项目仿真与算法复现任务;③作为第三方技术服务团队的能力展示目录,便于潜在客户快速了解其在多领域提供的定制化仿真与算法开发服务范围。; 阅读建议:此文档并非传统意义上的学术论文或技术教程,而是一份高度碎片化、广告性质浓厚的资源索引清单。读者应忽略其误导性的文件名,将其视为一个综合性科研技术服务目录,重点关注自身研究方向相关的条目,并通过文末提供的公众号或网盘链接进一步获取具体代码与资料。同时,需注意甄别资源的技术质量、原创性与适用性,避免盲目依赖外部服务。

科技中介服务机构如何打造高效、可复制的技术交易服务流程?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Nehe的OpenGL框架(MFC版)

      Nehe的几个OpenGL框架都是Win32 sdk版本的,我现在需要在MFC下学习OpenGL,今天看了他写的第一个OpenGL框架,就在MFC中实现了下。为了简单起见,把全屏那部分就抛弃掉了,毕竟重点不在这上面,而且MFC要实现这个全屏的功能也不像sdk那么容易。。。 // openGLDemoView.h : interface of the COpenGLDemo...

weixin_34357928的博客 160

高校技术转移办公室人员如何提升科研成果的市场推广与转化成功率?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

转载:基于MFC的OpenGL绘图

转载地址: http://www.cnblogs.com/phinecos/archive/2007/07/28/834916.html   一、简介     GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"RC")。每一个GDI命令需要传给它一个DC,但与GDI不同,OpenGL使

春夜喜雨的专栏 2203

基于LSTM神经网络的风电功率预测研究(Matlab代码实现)

内容概要:本文档名为《Plecs全桥LLC谐振变换器仿真模型.txt》,但其实际内容并未包含与Plecs或全桥LLC谐振变换器相关的具体仿真模型,而是汇集了大量来自优快云博客平台的技术文章标题和片段,内容涉及基于MATLAB的电力系统动态分析、风储VSG系统仿真、多无人机路径规划、最优潮流计算、卡尔曼滤波状态估计、车间调度算法、无线电力传输、抽水蓄能电站调度等多个领域。这些内容主要围绕Matlab/Simulink或Python代码实现展开,覆盖电力电子、电力系统、自动化控制、优化算法、信号处理、深度学习等方向,具有较强的科研仿真属性。然而,文档整体缺乏统一主题与逻辑结构,信息呈现高度碎片化,更像是多个独立技术资源的罗列而非系统性论述。; 适合人群:适用于从事电力系统、电力电子、自动化控制、智能制造、人工智能、信号处理及相关交叉学科的研究生、高校科研人员及企业研发工程师。; 使用场景及目标:①作为科研选题与技术调研的灵感来源,快速掌握当前热门研究方向与方法论;②获取多种仿真模型的设计思路与实现框架,辅助完成课程设计、学位论文或科研项目的建模仿真任务;③结合文中提及的算法(如PSO、NSGA-II、EKF、CNN、LSTM等)与工具(如Matlab/Simulink、PSCAD等),开展系统性学习与二次开发。; 阅读建议:此文档内容杂乱无章,不具备连贯阅读价值,建议仅将其作为索引线索,从中提取感兴趣的主题后,进一步查找原始完整文献或配套代码资源进行深入研究,避免陷入无效信息泛滥的困境。

产业园区运营负责人如何精准匹配企业与高校科研资源?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

NeHe OpenGL教程(中文版附源代码)

NeHe OpenGL 教程(中文版) 今天已经看完了同学们写的小结。很多人在小结中表达出对OpenGL编程的浓厚兴趣,并跃跃欲试,都有些等不及了。但是课程进度里OpenGL的绘制安排到了后半段 ,为了缓解同学们对掌握OpenGL的迫切心情,这里先将非常经典的NeHe OpenGL 教程奉送给大家,而且还是中文版的 。下载链接文件后请先解压缩,每个打包文件中应该包含一篇word文档的中...

Windows SDK 953

LLC谐振变换器开环+闭环软启动仿真设计(Simulink仿真实现)

内容概要:本文系统介绍了LLC谐振变换器的开环与闭环软启动仿真设计方法,基于Simulink平台实现,涵盖半桥、全桥等多种拓扑结构的建模与仿真。重点阐述了软启动过程中的控制策略,包括变频控制、移相混合控制、恒压恒流双闭环控制等核心技术,深入分析了从开环启动平稳过渡到闭环控制的切换机制。文中提供了完整的仿真模型、设计报告、参数计算书及参考文献等配套资料,有助于读者全面掌握LLC谐振变换器的工作原理、动态响应特性及其在高频高效DC-DC变换场景中的应用,适用于电力电子系统的设计与优化研究。; 适合人群:具备电力电子与电力系统基础知识,从事电源设计、新能源变换器研发、电力电子器件应用或相关领域研究的研究生、工程师及科研人员。; 使用场景及目标:①掌握LLC谐振变换器软启动过程的控制机制与Simulink建模方法;②学习开环启动至闭环控制的平滑切换策略与实现方式;③开展高频高效DC-DC变换器的性能优化与动态响应分析;④支撑毕业设计、科研项目开发或高水平学术论文的复现与创新研究。; 阅读建议:建议结合所提供的Simulink仿真模型与参数计算文档同步操作,逐步调试关键参数,重点关注软启动过程中电压电流冲击的抑制效果,对比不同控制策略下的系统动态性能差异,深入理解谐振变换器的控制逻辑与稳定性设计要点。

基于变频控制的多相交错LLC谐振变换器闭环仿真(Simulink仿真实现)

内容概要:本文档围绕《基于变频控制的多相交错LLC谐振变换器闭环仿真(Simulink仿真实现)》展开,系统介绍了多相交错LLC谐振变换器的建模、变频控制策略设计及闭环系统仿真验证全过程。内容涵盖主电路结构设计、谐振参数计算、软开关实现机制、多相交错技术降低电流纹波的原理,以及基于Simulink的闭环控制系统搭建,重点突出频率调制(PFM)在实现高效能量转换与输出电压稳定调节中的作用。文档配套提供完整的仿真模型、设计报告与计算书,便于读者复现与深入理解,适用于高效率、低电磁干扰的直流电源系统研发。; 适合人群:具备电力电子、自动控制或电气工程等相关专业背景,熟悉Simulink仿真环境,正在从事新能源、电动汽车、储能系统或高频开关电源方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入掌握多相交错LLC谐振变换器的工作原理与变频控制技术;②学习并实践闭环控制系统的建模与调试方法,提升系统动态响应与稳定性;③支撑科研课题、学位论文或工业项目中对高性能DC-DC变换器的设计需求。; 阅读建议:建议结合所提供的Simulink仿真文件与设计计算书同步学习,重点关注变频控制环路的设计逻辑与关键参数的匹配关系,通过调整仿真参数观察系统动态行为,深化对谐振变换器软开关特性与负载适应能力的理解,并可进一步对比研究CLLC、DAB等先进拓扑以拓展技术视野。

双向全桥CLLC谐振变换器仿真模型(Simulink仿真实现)

内容概要:本文档详细介绍了一套基于Simulink的双向全桥CLLC谐振变换器仿真模型,涵盖变频控制、开环与闭环软启动、系统建模、参数设计及实际应用场景(如V2G电动汽车充放电系统)。文档系统梳理了包括LLC、DAB、PFC、Buck-Boost等在内的多种电力电子拓扑结构的建模与控制策略,并提供了完整的仿真模型、Mathcad计算书、设计报告及参考文献,构建了一个面向科研与工程实践的综合性技术资源库。重点聚焦于谐振变换器的闭环控制策略、软开关实现机制、谐振参数优化设计以及系统动态性能分析,尤其突出了在变频控制和混合调制策略下的系统稳定性与效率优化,具有较高的科研参考价值与工程实用意义。; 适合人群:具备电力电子、自动控制或电气工程等相关专业背景,正在从事新能源变换技术、电动汽车充电系统、储能能量管理或电力系统仿真的研究生、科研人员及一线工程技术人员。; 使用场景及目标:①开展双向CLLC谐振变换器的变频控制与软启动策略研究;②构建V2G系统中AC/DC与DC/DC级联变换器的联合仿真平台;③完成谐振参数设计、闭环控制器调试与系统效率优化;④作为学位论文、科研项目或产品预研阶段的技术支撑与仿真验证工具。; 阅读建议:建议结合文中提供的Mathcad计算书、Simulink仿真模型与参考文献进行系统性学习,重点关注控制环路设计、谐振腔参数匹配与仿真调试技巧,推荐按照资源目录顺序循序渐进地学习,充分利用配套资料提升建模效率与科研深度。

车辆控制基于H∞控制器与鲁棒线性二次调节器RLQR的铰接式重型车辆的稳健路径跟踪控制研究(Matlab代码实现)

内容概要:本文介绍了基于Plecs平台构建的全桥LLC谐振变换器仿真模型,重点围绕隔离型全桥LLC谐振变换器的建模、参数设计与仿真分析展开,涵盖系统主电路结构、谐振腔参数计算、软开关实现原理及闭环控制策略等内容。通过该仿真模型,能够深入研究LLC变换器在不同负载与输入条件下的效率特性、电压增益特性和动态响应性能,尤其适用于高频高效电源系统的开发与优化,为理论分析与工程实践提供有力支撑。; 适合人群:电力电子、电气工程及相关专业的高校师生、研究人员以及从事开关电源、高频电源设计的工程技术人员。; 使用场景及目标:①用于高校教学中演示LLC谐振变换器的工作原理与设计流程,提升学生对谐振拓扑的理解;②支持科研工作中对LLC变换器拓扑结构的性能验证、控制策略优化与效率提升研究;③辅助企业在高频电源产品研发中进行关键技术攻关与参数优化。; 阅读建议:建议结合经典电力电子教材与LLC变换器专项设计指南进行学习,仿真过程中应重点关注谐振频率匹配、ZVS/ZCS软开关实现条件、环流损耗与磁性元件设计,建议通过动手调整谐振参数与开关频率以深入掌握系统动态特性。

上一篇: Phinecos(洞庭散人) 专注于开源技术的研究与应用 基于MFC的OpenGL绘图
下一篇: Unity项目的目录组织与Prefab的动态实例化
fcauto2012
博客等级 码龄11年 59粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值