mirror of
https://github.com/SFML/SFML.git
synced 2024-11-24 20:31:05 +08:00
Added the Linux P-Buffer implementation (WIP)
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1146 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
470963326e
commit
9342dc77bb
226
src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp
Normal file
226
src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Linux/RenderImageImplPBuffer.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer::RenderImageImplPBuffer() :
|
||||
myPBuffer(NULL),
|
||||
myContext(NULL),
|
||||
myWidth (0),
|
||||
myHeight (0)
|
||||
{
|
||||
myDisplay = XOpenDisplay(NULL);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Destructor
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
{
|
||||
if (myContext)
|
||||
glXDestroyContext(myDisplay, myContext);
|
||||
|
||||
if (myPBuffer)
|
||||
glXDestroyGLXPbufferSGIX(myDisplay, myPBuffer);
|
||||
|
||||
XCloseDisplay(myDisplay);
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context Ctx;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check whether the system supports P-Buffer or not
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
// Make sure that GLEW is initialized
|
||||
EnsureGlewInit();
|
||||
|
||||
return false; //glxewIsSupported("GLX_SGIX_pbuffer");
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::Create
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::Create(unsigned int Width, unsigned int Height, unsigned int /*TextureId*/, bool DepthBuffer)
|
||||
{
|
||||
// Store the dimensions
|
||||
myWidth = Width;
|
||||
myHeight = Height;
|
||||
|
||||
// Define the PBuffer attributes
|
||||
int VisualAttributes[] =
|
||||
{
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_ALPHA_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, (DepthBuffer ? 24 : 0),
|
||||
0
|
||||
};
|
||||
int PBufferAttributes[] =
|
||||
{
|
||||
GLX_PBUFFER_WIDTH, Width,
|
||||
GLX_PBUFFER_HEIGHT, Height,
|
||||
0
|
||||
};
|
||||
|
||||
// Get the available FB configurations
|
||||
int NbConfigs = 0;
|
||||
GLXFBConfig* Configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), VisualAttributes, &NbConfigs);
|
||||
if (!Configs || !NbConfigs)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to find a suitable pixel format for PBuffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the P-Buffer
|
||||
myPBuffer = glXCreateGLXPbufferSGIX(myDisplay, Configs[0], Width, Height, PBufferAttributes);
|
||||
if (!myPBuffer)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl;
|
||||
XFree(Configs);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the actual size of the P-Buffer
|
||||
unsigned int ActualWidth, ActualHeight;
|
||||
glXQueryGLXPbufferSGIX(myDisplay, myPBuffer, GLX_WIDTH_SGIX, &ActualWidth);
|
||||
glXQueryGLXPbufferSGIX(myDisplay, myPBuffer, GLX_HEIGHT_SGIX, &ActualHeight);
|
||||
if ((ActualWidth != Width) || (ActualHeight != Height))
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to match the requested size). "
|
||||
<< "Size: " << ActualWidth << "x" << ActualHeight << " - "
|
||||
<< "Requested: " << Width << "x" << Height
|
||||
<< std::endl;
|
||||
XFree(Configs);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll have to share the P-Buffer context with the current context
|
||||
GLXDrawable CurrentDrawable = glXGetCurrentDrawable();
|
||||
GLXContext CurrentContext = glXGetCurrentContext();
|
||||
if (CurrentContext)
|
||||
glXMakeCurrent(myDisplay, NULL, NULL);
|
||||
|
||||
// Create the context
|
||||
XVisualInfo* Visual = glXGetVisualFromFBConfig(myDisplay, Configs[0]);
|
||||
myContext = glXCreateContext(myDisplay, Visual, CurrentContext, true);
|
||||
if (!myContext)
|
||||
{
|
||||
std::cerr << "Impossible to create render image (failed to create the OpenGL context)" << std::endl;
|
||||
XFree(Configs);
|
||||
XFree(Visual);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Restore the previous active context
|
||||
if (CurrentContext)
|
||||
glXMakeCurrent(myDisplay, CurrentDrawable, CurrentContext);
|
||||
|
||||
// Cleanup resources
|
||||
XFree(Configs);
|
||||
XFree(Visual);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::Activate
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::Activate(bool Active)
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
if (myPBuffer && myContext && (glXGetCurrentContext() != myContext))
|
||||
{
|
||||
// Bind the OpenGL context of the P-Buffer
|
||||
if (!glXMakeCurrent(myDisplay, myPBuffer, myContext))
|
||||
{
|
||||
std::cout << "Failed to activate render image" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't actually unbind the P-Buffer, for performances reasons
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::UpdateTexture
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::UpdateTexture(unsigned int TextureId)
|
||||
{
|
||||
// Store the current active context
|
||||
GLXDrawable CurrentDrawable = glXGetCurrentDrawable();
|
||||
GLXContext CurrentContext = glXGetCurrentContext();
|
||||
|
||||
if (Activate(true))
|
||||
{
|
||||
// Bind the texture
|
||||
GLCheck(glEnable(GL_TEXTURE_2D));
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, TextureId));
|
||||
|
||||
// Copy the rendered pixels to the image
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||
|
||||
// Restore the previous context
|
||||
glXMakeCurrent(myDisplay, CurrentDrawable, CurrentContext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
103
src/SFML/Graphics/Linux/RenderImageImplPBuffer.hpp
Normal file
103
src/SFML/Graphics/Linux/RenderImageImplPBuffer.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
#define SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Graphics/GLEW/glew.h>
|
||||
#include <SFML/Graphics/GLEW/glxew.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Specialization of RenderImageImpl using GLX P-Buffers
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplPBuffer : public RenderImageImpl
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~RenderImageImplPBuffer();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check whether the system supports P-Buffer or not
|
||||
///
|
||||
/// \return True if P-Buffer render images are supported
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool IsSupported();
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::Create
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool Create(unsigned int Width, unsigned int Height, unsigned int TextureId, bool DepthBuffer);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::Activate
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool Activate(bool Active);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see RenderImageImpl::UpdateTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool UpdateTexture(unsigned TextureId);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
::Display* myDisplay; ///< Connection to the X display
|
||||
GLXPbuffer myPBuffer; ///< P-Buffer
|
||||
GLXContext myContext; ///< Associated OpenGL context
|
||||
unsigned int myWidth; ///< Width of the P-Buffer
|
||||
unsigned int myHeight; ///< Height of the P-Buffer
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
@ -1,4 +1,4 @@
|
||||
SRC = $(wildcard *.cpp)
|
||||
SRC = $(wildcard *.cpp ./Linux/*.cpp)
|
||||
SRCGLEW = $(wildcard ./GLEW/*.c)
|
||||
SRCJPEG = $(wildcard ./libjpeg/*.c)
|
||||
SRCPNG = $(wildcard ./libpng/*.c)
|
||||
|
@ -72,7 +72,7 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check whether the system supports FBOs or not
|
||||
/// Check whether the system supports P-Buffer or not
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user