MFC自定义控件 绘画Opengl时 在光照下图形变形

c_c_yuan 2013-03-21 09:57:58
网上照抄了一个OpenGL自定义控件的代码,然后稍加修改了下,在没有光照的情况下显示的还算正常,但是添加了光照之后,就很神奇的想象了,看下图

移动摄像头的位置

移动摄像头的位置

不启用光照的效果

这只是一个普通的长方体呀,看着相当纠结的样子,是不是我自定义控件定义出错了呀?求指点呀!!!
以下是相应的代码

[code=c]#include "StdAfx.h"
#include "OpenglCwnd.h"
#include <math.h>
#include "BHDBridgeSection.h"
IMPLEMENT_DYNAMIC(COpenglCwnd, CWnd)

COpenglCwnd::COpenglCwnd(void)
{
//注册控件类
RegisterCwndClass();
m_pDC = NULL;
m_hRC = NULL;
m_glfGridUnit = 1;

//出事颜色表
m_clrBackgroud = RGB(0xCA, 0xE1, 0xFF);
//设置摄像机坐标/视点
m_glfViewPosX = 2;
m_glfViewPosY = 15;
m_glfViewPosZ = 20;

//设置摄像机朝向/观察点
m_glfTargetPosX = 0;
m_glfTargetPosY = 0;
m_glfTargetPosZ = -10;

//设置摄像机法向量
m_glfCamDirectX = 0;
m_glfCamDirectY = 1;
m_glfCamDirectZ = 0;

csize = 2.5f;
islager = false;
sensor = NULL;
}

COpenglCwnd::~COpenglCwnd(void)
{
}

void COpenglCwnd::RegisterCwndClass()
{
HINSTANCE hInstance = AfxGetInstanceHandle();
WNDCLASS wndclsCtrl;
ZeroMemory(&wndclsCtrl, sizeof(WNDCLASS));
if(::GetClassInfo(hInstance, CWNDOPNEGL_CLASS_NAME, &wndclsCtrl))
return;

// 设置控件类信息
wndclsCtrl.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclsCtrl.lpfnWndProc = ::DefWindowProc;
wndclsCtrl.cbClsExtra = 0;
wndclsCtrl.cbWndExtra = 0;
wndclsCtrl.hInstance = hInstance;
wndclsCtrl.hIcon = NULL;
wndclsCtrl.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
wndclsCtrl.hbrBackground= NULL;
wndclsCtrl.lpszMenuName = NULL;
wndclsCtrl.lpszClassName= CWNDOPNEGL_CLASS_NAME;

//注册控件类
AfxRegisterClass(&wndclsCtrl);
}

void COpenglCwnd::SetSceneSize(GLsizei glsWidth, GLsizei glsHeight)
{
if (glsHeight == 0 || glsWidth == 0)
{
//ccyuan==error
return;
}
float fRationWH;
fRationWH = float(glsWidth)/glsHeight;
glViewport(0, 0, glsWidth, glsHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(35.0f, fRationWH, 0.01f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDrawBuffer(GL_BACK);

// Lights, material properties
GLfloat ambientProperties[] = {0.2f, 0.2f, 0.2f, 1.0f};
GLfloat diffuseProperties[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat specularProperties[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat light_position[] = {0.0f, 0.0f, 1.0f, 0.0f};

glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties);
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties);
glLightfv( GL_LIGHT0, GL_SPECULAR, specularProperties);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

// Default : lighting
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuseProperties);

glEnable(GL_DEPTH_TEST);
}

void COpenglCwnd::InitOpenGL()
{
GLuint glnPixelFormat;

static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};

//设置设备环境
m_pDC = GetDC();
glnPixelFormat = ChoosePixelFormat(m_pDC->m_hDC, &pfd);
SetPixelFormat(m_pDC->m_hDC, glnPixelFormat, &pfd);
m_hRC = wglCreateContext(m_pDC->m_hDC);
wglMakeCurrent(m_pDC->m_hDC, m_hRC);

//设置渲染环境

glClearColor(float(GetRValue(m_clrBackgroud)/255), float(GetGValue(m_clrBackgroud)/255), float(GetBValue(m_clrBackgroud)/255), 0.5f);
glShadeModel(GL_SMOOTH);
//
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void COpenglCwnd::RenderScene()
{

//绘背景色
//glClearColor(float(GetRValue(m_clrBackgroud))/255, float(GetGValue(m_clrBackgroud))/255, float(GetBValue(m_clrBackgroud))/255, 0.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//设置场景坐标系
glLoadIdentity();
//设置观察点
gluLookAt(m_glfViewPosX, m_glfViewPosY, m_glfViewPosZ, m_glfTargetPosX, m_glfTargetPosY, m_glfTargetPosZ, m_glfCamDirectX, m_glfCamDirectY, m_glfCamDirectZ);
// gluLookAt(3,15,20,0,0,-10, 0,1,0);

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
glColor3f(0.0f, 1.0f, 1.0f);
glTranslatef(-8.0f, 0.0f,0.0f);
// glutSolidCube(8.0f);
glBegin(GL_QUADS);
//front
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, -4.0f, 0.0f);
glVertex3f( 1.0f, -4.0f, 0.0f);
glVertex3f( 1.0f, -2.0f, 0.0f);
glVertex3f(-1.0f, -2.0f, 0.0f);
//right
glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, -4.0f, -20.0f);
glVertex3f(1.0f, -2.0f, -20.0f);
glVertex3f(1.0f, -2.0f, 0.0f);
glVertex3f(1.0f, -4.0f, 0.0f);
//back
glNormal3f(0.0f, 0.0f, -1.0f);
glVertex3f(-1.0f, -4.0f, -20.0f);
glVertex3f(-1.0f, -2.0f, -20.0f);
glVertex3f( 1.0f, -2.0f, -20.0f);
glVertex3f( 1.0f, -4.0f, -20.0f);
//left
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, -4.0f, 0.0f);
glVertex3f(-1.0f, -2.0f, 0.0f);
glVertex3f(-1.0f, -2.0f, -20.0f);
glVertex3f(-1.0f, -4.0f, -20.0f);
//up
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -2.0f, 0.0f);
glVertex3f( 1.0f, -2.0f, 0.0f);
glVertex3f( 1.0f, -2.0f, -20.0f);
glVertex3f(-1.0f, -2.0f, -20.0f);
//down
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, -4.0f, 0.0f);
glVertex3f(-1.0f, -4.0f, -20.0f);
glVertex3f( 1.0f, -4.0f, -20.0f);
glVertex3f( 1.0f, -4.0f, 0.0f);
glEnd();

}

BEGIN_MESSAGE_MAP(COpenglCwnd, CWnd)
ON_WM_PAINT()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

void COpenglCwnd::PreSubclassWindow()
{
DWORD dwStyle, dwStyleEx;
CRect rectCtrl;

dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
dwStyleEx = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
dwStyleEx |= WS_EX_CLIENTEDGE;

//重设窗口风格
SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
SetWindowLong(m_hWnd, GWL_EXSTYLE, dwStyleEx);
//初始OpenGL环境
InitOpenGL();
//设置场景大小
GetClientRect(rectCtrl);
SetSceneSize(rectCtrl.Width(), rectCtrl.Height());

CWnd::PreSubclassWindow();
// SetTimer(NULL, 1, NULL);
}
void COpenglCwnd::OnPaint()
{
CRect rectClient;
CPaintDC dc(this);

//获取视图区域
GetClientRect(rectClient);
//关联DC与RC
wglMakeCurrent(m_pDC->m_hDC, m_hRC);
//绘制场景
RenderScene();
//翻页
SwapBuffers(m_pDC->m_hDC);
//释放绘图设备
wglMakeCurrent(m_pDC->m_hDC, NULL);
}

void COpenglCwnd::OnDestroy()
{
//清理绘图设备
wglMakeCurrent(m_pDC->m_hDC, NULL);
wglDeleteContext(m_hRC);

CWnd::OnDestroy();
}

void COpenglCwnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);

wglMakeCurrent(m_pDC->m_hDC, m_hRC);
SetSceneSize(cx, cy);
wglMakeCurrent(m_pDC->m_hDC, NULL);

}

void COpenglCwnd::OnTimer(UINT_PTR nIDEvent)
{

InvalidateRect(NULL,FALSE);
CWnd::OnTimer(nIDEvent);
}



BOOL COpenglCwnd::PreTranslateMessage(MSG* pMsg)
{

if(pMsg->message == WM_KEYDOWN)
{
//MessageBox(CString("ccyuan"));
switch(pMsg->wParam)
{
case VK_LEFT:
m_glfViewPosX -=1.0f;
InvalidateRect(NULL,FALSE);
return TRUE;
case VK_RIGHT:
m_glfViewPosX += 1.0f;
InvalidateRect(NULL,FALSE);
return TRUE;
case VK_UP:
m_glfViewPosY += 1.0f;
InvalidateRect(NULL,FALSE);
return TRUE;
case VK_DOWN:
m_glfViewPosY -= 1.0f;
InvalidateRect(NULL,FALSE);
return TRUE;
case VK_HOME:
m_glfViewPosZ -= 1.0f;
InvalidateRect(NULL,FALSE);
return TRUE;
case VK_END:
m_glfViewPosZ += 1.0f;
InvalidateRect(NULL,FALSE);
return TRUE;

}

}
return CWnd::PreTranslateMessage(pMsg);
}
void COpenglCwnd::OnLButtonDown(UINT nFlags, CPoint point)
{
this->SetFocus();
InvalidateRect(NULL,FALSE);
}
...全文
253 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
c_c_yuan 2013-03-21
  • 打赏
  • 举报
回复
引用 1 楼 victor_woo 的回复:
你换一个对3D支持好的显卡机器试一下
现在主要是直接绘画在Dialog上可以正常显示,但是绘画在自定义控件上就不行了,郁闷!在我机子上也是可以正常显示的,在虚拟机上运行就显示不正常了,跟上面一样。在公司的电脑上也是出现那个奇葩现象。估计是还是在自定义控件上的错误。
victor_woo 2013-03-21
  • 打赏
  • 举报
回复
你换一个对3D支持好的显卡机器试一下
victor_woo 2013-03-21
  • 打赏
  • 举报
回复
引用 2 楼 c_c_yuan 的回复:
引用 1 楼 victor_woo 的回复:你换一个对3D支持好的显卡机器试一下 现在主要是直接绘画在Dialog上可以正常显示,但是绘画在自定义控件上就不行了,郁闷!在我机子上也是可以正常显示的,在虚拟机上运行就显示不正常了,跟上面一样。在公司的电脑上也是出现那个奇葩现象。估计是还是在自定义控件上的错误。
我也在虚拟机中做OpenGL开发,虚拟机中的3D显示质量明显不如实际电脑的显示
彩阳 2013-03-21
  • 打赏
  • 举报
回复
与深度缓存有关,查一查设置深度缓存的相关代码。
内容概要:本文围绕基于三重移相控制(TPS)的双有源桥(DAB)高频隔离DC-DC变换器开展系统性研究,重点构建了其在Simulink环境下的高精度仿真模型。研究全面涵盖SPS单相移相、DPS双重重移相与TPS三重移相等多种控制策略的建模、实现与性能对比,深入分析不同模式下变换器的功率传输特性、软开关实现条件及功率回流问题,旨在提升DAB在交直流混合微电网、能量路由器、多端口柔性互联装置等场景中的转换效率与动态响应能力。通过对ZVS(零电压切换)条件的精确控制与移相角参数的优化,有效降低了开关损耗,增强了系统整体能效与运行稳定性。该仿真模型具有良好的可扩展性,适用于复杂电能转换系统的科研验证与工程开发。; 适合人群:电力电子、电气工程及其自动化等相关专业的硕士研究生、博士生、科研人员以及从事新能源变换器、柔性输配电系统设计的工程技术人员。; 使用场景及目标:①掌握双有源桥DAB变换器的基本工作原理及其在高频隔离场合的核心优势;②深入理解三重移相控制策略的设计机理、控制自由度分配及其在效率优化中的关键作用;③构建并调试可用于科研论文撰写、项目申报或实际系统验证的高保真Simulink仿真模型,支撑理论分析与实验对比。; 阅读建议:建议结合MATLAB/Simulink平台进行动手实践,重点关注主电路拓扑搭建、移相控制模块设计、驱动信号序配置及ZVS实现条件的仿真观测,推荐通过对比SPS、DPS与TPS三种模式的稳态与动态响应曲线,深入掌握各控制策略的适用边界与优化方向。
【重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!

19,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧