⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderoglwnd.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) Greg James, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Greg James, 2001"
 */
// RenderOGLWnd.cpp : implementation file
//

#include <GL/gl.h>
#include <GL/glu.h>

#include "StdAfx.h"
#include "NVEffectsBrowser.h"
#include "RenderOGLWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CRenderOGLWnd

IMPLEMENT_DYNCREATE(CRenderOGLWnd, CRenderWnd)

CRenderOGLWnd::CRenderOGLWnd()
  : m_bActive(false),
    m_bClean(false),
	m_iPixelFormat(-1),
    m_bLogoValid(false),
    m_pDC(NULL),
    m_hRC(0)
{
}

CRenderOGLWnd::~CRenderOGLWnd()
{
}


BEGIN_MESSAGE_MAP(CRenderOGLWnd, CWnd)
	//{{AFX_MSG_MAP(CRenderOGLWnd)
	ON_WM_SIZE()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_SYSKEYDOWN()
	ON_WM_SYSKEYUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRenderOGLWnd overridden methods

HRESULT CRenderOGLWnd::Init()
{
	return InitOpenGL();
}

HRESULT CRenderOGLWnd::Release()
{
	return ReleaseOpenGL();
}

HRESULT CRenderOGLWnd::UpdateDevice()
{
	return S_OK;
}

HRESULT CRenderOGLWnd::ConfirmDevice(EBEffect *pEffect)
{
	HRESULT hr = pEffect->ConfirmDevice(&m_sPFD);
    if (FAILED(hr))
        SetDefaultError(_T("This effect cannot run in this window or on this hardware."));

    return hr;
}

HRESULT CRenderOGLWnd::SetupEffect(EBEffect *pEffect)
{
	HRESULT hr;

	hr = SetDefaultRenderstates();
	if (FAILED(hr))
        return hr;

	hr = ConfirmDevice(pEffect);
	if (FAILED(hr))
        return hr;

	// Mark the context as dirty (must be replaced to reset state)
	m_bClean  = false;

	hr = pEffect->Initialize(m_hRC);
    if (FAILED(hr)) {
        SetDefaultError(_T("This effect was unable to initialize."));
        return hr;
    }

	CRect r;
	GetClientRect(r);
	pEffect->Resize(GetSafeHwnd(), r.Width(), r.Height(), true);

	return S_OK;
}

HRESULT CRenderOGLWnd::SetDefaultRenderstates()
{
	if (m_bClean)
		return S_OK;

	// Make no context current
	if (!wglMakeCurrent(NULL, NULL))
		return E_FAIL;

    // Delete the effect's RC
    if (m_hRC)
		if (wglDeleteContext(m_hRC) == false)
				return E_FAIL;
	m_hRC = NULL;
	
     
    SAFE_DELETE(m_pDC);

    m_pDC = new CClientDC(this);
    if (m_pDC == 0)
        return E_FAIL;

 	// Get a rendering context for the effect
	m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
	if (m_hRC == 0)
        return E_FAIL;

	// Make the effect context current
	if (!wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC))
		return E_FAIL;

	// Mark the context as clean
	m_bClean  = true;

    return S_OK;
}

HRESULT CRenderOGLWnd::Render(bool bDrawLogo)
{
	ASSERT(m_pDC);
	if (!m_pDC)
		return NVEFF_ERR_NOTINITIALIZED;

	// Short circuit if the window is hidden or somesuch...
	CRect r;
	GetClientRect(&r);
	CNVEffectsDoc* pDoc = GetDocument();
	if (!IsWindowVisible() ||
		(r.Width() <= 0 || r.Height() <= 0) ||
		!pDoc->IsEffectValid())
		return NVEFF_ERR_NOTINITIALIZED;

	// Call the effect
    HRESULT hr = pDoc->Tick();
    if (FAILED(hr))
        return hr;

	// Possibly draw the burned-in logo
	if (bDrawLogo && m_bLogoValid)
		DrawLogo();

	// Display the frame
	if (!SwapBuffers(m_pDC->GetSafeHdc()))
    {
        hr = RecoverSwapFailure();
        if (FAILED(hr))
            return hr;
    }
	// Update the FPS, TPS, VPS labels...
	GetRenderView()->UpdateLabels();

	return S_OK;
}

HRESULT CRenderOGLWnd::RecoverSwapFailure()
{
	if (!wglMakeCurrent(NULL, NULL))
		return E_FAIL;

    SAFE_DELETE(m_pDC);

    m_pDC = new CClientDC(this);
    if (m_pDC == 0)
        return E_FAIL;

	// Make the effect context current
	if (!wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC))
		return E_FAIL;

    return S_OK;
}

HRESULT CRenderOGLWnd::Refresh(CDC*)
{
	ASSERT(m_pDC);
	if (!m_pDC)
		return NVEFF_ERR_NOTINITIALIZED;

	if (!SwapBuffers(m_pDC->GetSafeHdc()))
    {
        HRESULT hr = RecoverSwapFailure();
        if (FAILED(hr))
            return hr;
    }

	return S_OK;
}

HRESULT CRenderOGLWnd::Clear()
{
	ASSERT(m_pDC);
	if (!m_pDC)
		return NVEFF_ERR_NOTINITIALIZED;

    // Save the clear color
    glPushAttrib(GL_COLOR_BUFFER_BIT);

    // Clear the window to the system color
    COLORREF c = GetSysColor(COLOR_3DFACE);
    float r = ((c & 0x0000ff) >>  0) / 255.0f;
    float g = ((c & 0x00ff00) >>  8) / 255.0f;
    float b = ((c & 0xff0000) >> 16) / 255.0f;

    glClearColor(r, g, b, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT);

    // Restore the clear color
    glPopAttrib();

	if (!SwapBuffers(m_pDC->GetSafeHdc()))
    {
        HRESULT hr = RecoverSwapFailure();
        if (FAILED(hr))
            return hr;
    }

	return S_OK;
}

/////////////////////////////////////////////////////////////////////////////
// CRenderOGLWnd message handlers

void CRenderOGLWnd::OnSize(UINT nType, int cx, int cy) 
{
	CRenderWnd::OnSize(nType, cx, cy);

	// Short circuit if this window is hidden
	if (!IsWindowVisible())
		return;
}

void CRenderOGLWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CRenderWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CRenderOGLWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CRenderWnd::OnKeyUp(nChar, nRepCnt, nFlags);
}

void CRenderOGLWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CRenderWnd::OnLButtonDown(nFlags, point);
}

void CRenderOGLWnd::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CRenderWnd::OnLButtonUp(nFlags, point);
}

void CRenderOGLWnd::OnMouseMove(UINT nFlags, CPoint point) 
{
	CRenderWnd::OnMouseMove(nFlags, point);
}

void CRenderOGLWnd::OnRButtonDown(UINT nFlags, CPoint point) 
{
	CRenderWnd::OnRButtonDown(nFlags, point);
}

void CRenderOGLWnd::OnRButtonUp(UINT nFlags, CPoint point) 
{
	CRenderWnd::OnRButtonUp(nFlags, point);
}

void CRenderOGLWnd::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CRenderWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
}

void CRenderOGLWnd::OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CRenderWnd::OnSysKeyUp(nChar, nRepCnt, nFlags);
}

/////////////////////////////////////////////////////////////////////////////
// CRenderOGLWnd private methods

HRESULT CRenderOGLWnd::InitOpenGL()
{
	if (m_bActive)
		return S_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -