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);
}
...全文
187 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
  • 打赏
  • 举报
回复
与深度缓存有关,查一查设置深度缓存的相关代码。

19,468

社区成员

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

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