Added Canvas MSAA support in OpenGL ES 2 on iOS and when ANGLE is used on Windows.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2015-02-24 03:07:46 -04:00
parent 517ee44e84
commit 2cc53bb85c
3 changed files with 44 additions and 20 deletions
+12 -4
View File
@@ -149,12 +149,11 @@ struct FramebufferStrategyCorePacked : public FramebufferStrategy
return true;
}
virtual bool createMSAABuffer(int width, int height, int &samples, GLenum internalformat, GLuint &buffer)
virtual bool createMSAABuffer(int width, int height, int &samples, GLenum iformat, GLuint &buffer)
{
glGenRenderbuffers(1, &buffer);
glBindRenderbuffer(GL_RENDERBUFFER, buffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat,
width, height);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, iformat, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, buffer);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
@@ -1020,7 +1019,10 @@ bool Canvas::resolveMSAA()
previous = current->fbo;
// Do the MSAA resolve by blitting the MSAA renderbuffer to the texture.
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
// For many of the extensions that add suffixes to the functions, we assign
// function pointers in OpenGL.cpp so we can call the core functions.
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
|| GLAD_ANGLE_framebuffer_multisample)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
@@ -1034,6 +1036,12 @@ bool Canvas::resolveMSAA()
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
else if (GLAD_APPLE_framebuffer_multisample)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
glResolveMultisampleFramebufferAPPLE();
}
else
return false;
+30 -14
View File
@@ -108,12 +108,12 @@ void OpenGL::setupContext()
state.pointSize = 1.0f;
// Initialize multiple texture unit support for shaders.
state.textureUnits.clear();
state.boundTextures.clear();
GLint maxtextureunits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtextureunits);
state.textureUnits.resize(maxtextureunits, 0);
state.boundTextures.resize(maxtextureunits, 0);
GLenum curgltextureunit;
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *) &curgltextureunit);
@@ -121,10 +121,10 @@ void OpenGL::setupContext()
state.curTextureUnit = (int) curgltextureunit - GL_TEXTURE0;
// Retrieve currently bound textures for each texture unit.
for (int i = 0; i < (int) state.textureUnits.size(); i++)
for (int i = 0; i < (int) state.boundTextures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &state.textureUnits[i]);
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &state.boundTextures[i]);
}
glActiveTexture(curgltextureunit);
@@ -176,7 +176,7 @@ void OpenGL::initVendor()
vendor = VENDOR_INTEL;
else if (strstr(vstr, "Mesa"))
vendor = VENDOR_MESA_SOFT;
else if (strstr(vstr, "Apple Computer"))
else if (strstr(vstr, "Apple Computer") || strstr(vstr, "Apple Inc."))
vendor = VENDOR_APPLE;
else if (strstr(vstr, "Microsoft"))
vendor = VENDOR_MICROSOFT;
@@ -196,6 +196,18 @@ void OpenGL::initVendor()
void OpenGL::initOpenGLFunctions()
{
if (!(GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
{
// There are like 100 different suffixed versions of glRenderbufferStorageMultisample,
// so we'll just assign all the ones we use to the core function pointer.
if (GLAD_APPLE_framebuffer_multisample)
fp_glRenderbufferStorageMultisample = (pfn_glRenderbufferStorageMultisample) fp_glRenderbufferStorageMultisampleAPPLE;
else if (GLAD_ANGLE_framebuffer_multisample)
fp_glRenderbufferStorageMultisample = (pfn_glRenderbufferStorageMultisample) fp_glRenderbufferStorageMultisampleANGLE;
if (GLAD_ANGLE_framebuffer_blit)
fp_glBlitFramebuffer = (pfn_glBlitFramebuffer) fp_glBlitFramebufferANGLE;
}
}
void OpenGL::initMaxValues()
@@ -219,8 +231,12 @@ void OpenGL::initMaxValues()
maxRenderTargets = std::min(maxattachments, maxdrawbuffers);
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_EXT_framebuffer_multisample)
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
|| GLAD_EXT_framebuffer_multisample || GLAD_APPLE_framebuffer_multisample
|| GLAD_ANGLE_framebuffer_multisample)
{
glGetIntegerv(GL_MAX_SAMPLES, &maxRenderbufferSamples);
}
else
maxRenderbufferSamples = 0;
}
@@ -241,7 +257,7 @@ void OpenGL::createDefaultTexture()
// primitives, which would create the need to use different "passthrough"
// shaders for untextured primitives vs images.
GLuint curtexture = state.textureUnits[state.curTextureUnit];
GLuint curtexture = state.boundTextures[state.curTextureUnit];
glGenTextures(1, &state.defaultTexture);
bindTexture(state.defaultTexture);
@@ -446,7 +462,7 @@ GLuint OpenGL::getDefaultTexture() const
void OpenGL::setTextureUnit(int textureunit)
{
if (textureunit < 0 || (size_t) textureunit >= state.textureUnits.size())
if (textureunit < 0 || (size_t) textureunit >= state.boundTextures.size())
throw love::Exception("Invalid texture unit index (%d).", textureunit);
if (textureunit != state.curTextureUnit)
@@ -457,24 +473,24 @@ void OpenGL::setTextureUnit(int textureunit)
void OpenGL::bindTexture(GLuint texture)
{
if (texture != state.textureUnits[state.curTextureUnit])
if (texture != state.boundTextures[state.curTextureUnit])
{
state.textureUnits[state.curTextureUnit] = texture;
state.boundTextures[state.curTextureUnit] = texture;
glBindTexture(GL_TEXTURE_2D, texture);
}
}
void OpenGL::bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev)
{
if (textureunit < 0 || (size_t) textureunit >= state.textureUnits.size())
if (textureunit < 0 || (size_t) textureunit >= state.boundTextures.size())
throw love::Exception("Invalid texture unit index.");
if (texture != state.textureUnits[textureunit])
if (texture != state.boundTextures[textureunit])
{
int oldtextureunit = state.curTextureUnit;
setTextureUnit(textureunit);
state.textureUnits[textureunit] = texture;
state.boundTextures[textureunit] = texture;
glBindTexture(GL_TEXTURE_2D, texture);
if (restoreprev)
@@ -486,7 +502,7 @@ void OpenGL::deleteTexture(GLuint texture)
{
// glDeleteTextures binds texture 0 to all texture units the deleted texture
// was bound to before deletion.
for (GLuint &texid : state.textureUnits)
for (GLuint &texid : state.boundTextures)
{
if (texid == texture)
texid = 0;
+2 -2
View File
@@ -77,7 +77,7 @@ public:
VENDOR_NVIDIA,
VENDOR_INTEL,
VENDOR_MESA_SOFT, // Software renderer.
VENDOR_APPLE, // Software renderer.
VENDOR_APPLE, // Software renderer on desktops.
VENDOR_MICROSOFT, // Software renderer.
VENDOR_IMGTEC,
VENDOR_ARM,
@@ -353,7 +353,7 @@ private:
Color clearColor;
// Texture unit state (currently bound texture for each texture unit.)
std::vector<GLuint> textureUnits;
std::vector<GLuint> boundTextures;
// Currently active texture unit.
int curTextureUnit;