246 lines
6.1 KiB
C++
246 lines
6.1 KiB
C++
/*=============================================================================
|
|
GLPBuffer.cpp : implementation of the NVidia Pixel Buffers.
|
|
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
|
|
|
Revision history:
|
|
* Created by Honich Andrey
|
|
|
|
=============================================================================*/
|
|
|
|
#include "RenderPCH.h"
|
|
#include "GL_Renderer.h"
|
|
#include "GLPBuffer.h"
|
|
|
|
|
|
CPBuffer::CPBuffer( int w, int h, unsigned int mode ) : m_Width(w), m_Height(h), m_Mode(mode), m_MyDC(NULL), m_MyGLctx(NULL), m_Buffer(NULL)
|
|
{
|
|
}
|
|
|
|
CPBuffer::~CPBuffer()
|
|
{
|
|
if (m_Buffer)
|
|
{
|
|
pwglDeleteContext(m_MyGLctx);
|
|
wglReleasePbufferDCARB(m_Buffer, m_MyDC);
|
|
wglDestroyPbufferARB(m_Buffer);
|
|
}
|
|
}
|
|
|
|
// Check to see if the pbuffer was lost.
|
|
// If it was lost, destroy it and then recreate it.
|
|
void CPBuffer::mfHandleModeSwitch()
|
|
{
|
|
int lost = 0;
|
|
|
|
wglQueryPbufferARB(m_Buffer, WGL_PBUFFER_LOST_ARB, &lost);
|
|
|
|
if ( lost )
|
|
{
|
|
this->~CPBuffer();
|
|
mfInitialize();
|
|
}
|
|
}
|
|
|
|
// This function actually does the creation of the p-buffer.
|
|
// It can only be called once a window has already been created.
|
|
bool CPBuffer::mfInitialize(bool bShare)
|
|
{
|
|
HDC hdc = pwglGetCurrentDC();
|
|
HGLRC hglrc = pwglGetCurrentContext();
|
|
|
|
// Query for a suitable pixel format based on the specified mode.
|
|
int iattributes[2*MAX_ATTRIBS];
|
|
float fattributes[2*MAX_ATTRIBS];
|
|
int nfattribs = 0;
|
|
int niattribs = 0;
|
|
|
|
// Attribute arrays must be "0" terminated - for simplicity, first
|
|
// just zero-out the array entire, then fill from left to right.
|
|
for ( int a = 0; a < 2*MAX_ATTRIBS; a++ )
|
|
{
|
|
iattributes[a] = 0;
|
|
fattributes[a] = 0;
|
|
}
|
|
|
|
// Since we are trying to create a pbuffer, the pixel format we
|
|
// request (and subsequently use) must be "p-buffer capable".
|
|
iattributes[2*niattribs ] = WGL_DRAW_TO_PBUFFER_ARB;
|
|
iattributes[2*niattribs+1] = true;
|
|
niattribs++;
|
|
|
|
if (m_Mode & FPB_DRAWTOTEXTURE)
|
|
{
|
|
iattributes[2*niattribs ] = WGL_BIND_TO_TEXTURE_RGB_ARB;
|
|
iattributes[2*niattribs+1] = true;
|
|
niattribs++;
|
|
}
|
|
else
|
|
{
|
|
if ( m_Mode & FPB_INDEX )
|
|
{
|
|
iattributes[2*niattribs ] = WGL_PIXEL_TYPE_ARB;
|
|
iattributes[2*niattribs+1] = WGL_TYPE_COLORINDEX_ARB; // Yikes!
|
|
niattribs++;
|
|
}
|
|
else
|
|
{
|
|
iattributes[2*niattribs ] = WGL_PIXEL_TYPE_ARB;
|
|
iattributes[2*niattribs+1] = WGL_TYPE_RGBA_ARB;
|
|
niattribs++;
|
|
}
|
|
|
|
if ( m_Mode & FPB_DOUBLE )
|
|
{
|
|
iattributes[2*niattribs ] = WGL_DOUBLE_BUFFER_ARB;
|
|
iattributes[2*niattribs+1] = true;
|
|
niattribs++;
|
|
}
|
|
|
|
if ( m_Mode & FPB_DEPTH )
|
|
{
|
|
iattributes[2*niattribs ] = WGL_DEPTH_BITS_ARB;
|
|
iattributes[2*niattribs+1] = 1;
|
|
niattribs++;
|
|
}
|
|
|
|
if ( m_Mode & FPB_STENCIL )
|
|
{
|
|
iattributes[2*niattribs ] = WGL_STENCIL_BITS_ARB;
|
|
iattributes[2*niattribs+1] = 1;
|
|
niattribs++;
|
|
}
|
|
|
|
if ( m_Mode & FPB_ACCUM )
|
|
{
|
|
iattributes[2*niattribs ] = WGL_ACCUM_BITS_ARB;
|
|
iattributes[2*niattribs+1] = 1;
|
|
niattribs++;
|
|
}
|
|
|
|
iattributes[2*niattribs ] = WGL_SUPPORT_OPENGL_ARB;
|
|
iattributes[2*niattribs+1] = true;
|
|
niattribs++;
|
|
}
|
|
|
|
int format;
|
|
int pformat[MAX_PFORMATS];
|
|
unsigned int nformats;
|
|
if ( !wglChoosePixelFormatARB( hdc, iattributes, fattributes, MAX_PFORMATS, pformat, &nformats ) )
|
|
{
|
|
iLog->Log("Warning: PBuffer creation error: Couldn't find a suitable pixel format.\n" );
|
|
return false;
|
|
}
|
|
format = pformat[0];
|
|
|
|
// Create the p-buffer.
|
|
iattributes[0] = 0;
|
|
niattribs = 0;
|
|
if (m_Mode & FPB_DRAWTOTEXTURE)
|
|
{
|
|
iattributes[2*niattribs ] = WGL_TEXTURE_FORMAT_ARB;
|
|
iattributes[2*niattribs+1] = WGL_TEXTURE_RGBA_ARB;
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = WGL_TEXTURE_TARGET_ARB;
|
|
iattributes[2*niattribs+1] = WGL_TEXTURE_2D_ARB;
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = WGL_MIPMAP_TEXTURE_ARB;
|
|
iattributes[2*niattribs+1] = 0;
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = WGL_PBUFFER_LARGEST_ARB;
|
|
iattributes[2*niattribs+1] = 0;
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = 0;
|
|
}
|
|
m_Buffer = wglCreatePbufferARB( hdc, format, m_Width, m_Height, iattributes );
|
|
if ( !m_Buffer )
|
|
{
|
|
DWORD err = GetLastError();
|
|
iLog->Log("Warning: PBuffer creation error: wglCreatePbufferARB() failed\n" );
|
|
if ( err == ERROR_INVALID_PIXEL_FORMAT )
|
|
{
|
|
iLog->Log("Warning: ERROR_INVALID_PIXEL_FORMAT\n" );
|
|
}
|
|
else
|
|
if ( err == ERROR_NO_SYSTEM_RESOURCES )
|
|
{
|
|
iLog->Log("Warning: ERROR_NO_SYSTEM_RESOURCES\n" );
|
|
}
|
|
else
|
|
if ( err == ERROR_INVALID_DATA )
|
|
{
|
|
iLog->Log("Warning: ERROR_INVALID_DATA\n" );
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Get the device context.
|
|
m_MyDC = wglGetPbufferDCARB( m_Buffer );
|
|
if ( !m_MyDC )
|
|
{
|
|
iLog->Log("Warning: PBuffer creation error: wglGetPbufferDCARB() failed\n" );
|
|
return false;
|
|
}
|
|
|
|
// Create a gl context for the p-buffer.
|
|
m_MyGLctx = pwglCreateContext( m_MyDC );
|
|
if ( !m_MyGLctx )
|
|
{
|
|
iLog->Log("Warning: PBuffer creation error: wglCreateContext() failed\n" );
|
|
return false;
|
|
}
|
|
|
|
if( bShare )
|
|
{
|
|
if( !pwglShareLists(hglrc, m_MyGLctx) )
|
|
{
|
|
iLog->Log("Warning: PBuffer: wglShareLists() failed\n" );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Determine the actual width and height we were able to create.
|
|
wglQueryPbufferARB( m_Buffer, WGL_PBUFFER_WIDTH_ARB, &m_Width );
|
|
wglQueryPbufferARB( m_Buffer, WGL_PBUFFER_HEIGHT_ARB, &m_Height );
|
|
|
|
#ifdef _DEBUG
|
|
iLog->Log("Created a %d x %d PBuffer\n", m_Width, m_Height );
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CPBuffer::mfMakeCurrent()
|
|
{
|
|
if ( !pwglMakeCurrent( m_MyDC, m_MyGLctx ) )
|
|
{
|
|
iLog->Log("Warning: CPBuffer::mfMakeCurrent() failed.\n" );
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CPBuffer::mfMakeMainCurrent()
|
|
{
|
|
CGLRenderer *rd = gcpOGL;
|
|
if ( !pwglMakeCurrent( rd->m_CurrContext->m_hDC, rd->m_CurrContext->m_hRC ) )
|
|
{
|
|
iLog->Log("Warning: CPBuffer::mfMakeMainCurrent() failed.\n" );
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
BOOL CPBuffer::mfTextureBind()
|
|
{
|
|
return wglBindTexImageARB(m_Buffer, WGL_FRONT_LEFT_ARB);
|
|
}
|
|
|
|
BOOL CPBuffer::mfReleaseFromTexture()
|
|
{
|
|
return wglReleaseTexImageARB(m_Buffer, WGL_FRONT_LEFT_ARB);
|
|
}
|