📄 pbuffer.cpp
字号:
#include "stdafx.h"
#include "Shadow.h"
#include "PBuffer.h"
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
//------------------------------------------------------------------------------
// Function : IsPowerOfTwo
// Description :
//------------------------------------------------------------------------------
/**
* @fn IsPowerOfTwo(int n)
* @brief Returns true if /param n is an integer power of 2.
*
* Taken from Steve Baker's Cute Code Collection.
*/
bool IsPowerOfTwo(int n)
{
return ((n&(n-1))==0);
}
//------------------------------------------------------------------------------
// Function : CFloatPBuffer::CFloatPBuffer
// Description : Simple Version of CFloatPBuffer to Render to TEXTURE
// Usage :
// Date : 2003/11/5
// Modified By : Youquan Liu in IOS, CAS
//------------------------------------------------------------------------------
/**
* @fn CFloatPBuffer::CFloatPBuffer()
* @brief Constructor.
*/
CFloatPBuffer::CFloatPBuffer(int iWidth, int iHeight): _iWidth(iWidth), _iHeight(iHeight)
{
assert(iWidth > 0 && iHeight > 0);
}
//------------------------------------------------------------------------------
// Function : CFloatPBuffer::~CFloatPBuffer
// Description :
//------------------------------------------------------------------------------
CFloatPBuffer::~CFloatPBuffer()
{
if ( _hPBuffer )
{
// Check if we are currently rendering in the pbuffer
if (wglGetCurrentContext() == _hGLContext)
wglMakeCurrent(0,0);
wglDeleteContext( _hGLContext);
wglReleasePbufferDCARB( _hPBuffer, _hDC);
wglDestroyPbufferARB( _hPBuffer );
_hPBuffer = 0;
}
}
//------------------------------------------------------------------------------
// Function : CFloatPBuffer::~CFloatPBuffer
// Description : Check to see if the pbuffer was lost.
// If it was lost, destroy it and then recreate it.
//------------------------------------------------------------------------------
void CFloatPBuffer::HandleModeSwitch()
{
int lost = 0;
wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_LOST_ARB, &lost );
if ( lost )
{
this->~CFloatPBuffer();
Initialize();
}
}
bool CFloatPBuffer::Initialize()
{
// Get the current context.
//HDC hdc = wglGetCurrentDC();
//HGLRC hglrc = wglGetCurrentContext();
// cache the current context so we can reset it when EndCapture() is called.
_hPreviousDC = wglGetCurrentDC();
_hPreviousContext = wglGetCurrentContext();
int iFormat = 0;
unsigned int iNumFormats;
int attribChooseList[50];
int attribCreateList[50];
int attribChoose = 0;
int attribCreate = 0;
attribChooseList[attribChoose++] = WGL_DRAW_TO_PBUFFER_ARB;
attribChooseList[attribChoose++] = true;
attribChooseList[attribChoose++] = WGL_ACCELERATION_ARB;
attribChooseList[attribChoose++] = WGL_FULL_ACCELERATION_ARB;
attribChooseList[attribChoose++] = WGL_RED_BITS_ARB;
attribChooseList[attribChoose++] = 32;
attribChooseList[attribChoose++] = WGL_GREEN_BITS_ARB;
attribChooseList[attribChoose++] = 32;
attribChooseList[attribChoose++] = WGL_BLUE_BITS_ARB;
attribChooseList[attribChoose++] = 32;
attribChooseList[attribChoose++] = WGL_ALPHA_BITS_ARB;
attribChooseList[attribChoose++] = 32;
//////Add by myself
// attribChooseList[attribChoose++] = WGL_DOUBLE_BUFFER_ARB;
// attribChooseList[attribChoose++] = GL_TRUE;
attribChooseList[attribChoose++] = WGL_FLOAT_COMPONENTS_NV;
attribChooseList[attribChoose++] = GL_TRUE;
attribChooseList[attribChoose++] = WGL_STENCIL_BITS_ARB;
attribChooseList[attribChoose++] = 0;
attribChooseList[attribChoose++] = WGL_DEPTH_BITS_ARB;
attribChooseList[attribChoose++] = 8;
attribChooseList[attribChoose++] = WGL_DRAW_TO_PBUFFER_ARB;
attribChooseList[attribChoose++] = GL_TRUE;
attribChooseList[attribChoose++] = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV;
attribChooseList[attribChoose++] = GL_TRUE;
attribChooseList[attribChoose++] = 0;
attribCreateList[attribCreate++] = WGL_TEXTURE_FORMAT_ARB;
attribCreateList[attribCreate++] = WGL_TEXTURE_FLOAT_RGBA_NV;
attribCreateList[attribCreate++] = WGL_TEXTURE_TARGET_ARB;
attribCreateList[attribCreate++] = WGL_TEXTURE_RECTANGLE_NV;
attribCreateList[attribCreate++] = WGL_MIPMAP_TEXTURE_ARB;
attribCreateList[attribCreate++] = GL_FALSE;
attribCreateList[attribCreate++] = WGL_PBUFFER_LARGEST_ARB;
attribCreateList[attribCreate++] = GL_FALSE;
attribCreateList[attribCreate++] = 0;
if (!wglChoosePixelFormatARB( _hPreviousDC, attribChooseList, NULL, 1, &iFormat, &iNumFormats))
{
AfxMessageBox( "CFloatPBuffer::Initialize() creation error: wglChoosePixelFormatARB() failed.\n");
return false;
}
if ( iNumFormats <= 0 )
{
AfxMessageBox( "CFloatPBuffer::Initialize() creation error: Couldn't find a suitable pixel format.\n");
return false;
}
// Create the p-buffer.
_hPBuffer = wglCreatePbufferARB( _hPreviousDC, iFormat, _iWidth, _iHeight, attribCreateList );
if (!_hPBuffer)
{
AfxMessageBox( "CFloatPBuffer::Initialize() pbuffer creation error: wglCreatePbufferARB() failed\n");
return false;
}
// Get the device context.
_hDC = wglGetPbufferDCARB( _hPBuffer);
if ( !_hDC )
{
AfxMessageBox( "CFloatPBuffer::Initialize() creation error: wglGetGetPbufferDCARB() failed\n");
return false;
}
// Create a gl context for the p-buffer.
_hGLContext = wglCreateContext( _hDC );
if ( !_hGLContext )
{
AfxMessageBox( "CFloatPBuffer::Initialize() creation error: wglCreateContext() failed\n");
return false;
}
// Share lists, texture objects, and program objects.
if( !wglShareLists(_hPreviousContext, _hGLContext) )
{
AfxMessageBox( "CFloatPBuffer::Initialize() creation error: wglShareLists() failed\n" );
return false;
}
// Determine the actual width and height we were able to create.
wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
_bInitialized = true;
return true;
}
//------------------------------------------------------------------------------
// Function : CFloatPBuffer::BeginCapture
// Description : brief Activates rendering to the CFloatPBuffer.
//------------------------------------------------------------------------------
bool CFloatPBuffer::BeginCapture()
{
// release the pbuffer from the render texture object
if (FALSE == wglReleaseTexImageARB(_hPBuffer, WGL_FRONT_LEFT_ARB))
{
AfxMessageBox( "CFloatPBuffer::BeginCapture() creation error: wglReleaseTexImageARB() failed\n" );
return false;
}
// make the pbuffer's rendering context current.
if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
{
AfxMessageBox( "CFloatPBuffer::BeginCapture() creation error: wglMakeCurrent() failed\n" );
return false;
}
return true;
}
//------------------------------------------------------------------------------
// Function : CFloatPBuffer::EndCapture
// Description : brief Ends rendering to the CFloatPBuffer.
//------------------------------------------------------------------------------
bool CFloatPBuffer::EndCapture()
{
// make the previous rendering context current
if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
{
AfxMessageBox( "CFloatPBuffer::EndCapture() creation error: wglMakeCurrent() failed\n" );
return false;
}
// bind the pbuffer to the render texture object
//glBindTexture(_iTextureTarget, _iTextureID);
if (FALSE == wglBindTexImageARB(_hPBuffer, WGL_FRONT_LEFT_ARB))
{
AfxMessageBox( "CFloatPBuffer::EndCapture() creation error: wglBindTexImageARB() failed\n" );
return false;
}
return true;
}
void CFloatPBuffer::Activate()
{
wglMakeCurrent( _hDC, _hGLContext);
}
void CFloatPBuffer::InActivate()
{
wglMakeCurrent( _hPreviousDC, _hPreviousContext);
}
CFloatPBuffer *resultBuffer;
CFloatPBuffer *pbuffer[10];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -