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

📄 pbuffer.cpp

📁 PDE simulator on GPU.
💻 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 + -