support for OpenGL 2.0
* use OpenGL 2.0 auxiliary buffers when FBO is not supported, thus this means that OpenGL 3 is not a requirement anymore, so otclient might work in older video cards * map zooming will never work well with Opengl 2.0 because of glCopyTexSubImage2D limitation
This commit is contained in:
parent
5c35938a92
commit
01d5fad315
|
@ -86,6 +86,10 @@ void CoordsBuffer::addRepeatedRects(const Rect& dest, const Rect& src)
|
||||||
|
|
||||||
void CoordsBuffer::enableHardwareCaching(HardwareBuffer::UsagePattern usagePattern)
|
void CoordsBuffer::enableHardwareCaching(HardwareBuffer::UsagePattern usagePattern)
|
||||||
{
|
{
|
||||||
|
#ifndef OPENGL_ES2
|
||||||
|
if(!GL_ARB_vertex_buffer_object)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
m_hardwareCacheMode = usagePattern;
|
m_hardwareCacheMode = usagePattern;
|
||||||
m_hardwareCaching = true;
|
m_hardwareCaching = true;
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
|
|
|
@ -25,30 +25,52 @@
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
uint FrameBuffer::boundFbo = 0;
|
uint FrameBuffer::boundFbo = 0;
|
||||||
|
std::vector<bool> auxBuffers;
|
||||||
|
|
||||||
FrameBuffer::FrameBuffer()
|
FrameBuffer::FrameBuffer()
|
||||||
{
|
{
|
||||||
m_clearColor = Color::alpha;
|
m_clearColor = Color::alpha;
|
||||||
|
internalCreate();
|
||||||
glGenFramebuffers(1, &m_fbo);
|
|
||||||
if(!m_fbo)
|
|
||||||
logFatal("Unable to create framebuffer object");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer::FrameBuffer(const Size& size)
|
FrameBuffer::FrameBuffer(const Size& size)
|
||||||
{
|
{
|
||||||
m_clearColor = Color::alpha;
|
m_clearColor = Color::alpha;
|
||||||
|
internalCreate();
|
||||||
glGenFramebuffers(1, &m_fbo);
|
|
||||||
if(!m_fbo)
|
|
||||||
logFatal("Unable to create framebuffer object");
|
|
||||||
|
|
||||||
resize(size);
|
resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FrameBuffer::internalCreate()
|
||||||
|
{
|
||||||
|
if(g_graphics.hasFBO()) {
|
||||||
|
glGenFramebuffers(1, &m_fbo);
|
||||||
|
if(!m_fbo)
|
||||||
|
logFatal("Unable to create framebuffer object");
|
||||||
|
} else { // use auxiliar buffers when FBOs are not supported
|
||||||
|
m_fbo = 0;
|
||||||
|
if(auxBuffers.size() == 0) {
|
||||||
|
int maxAuxs;
|
||||||
|
glGetIntegerv(GL_AUX_BUFFERS, &maxAuxs);
|
||||||
|
auxBuffers.resize(maxAuxs+1, false);
|
||||||
|
}
|
||||||
|
for(uint i=1;i<auxBuffers.size();++i) {
|
||||||
|
if(auxBuffers[i] == false) {
|
||||||
|
m_fbo = i;
|
||||||
|
auxBuffers[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!m_fbo)
|
||||||
|
logFatal("There is no available auxiliar buffer for a new framebuffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FrameBuffer::~FrameBuffer()
|
FrameBuffer::~FrameBuffer()
|
||||||
{
|
{
|
||||||
glDeleteFramebuffers(1, &m_fbo);
|
if(g_graphics.hasFBO()) {
|
||||||
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
|
} else {
|
||||||
|
auxBuffers[m_fbo] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::resize(const Size& size)
|
void FrameBuffer::resize(const Size& size)
|
||||||
|
@ -59,15 +81,19 @@ void FrameBuffer::resize(const Size& size)
|
||||||
if(m_texture && m_texture->getSize() == size)
|
if(m_texture && m_texture->getSize() == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
internalBind();
|
|
||||||
m_texture = TexturePtr(new Texture(size.width(), size.height(), 4));
|
m_texture = TexturePtr(new Texture(size.width(), size.height(), 4));
|
||||||
m_texture->setSmooth(true);
|
m_texture->setSmooth(true);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
|
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
if(g_graphics.hasFBO()) {
|
||||||
if(status != GL_FRAMEBUFFER_COMPLETE)
|
internalBind();
|
||||||
logFatal("Unable to setup framebuffer object");
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
|
||||||
internalRelease();
|
|
||||||
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if(status != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
logFatal("Unable to setup framebuffer object");
|
||||||
|
internalRelease();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::bind(bool clear)
|
void FrameBuffer::bind(bool clear)
|
||||||
|
@ -115,7 +141,15 @@ void FrameBuffer::internalBind()
|
||||||
if(boundFbo == m_fbo)
|
if(boundFbo == m_fbo)
|
||||||
return;
|
return;
|
||||||
assert(boundFbo != m_fbo);
|
assert(boundFbo != m_fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
|
||||||
|
if(g_graphics.hasFBO()) {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
} else {
|
||||||
|
int buffer = GL_AUX0 + m_fbo - 1;
|
||||||
|
glDrawBuffer(buffer);
|
||||||
|
glReadBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
m_prevBoundFbo = boundFbo;
|
m_prevBoundFbo = boundFbo;
|
||||||
boundFbo = m_fbo;
|
boundFbo = m_fbo;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +157,18 @@ void FrameBuffer::internalBind()
|
||||||
void FrameBuffer::internalRelease()
|
void FrameBuffer::internalRelease()
|
||||||
{
|
{
|
||||||
assert(boundFbo == m_fbo);
|
assert(boundFbo == m_fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_prevBoundFbo);
|
if(g_graphics.hasFBO()) {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_prevBoundFbo);
|
||||||
|
} else {
|
||||||
|
m_texture->bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_texture->getWidth(), m_texture->getHeight());
|
||||||
|
|
||||||
|
int buffer = GL_BACK;
|
||||||
|
if(m_prevBoundFbo != 0)
|
||||||
|
buffer = GL_AUX0 + m_fbo - 1;
|
||||||
|
|
||||||
|
glDrawBuffer(buffer);
|
||||||
|
glReadBuffer(buffer);
|
||||||
|
}
|
||||||
boundFbo = m_prevBoundFbo;
|
boundFbo = m_prevBoundFbo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
const Size& getSize() { return m_texture->getSize(); }
|
const Size& getSize() { return m_texture->getSize(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void internalCreate();
|
||||||
void internalBind();
|
void internalBind();
|
||||||
void internalRelease();
|
void internalRelease();
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,8 @@ void Graphics::init()
|
||||||
logFatal("Unable to init GLEW: ", glewGetErrorString(err));
|
logFatal("Unable to init GLEW: ", glewGetErrorString(err));
|
||||||
if(!GLEW_ARB_vertex_program || !GLEW_ARB_vertex_shader ||
|
if(!GLEW_ARB_vertex_program || !GLEW_ARB_vertex_shader ||
|
||||||
!GLEW_ARB_fragment_program || !GLEW_ARB_fragment_shader ||
|
!GLEW_ARB_fragment_program || !GLEW_ARB_fragment_shader ||
|
||||||
!GLEW_ARB_framebuffer_object ||
|
!GLEW_ARB_texture_non_power_of_two || !GLEW_ARB_multitexture)
|
||||||
!GLEW_ARB_multitexture)
|
logFatal("Some OpenGL 2.0 extensions is not supported by your system graphics, please try updating your video drivers or buy a new hardware.");
|
||||||
logFatal("Your video driver is not supported");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
@ -59,11 +58,13 @@ void Graphics::terminate()
|
||||||
m_emptyTexture.reset();
|
m_emptyTexture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::isExtensionSupported(const char *extension)
|
bool Graphics::hasFBO()
|
||||||
{
|
{
|
||||||
std::string extensionsString = (const char*)glGetString(GL_EXTENSIONS);
|
#ifndef OPENGL_ES2
|
||||||
auto extensions = Fw::split(extensionsString);
|
return GLEW_ARB_framebuffer_object;
|
||||||
return std::find(extensions.begin(), extensions.end(), extension) != extensions.end();
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::resize(const Size& size)
|
void Graphics::resize(const Size& size)
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
bool isExtensionSupported(const char *extension);
|
bool hasFBO();
|
||||||
|
|
||||||
void resize(const Size& size);
|
void resize(const Size& size);
|
||||||
void beginRender();
|
void beginRender();
|
||||||
|
|
Loading…
Reference in New Issue