mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-07 11:40:42 +00:00
285 lines
7.5 KiB
C++
285 lines
7.5 KiB
C++
|
|
||
|
#include "gl_pbuffer.h"
|
||
|
|
||
|
#include <wx/utils.h>
|
||
|
|
||
|
pBuffer::pBuffer()
|
||
|
{
|
||
|
}
|
||
|
pBuffer::pBuffer(int width, int height)
|
||
|
:m_width(width),m_height(height)
|
||
|
{
|
||
|
}
|
||
|
pBuffer::~pBuffer()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
#if defined(__WXMSW__)
|
||
|
|
||
|
/*#if !defined(wglGetExtensionsStringARB)
|
||
|
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
||
|
|
||
|
// WGL_ARB_pbuffer
|
||
|
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = NULL;
|
||
|
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = NULL;
|
||
|
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = NULL;
|
||
|
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = NULL;
|
||
|
PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = NULL;
|
||
|
|
||
|
// WGL_ARB_pixel_format
|
||
|
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL;
|
||
|
PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = NULL;
|
||
|
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
|
||
|
#endif */
|
||
|
|
||
|
|
||
|
pBufferWGL::pBufferWGL(int width, int height)
|
||
|
:m_texture(0)
|
||
|
{
|
||
|
|
||
|
hGlRc=0;
|
||
|
hBuffer=0;
|
||
|
hdc=0;
|
||
|
saveHdc=0;
|
||
|
saveHglrc=0;
|
||
|
|
||
|
if (!InitGLStuff()) {
|
||
|
throw GLException(wxT("Could not Init GL Stuff"));
|
||
|
}
|
||
|
|
||
|
// Adjust to square power of 2
|
||
|
int ms=MAX(width,height);
|
||
|
int j;
|
||
|
for (int i=4;i<32;i++) { // min size 16x16.. probably a usless size.
|
||
|
j=1 << i;
|
||
|
if (j >= ms) break;
|
||
|
}
|
||
|
assert (j>=ms); // I seriously doubt this will ever happen ;)
|
||
|
|
||
|
// WGL only supports square pBuffers
|
||
|
m_width=j;
|
||
|
m_height=j;
|
||
|
|
||
|
wxLogMessage(wxString::Format(wxT("Adjusting pBuffer width and height to %ix%i"),j,j));
|
||
|
|
||
|
// Create Texture
|
||
|
glGenTextures(1, &m_texture);
|
||
|
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||
|
|
||
|
glTexImage2D(GL_TEXTURE_2D, 0, 4, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||
|
|
||
|
// Get the context to work with (must be valid, will die otherwise)
|
||
|
saveHdc = wglGetCurrentDC();
|
||
|
saveHglrc = wglGetCurrentContext();
|
||
|
|
||
|
int pixelFormats;
|
||
|
int intAttrs[32] ={
|
||
|
WGL_RED_BITS_ARB,8,
|
||
|
WGL_GREEN_BITS_ARB,8,
|
||
|
WGL_BLUE_BITS_ARB,8,
|
||
|
WGL_ALPHA_BITS_ARB,8,
|
||
|
WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
|
||
|
WGL_BIND_TO_TEXTURE_RGBA_ARB, GL_TRUE,
|
||
|
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
|
||
|
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
|
||
|
WGL_DOUBLE_BUFFER_ARB,GL_FALSE,
|
||
|
0
|
||
|
}; // 0 terminate the list
|
||
|
|
||
|
unsigned int numFormats = 0;
|
||
|
|
||
|
wxLogError(wxT("Foo2"));
|
||
|
if (!wglChoosePixelFormatARB) {
|
||
|
throw GLException(wxT("No wglChoosePixelFormatARB available"));
|
||
|
}
|
||
|
if (!wglChoosePixelFormatARB( saveHdc, intAttrs, NULL, 1, &pixelFormats, &numFormats)) {
|
||
|
throw GLException(wxT("WGL: pbuffer creation error: Couldn't find a suitable pixel format."));
|
||
|
}
|
||
|
if (numFormats==0) {
|
||
|
throw GLException(wxT("WGL: pbuffer creation error: numFormats==0"));
|
||
|
}
|
||
|
const int attributes[]= {
|
||
|
WGL_TEXTURE_FORMAT_ARB,
|
||
|
WGL_TEXTURE_RGBA_ARB, // p-buffer will have RBA texture format
|
||
|
WGL_TEXTURE_TARGET_ARB,
|
||
|
WGL_TEXTURE_2D_ARB,
|
||
|
0
|
||
|
}; // Of texture target will be GL_TEXTURE_2D
|
||
|
|
||
|
//wglCreatePbufferARB(hDC, pixelFormats, pbwidth, pbheight, attributes);
|
||
|
hBuffer=wglCreatePbufferARB(saveHdc, pixelFormats, m_width, m_height, attributes );
|
||
|
if (!hBuffer) {
|
||
|
throw GLException(wxT("wglCreatePbufferARB failure"));
|
||
|
}
|
||
|
|
||
|
hdc=wglGetPbufferDCARB( hBuffer );
|
||
|
if (!hdc) {
|
||
|
throw GLException(wxT("wglGetPbufferDCARB failure"));
|
||
|
}
|
||
|
|
||
|
hGlRc=wglCreateContext(hdc);
|
||
|
if (!hGlRc) {
|
||
|
throw GLException(wxT("wglCreateContext failure"));
|
||
|
}
|
||
|
|
||
|
//printf("PBuffer size: %d x %d\n",w,h);
|
||
|
int w,h;
|
||
|
wglQueryPbufferARB(hBuffer, WGL_PBUFFER_WIDTH_ARB, &w);
|
||
|
wglQueryPbufferARB(hBuffer, WGL_PBUFFER_HEIGHT_ARB, &h);
|
||
|
|
||
|
// compare w & h to m_width & m_height.
|
||
|
|
||
|
wxLogError(wxT("Foo7"));
|
||
|
|
||
|
wglMakeCurrent(hdc,hGlRc);
|
||
|
|
||
|
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
|
||
|
glEnable(GL_BLEND);
|
||
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // enable transparency
|
||
|
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
glLoadIdentity();
|
||
|
glOrtho(0, width, height, 0, -1, 1);
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
glLoadIdentity();
|
||
|
|
||
|
glClearColor(0,0,0,1);
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
|
||
|
|
||
|
// switch back to the screen context
|
||
|
wglMakeCurrent(saveHdc, saveHglrc);
|
||
|
// So we can share the main context
|
||
|
wglShareLists(saveHglrc, hGlRc);
|
||
|
|
||
|
// Jump back to pBuffer ready for rendering
|
||
|
//wglMakeCurrent(hdc, hGlRc);
|
||
|
}
|
||
|
pBufferWGL::~pBufferWGL()
|
||
|
{
|
||
|
if (hGlRc) wglDeleteContext(hGlRc);
|
||
|
if (hBuffer) wglReleasePbufferDCARB(hBuffer, hdc);
|
||
|
if (hBuffer) wglDestroyPbufferARB(hBuffer);
|
||
|
}
|
||
|
void pBufferWGL::UseBuffer(bool b)
|
||
|
{
|
||
|
if (b) {
|
||
|
wglMakeCurrent(hdc, hGlRc);
|
||
|
} else {
|
||
|
wglMakeCurrent(saveHdc, saveHglrc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool pBufferWGL::InitGLStuff()
|
||
|
{
|
||
|
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||
|
char *ext = NULL;
|
||
|
|
||
|
if (wglGetExtensionsStringARB)
|
||
|
ext = (char*)wglGetExtensionsStringARB( wglGetCurrentDC() );
|
||
|
else {
|
||
|
wxLogError(wxT("Unable to get address for wglGetExtensionsStringARB!"));
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
#elif defined(__UNIX__) && !defined(__WXMAC__)
|
||
|
|
||
|
GLXContext real_shared_context=NULL;
|
||
|
|
||
|
|
||
|
pBufferGLX::pBufferGLX(int width, int height)
|
||
|
:pBuffer()
|
||
|
{
|
||
|
m_width=width;
|
||
|
m_height=height;
|
||
|
|
||
|
int attrib[]={
|
||
|
GLX_PBUFFER_WIDTH,m_width,
|
||
|
GLX_PBUFFER_HEIGHT,m_height,
|
||
|
GLX_PRESERVED_CONTENTS, True
|
||
|
};
|
||
|
|
||
|
pBuffer=0;
|
||
|
m_context=0,m_shared=0;
|
||
|
int ret;
|
||
|
display=NULL;
|
||
|
GLXFBConfig *fbc=NULL;
|
||
|
|
||
|
/*#if wxCHECK_VERSION(2,9,0)
|
||
|
display=wxGetX11Display();
|
||
|
fbc = GetGLXFBConfig(); // wxGLCanvas call
|
||
|
fbc = &fbc[0];
|
||
|
pBuffer=glXCreatePbuffer(display, fbc[0], attrib );
|
||
|
|
||
|
#else */
|
||
|
display=(Display *)wxGetDisplay();
|
||
|
int doubleBufferAttributess[] = {
|
||
|
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||
|
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||
|
GLX_DOUBLEBUFFER, True,
|
||
|
GLX_RED_SIZE, 8,
|
||
|
GLX_GREEN_SIZE, 8,
|
||
|
GLX_BLUE_SIZE, 8,
|
||
|
None
|
||
|
};
|
||
|
fbc=glXChooseFBConfig(display, DefaultScreen(display), doubleBufferAttributess, &ret);
|
||
|
pBuffer=glXCreatePbuffer(display, *fbc, attrib );
|
||
|
//#endif
|
||
|
|
||
|
if (pBuffer == 0) {
|
||
|
wxLogError(wxT("pBuffer not availble"));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// This function is not in WX sourcecode yet :(
|
||
|
//shared=shared_context->GetGLXContext();
|
||
|
|
||
|
if (real_shared_context) m_shared=real_shared_context; // Only available after redraw.. :(
|
||
|
else {
|
||
|
// First render screws up unless we do this..
|
||
|
m_shared=m_context= glXCreateNewContext(display,*fbc,GLX_RGBA_TYPE, NULL, True);
|
||
|
}
|
||
|
|
||
|
if (m_shared == 0) {
|
||
|
wxLogError(wxT("Context not availble"));
|
||
|
}
|
||
|
|
||
|
//#if !wxCHECK_VERSION(2,9,0)
|
||
|
XFree(fbc);
|
||
|
//#endif
|
||
|
|
||
|
glXMakeCurrent(display,pBuffer,m_shared);
|
||
|
|
||
|
//UseBuffer(true);
|
||
|
}
|
||
|
pBufferGLX::~pBufferGLX()
|
||
|
{
|
||
|
if (m_context) glXDestroyContext(display,m_context); // Destroy the context only if we created it..
|
||
|
if (pBuffer) glXDestroyPbuffer(display, pBuffer);
|
||
|
}
|
||
|
void pBufferGLX::UseBuffer(bool b)
|
||
|
{
|
||
|
if (b) {
|
||
|
if (glXMakeCurrent(display,pBuffer,m_shared)!=True) {
|
||
|
wxLogError(wxT("Couldn't make pBuffer current"));
|
||
|
}
|
||
|
} else {
|
||
|
|
||
|
// to be honest.. i'm not sure yet.. wx stupidly keeps the needed variables private
|
||
|
}
|
||
|
}
|
||
|
#elif defined(__DARWIN__) || defined(__WXMAC__)
|
||
|
|
||
|
|
||
|
#endif
|