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

📄 rendertexture.cpp

📁 PDE simulator on GPU.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
// File : RenderTexture.cpp
//------------------------------------------------------------------------------
// Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its 
// documentation for any purpose is hereby granted without fee, provided that 
// the above copyright notice appear in all copies and that both that copyright 
// notice and this permission notice appear in supporting documentation. 
// Binaries may be compiled with this software without any royalties or 
// restrictions. 
//
// The author(s) and The University of North Carolina at Chapel Hill make no 
// representations about the suitability of this software for any purpose. 
// It is provided "as is" without express or implied warranty.
/**
* @file RenderTexture.cpp
* 
* Implementation of class RenderTexture.  A multi-format render to 
* texture wrapper.
*/
#include "stdafx.h"
#include "Shadow.h"

#include "RenderTexture.h"
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

//------------------------------------------------------------------------------
// Function     	  : RenderTexture::RenderTexture
// Description	    : 
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::RenderTexture()
* @brief Constructor.
*/ 
RenderTexture::RenderTexture(int iWidth, int iHeight, bool bIsTexture /* = true */,
							 bool bIsDepthTexture /* = false */)
							 : _iWidth(iWidth), 
							 _iHeight(iHeight), 
							 _bIsTexture(bIsTexture),
							 _bIsDepthTexture(bIsDepthTexture),
							 _eUpdateMode(RT_RENDER_TO_TEXTURE),
							 _bInitialized(false),
							 _bFloat(false),
							 _bRectangle(false),
							 _bHasDepth(false),
							 _bHasStencil(false),
							 _bMipmap(false),
							 _bAnisoFilter(false),
							 _hDC(NULL), 
							 _hGLContext(NULL), 
							 _hPBuffer(NULL),
							 _hPreviousDC(0),
							 _hPreviousContext(0),
							 _iTextureTarget(GL_NONE),
							 _iTextureID(0)
{
	assert(iWidth > 0 && iHeight > 0);
	_iBits[0] = _iBits[1] = _iBits[2] = _iBits[3] = 0;
}


//------------------------------------------------------------------------------
// Function     	  : RenderTexture::~RenderTexture
// Description	    : 
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::~RenderTexture()
* @brief Destructor.
*/ 
RenderTexture::~RenderTexture()
{
	_Invalidate();
}

// Check to see if the pbuffer was lost.
// If it was lost, destroy it and then recreate it.
void RenderTexture::HandleModeSwitch()
{
    int lost = 0;
	
    wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_LOST_ARB, &lost );
	
    if ( lost )
    {
        this->~RenderTexture();
        Initialize();
    }
}

//------------------------------------------------------------------------------
// Function     	  : wglGetLastError
// Description	    : 
//------------------------------------------------------------------------------
/**
* @fn wglGetLastError()
* @brief Returns the last windows error generated.
*/ 
void RenderTexture::_wglGetLastError()
{
#ifdef _DEBUG
	
	DWORD err = GetLastError();
	switch(err)
	{
	case ERROR_INVALID_PIXEL_FORMAT:
		fprintf(stderr, "Win32 Error:  ERROR_INVALID_PIXEL_FORMAT\n");
		break;
	case ERROR_NO_SYSTEM_RESOURCES:
		fprintf(stderr, "Win32 Error:  ERROR_NO_SYSTEM_RESOURCES\n");
		break;
	case ERROR_INVALID_DATA:
		fprintf(stderr, "Win32 Error:  ERROR_INVALID_DATA\n");
		break;
	case ERROR_INVALID_WINDOW_HANDLE:
		fprintf(stderr, "Win32 Error:  ERROR_INVALID_WINDOW_HANDLE\n");
		break;
	case ERROR_RESOURCE_TYPE_NOT_FOUND:
		fprintf(stderr, "Win32 Error:  ERROR_RESOURCE_TYPE_NOT_FOUND\n");
		break;
	case ERROR_SUCCESS:
		// no error
		break;
	default:
		LPVOID lpMsgBuf;
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			err,
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(LPTSTR) &lpMsgBuf,
			0,
			NULL);
		
		fprintf(stderr, "Win32 Error %d: %s\n", err, lpMsgBuf);
		LocalFree( lpMsgBuf );
		break;
	}
	SetLastError(0);
	
#endif // _DEBUG
}


//------------------------------------------------------------------------------
// Function     	  : PrintExtensionError
// Description	    : 
//------------------------------------------------------------------------------
/**
* @fn PrintExtensionError( char* strMsg, ... )
* @brief Prints an error about missing OpenGL extensions.
*/ 
void PrintExtensionError( char* strMsg, ... )
{
	fprintf(stderr, "Error: RenderTexture requires the following unsupported "
		"OpenGL extensions: \n");
	char strBuffer[512];
	va_list args;
	va_start(args, strMsg);
	_vsnprintf( strBuffer, 512, strMsg, args );
	va_end(args);
	
	fprintf(stderr, strMsg);
}


//------------------------------------------------------------------------------
// 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     	  : RenderTexture::Initialize
// Description	    : 
//------------------------------------------------------------------------------
/**
* @fn RenderTexture::Initialize(bool bShare, bool bDepth, bool bStencil, bool bMipmap, bool bAnisoFilter, unsigned int iRBits, unsigned int iGBits, unsigned int iBBits, unsigned int iABits);
* @brief Initializes the RenderTexture, sharing display lists and textures if specified.
* 
* This function actually does the creation of the p-buffer.  It can only be called 
* once a GL context has already been created.  Note that if the texture is not
* power of two dimensioned, or has more than 8 bits per channel, enabling mipmapping
* or aniso filtering will cause an error.
*/ 
bool RenderTexture::Initialize(bool         bShare       /* = false */, 
                               bool         bDepth       /* = false */, 
                               bool         bStencil     /* = false */, 
                               bool         bMipmap      /* = false */, 
                               bool         bAnisoFilter /* = false */,
                               unsigned int iRBits       /* = 8 */, 
                               unsigned int iGBits       /* = 8 */, 
                               unsigned int iBBits       /* = 8 */, 
                               unsigned int iABits       /* = 8 */,
                               UpdateMode   updateMode   /* = RT_RENDER_TO_TEXTURE */)
{ 
	if (!extgl_Extensions.wgl.ARB_pbuffer)
	{
		PrintExtensionError("WGL_ARB_pbuffer");
		return false;
	}
	if (!extgl_Extensions.wgl.ARB_pixel_format)
	{
		PrintExtensionError("WGL_ARB_pixel_format");
		return false;
	}
	if (_bIsTexture && !extgl_Extensions.wgl.ARB_render_texture)
	{
		PrintExtensionError("WGL_ARB_render_texture");
		return false;
	}
	if (_bIsDepthTexture && !extgl_Extensions.ARB_depth_texture)
	{
		PrintExtensionError("GL_ARB_depth_texture");
		return false;
	}
	SetLastError(0);
	
	if (_bInitialized)
		_Invalidate();
	
	_bFloat       = (iRBits > 8 || iGBits > 8 || iBBits > 8 || iABits > 8);
	
	bool bNVIDIA = true;
	
	if (_bFloat && !extgl_Extensions.NV_float_buffer)
	{
		bNVIDIA = false;
		if (!extgl_Extensions.wgl.ATI_pixel_format_float)
		{
			PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
			return false;
		}
	}
	if (_bFloat && _bIsTexture && !bNVIDIA && !extgl_Extensions.ATI_texture_float)
	{
		PrintExtensionError("NV_float_buffer or ATI_texture_float");
	}
	if (!_bFloat && !extgl_Extensions.NV_texture_rectangle)
	{
		bNVIDIA = false;
	}
	
	_bRectangle   = _bFloat && bNVIDIA;
	
	if(_bIsDepthTexture)
		_bHasDepth  = true;    // we need depth for a depth texture...
	else
		_bHasDepth  = bDepth;
	
	_bHasStencil  = bStencil;
	_bMipmap      = false;   // until it is enabled.
	_bAnisoFilter = false;   // until it is enabled.
	_eUpdateMode  = updateMode;
	
	GLuint iWGLTextureTarget;
	GLuint iBindTarget;
	GLuint iTextureFormat;
	GLuint iDepthBindTarget;
	GLuint iDepthTextureFormat;
	
	if (_bIsTexture)
		glGenTextures(1, &_iTextureID);
	if (_bIsDepthTexture)
		glGenTextures(1, &_iDepthTextureID);
	
	// Determine the appropriate texture formats and filtering modes.
	if (_bIsTexture)
	{
		if (_bFloat)
		{      
			if (!bNVIDIA && !(IsPowerOfTwo(_iWidth) && IsPowerOfTwo(_iHeight)))
			{
				fprintf(stderr, 
					"RenderTexture Error: ATI textures must be power-of-two-dimensioned.\n");
				return false;
			}
			
			if (bNVIDIA)
				_iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
			else
				_iTextureTarget = GL_TEXTURE_2D;
			
			glBindTexture(_iTextureTarget, _iTextureID);  
			
			// We'll use clamp to edge as the default texture wrap mode for all tex types
			glTexParameteri( _iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri( _iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
			glTexParameteri( _iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri( _iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			
			if (bMipmap)
			{
				fprintf(stderr, 
					"RenderTexture Error: float textures do not support mipmaps\n");
				return false;
			}
			
			if (RT_COPY_TO_TEXTURE == _eUpdateMode)
			{
				GLuint iInternalFormat;
				GLuint iFormat;
				if (iABits > 0)
				{
					if (bNVIDIA)
						iInternalFormat = (iABits > 16) ? GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
					else
						iInternalFormat = (iABits > 16) ? GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
					iFormat = GL_RGBA;
				}
				else if (iBBits > 0)
				{
					if (bNVIDIA)
						iInternalFormat = (iBBits > 16) ? GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
					else
						iInternalFormat = (iBBits > 16) ? GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
					iFormat = GL_RGB;
				}
				else if (iGBits > 0)
				{
					if (bNVIDIA)
						iInternalFormat = (iGBits > 16) ? GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
					else
						iInternalFormat = (iGBits > 16) ? GL_LUMINANCE_ALPHA_FLOAT32_ATI : 
					GL_LUMINANCE_ALPHA_FLOAT16_ATI;
					iFormat = GL_LUMINANCE_ALPHA;
				}
				else 
				{
					if (bNVIDIA)
						iInternalFormat = (iRBits > 16) ? GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
					else
						iInternalFormat = (iRBits > 16) ? GL_LUMINANCE_FLOAT32_ATI : 
					GL_LUMINANCE_FLOAT16_ATI;
					iFormat = GL_LUMINANCE;
				}
				// Allocate the texture image (but pass it no data for now).
				glTexImage2D(_iTextureTarget, 0, iInternalFormat, _iWidth, _iHeight, 
					0, iFormat, GL_FLOAT, NULL);
			}
			else
			{ 
				if (bNVIDIA)
					iWGLTextureTarget = WGL_TEXTURE_RECTANGLE_NV;
				else
					iWGLTextureTarget = WGL_TEXTURE_2D_ARB;
				
				if (iABits > 0) 
				{ 
					if (bNVIDIA)
					{
						iBindTarget    = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV;  

⌨️ 快捷键说明

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