《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows

本文详细介绍如何在MFC SDI应用程序中集成OpenGL,包括下载所需文件、设置开发环境、实现像素格式、绘制上下文及设备上下文等关键步骤。

源代码下载:OpenGL_ch2.rar

WGL – Windows OpenGL扩展层

The WGL extension consists of a set of functions (wglCreateContext, wglDeleteContext etc.) and structures (such as PIXELFORMATDESCRIPTOR, GLYPHMETRICSFLOAT) etc. Thus every OpenGL implementation has a platform-specific portion which has to be set up and used according to the particular platform.

设备上下文

The Windows Graphical Device Interface (GDI) is capable of drawing to screen, to memory, to printers or to any other device that provides a GDI interface layer and that can process GDI calls. GDI accomplishes this by a rendering handle to the currently selected device, which is called the device context, or DC.

绘制上下文

A rendering context is the OpenGL equivalent of the GDI DC. All OpenGL calls are rendered to the device through a RC. The rendering context maintains OpenGL state variables such as current background color, current color etc. just as the DC maintains GDI state variables such as current pen, current brush etc.

像素格式

Pixel formats are the translation layer between OpenGL calls and the rendering operation that Windows performs.

举个例子,若像素格式只支持很少一部分颜色值,则OpenGL在用RGB(128,120,135)绘制一个像素时,就可能使用转换后的值(128,128,128)来绘制.

The pixel format selected essentially describes such things as how colors are displayed, depth of field resolution and what additional capabilities are supported by the rendering context created.

第一个基于MFCOpenGL应用程

开发环境:VC6.0

1, 首先下载需要的GLUT头文件,DLLLib文件,下载链接: glutdlls37beta.zip (149 kilobytes),解压缩后把gltu.h放到"VC98/Include/GL"下,把glut.libglut32.lib放到"VC9/Lib" 下glut32.dllglut.dll放到你创建的应用程序的运行目录下

2, 创建一个MFC SDI应用程序,在项目属性中加入所需要链接的库文件

1, stdafx.h中加入下列语句:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // OpenGLHeaders

#include
< gl/ gl.h>

#include
< gl/ glu.h>

#include
< gl/ glut.h>

#include
< gl/ glaux.h>

2, 打开ClassWizard,选择CCY457OpenGLView类,为下述消息加入消息处理函数:WM_CREATE (for OnCreate), WM_DESTROY (for OnDestroy), WM_SIZE (for OnSize), WM_ERASEBACKGROUND (for OnEraseBkground).

3,在窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> BOOLCCY457OpenGLView::PreCreateWindow(CREATESTRUCT & cs)
{
// TODO:ModifytheWindowclassorstylesherebymodifying
// theCREATESTRUCTcs
// AnOpenGLWindowmustbecreatedwiththefollowingflags
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
return CView::PreCreateWindow(cs);
}

4,CCY457OpenGLView.h中加入如下语句:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> HGLRCm_hRC; // RenderingContext
CDC * m_pDC; // DeviceContext
BOOLInitializeOpenGL(); // InitializeOpenGL
BOOLSetupPixelFormat(); // SetupthePixelFormat
void RenderScene(); // RendertheScene

5,OnCreate中我们将通过建立像素格式和绘制上下文来初始化OpenGL.InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC,然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> int CCY457OpenGLView::OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == - 1 )
return - 1 ;
// InitializeOpenGLHere
InitializeOpenGL();
return 0 ;
}

BOOLCCY457OpenGLView::InitializeOpenGL()
{
// GetaDCfortheClientArea
m_pDC = new CClientDC( this );
// FailuretoGetDC
if (m_pDC == NULL)
{
MessageBox(
" ErrorObtainingDC " );
return FALSE;
}
// Failuretosetthepixelformat
if ( ! SetupPixelFormat())
{
return FALSE;
}
// CreateRenderingContext
m_hRC = ::wglCreateContext(m_pDC -> GetSafeHdc());
// FailuretoCreateRenderingContext
if (m_hRC == 0 )
{
MessageBox(
" ErrorCreatingRC " );
return FALSE;
}
// MaketheRCCurrent
if (::wglMakeCurrent(m_pDC -> GetSafeHdc(),m_hRC) == FALSE)
{
MessageBox(
" ErrormakingRCCurrent " );
return FALSE;
}
// SpecifyBlackastheclearcolor
::glClearColor( 0.0f , 0.0f , 0.0f , 0.0f );
// Specifythebackofthebufferascleardepth
::glClearDepth( 1.0f );
// EnableDepthTesting
::glEnable(GL_DEPTH_TEST);
return TRUE;
}
// SetupPixelFormat
/////////////////////////////////////////////////////////////////////////// //
BOOLCCY457OpenGLView::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTORpfd =
{
sizeof (PIXELFORMATDESCRIPTOR), // sizeofthispfd
1 , // versionnumber
PFD_DRAW_TO_WINDOW | // supportwindow
PFD_SUPPORT_OPENGL | // supportOpenGL
PFD_DOUBLEBUFFER, // doublebuffered
PFD_TYPE_RGBA, // RGBAtype
24 , // 24-bitcolordepth
0 , 0 , 0 , 0 , 0 , 0 , // colorbitsignored
0 , // noalphabuffer
0 , // shiftbitignored
0 , // noaccumulationbuffer
0 , 0 , 0 , 0 , // accumbitsignored
16 , // 16-bitz-buffer
0 , // nostencilbuffer
0 , // noauxiliarybuffer
PFD_MAIN_PLANE, // mainlayer
0 , // reserved
0 , 0 , 0 // layermasksignored
};
int m_nPixelFormat = ::ChoosePixelFormat(m_pDC -> GetSafeHdc(), & pfd);
if (m_nPixelFormat == 0 )
{
return FALSE;
}
if (::SetPixelFormat(m_pDC -> GetSafeHdc(),m_nPixelFormat, & pfd) == FALSE)
{
return FALSE;
}
return TRUE;
}

6,OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> void CCY457OpenGLView::OnSize(UINTnType, int cx, int cy)
{
CView::OnSize(nType,cx,cy);
GLdoubleaspect_ratio;
// width/heightratio

if ( 0 >= cx || 0 >= cy)
{
return ;
}
// selectthefullclientarea
::glViewport( 0 , 0 ,cx,cy);
// computetheaspectratio
// thiswillkeepalldimensionscalesequal
aspect_ratio = (GLdouble)cx / (GLdouble)cy;
// selecttheprojectionmatrixandclearit
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
// selecttheviewingvolume
::gluPerspective( 45.0f ,aspect_ratio,.01f, 200.0f );

// switchbacktothemodelviewmatrixandclearit
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();
}

7,在绘制场景时,一般包括如下步骤:1)清空缓存。2)绘制场景。3Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> void CCY457OpenGLView::OnDraw(CDC * pDC)
{
CCY457OpenGLDoc
* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Clearoutthecolor&depthbuffers
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderScene();
// TellOpenGLtoflushitspipeline
::glFinish();
// NowSwapthebuffers
::SwapBuffers(m_pDC -> GetSafeHdc());
}
void CCY457OpenGLView::RenderScene()
{
// 第一个玩具嘛,先空着,后面慢慢填
}

8,试试改变窗口的大小,你会看到很严重的闪烁,并且关闭程序后会报告内存泄露,因此我们这就来解决这两个问题吧。

发生闪烁的原因是Windows先绘制背景,然后再是OpenGL绘制,因为我们已经让OpenGL负责清空背景色,因此我们不需要Windows去清空背景了

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> BOOLCCY457OpenGLView::OnEraseBkgnd(CDC * pDC)
{
// TellWindowsnottoerasethebackground
return TRUE;
}

内存泄露的原因是我们在SetupPixelFormat()中使用了new运算符来为CClientDC对象分配内存,因此需要显示delete掉。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> void CCY457OpenGLView::OnDestroy()
{
CView::OnDestroy();
// MaketheRCnon-current
if (::wglMakeCurrent( 0 , 0 ) == FALSE)
{
MessageBox(
" CouldnotmakeRCnon-current " );
}

// Deletetherenderingcontext
if (::wglDeleteContext(m_hRC) == FALSE)
{
MessageBox(
" CouldnotdeleteRC " );
}
// DeletetheDC
if (m_pDC)
{
deletem_pDC;
}
// SetittoNULL
m_pDC = NULL;
}

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值