GLMeta: Add framebuffer blitting support
This commit is contained in:
		
							parent
							
								
									7ad6b7b5df
								
							
						
					
					
						commit
						a26c73930d
					
				
					 9 changed files with 225 additions and 181 deletions
				
			
		| 
						 | 
					@ -150,7 +150,7 @@ struct BitmapPrivate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void bindFBO()
 | 
						void bindFBO()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		FBO::bind(gl.fbo, FBO::Draw);
 | 
							FBO::bind(gl.fbo, FBO::Generic);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void pushSetViewport(ShaderBase &shader) const
 | 
						void pushSetViewport(ShaderBase &shader) const
 | 
				
			||||||
| 
						 | 
					@ -384,11 +384,10 @@ void Bitmap::stretchBlt(const IntRect &destRect,
 | 
				
			||||||
	if (opacity == 255 && !p->touchesTaintedArea(destRect))
 | 
						if (opacity == 255 && !p->touchesTaintedArea(destRect))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Fast blit */
 | 
							/* Fast blit */
 | 
				
			||||||
		FBO::bind(source.p->gl.fbo, FBO::Read);
 | 
							GLMeta::blitBegin(p->gl);
 | 
				
			||||||
		FBO::bind(p->gl.fbo, FBO::Draw);
 | 
							GLMeta::blitSource(source.p->gl);
 | 
				
			||||||
 | 
							GLMeta::blitRectangle(sourceRect, destRect);
 | 
				
			||||||
		FBO::blit(sourceRect.x, sourceRect.y, sourceRect.w, sourceRect.h,
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
		          destRect.x,   destRect.y,   destRect.w,   destRect.h);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -397,9 +396,10 @@ void Bitmap::stretchBlt(const IntRect &destRect,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		TEXFBO &gpTex = shState->gpTexFBO(destRect.w, destRect.h);
 | 
							TEXFBO &gpTex = shState->gpTexFBO(destRect.w, destRect.h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FBO::bind(gpTex.fbo, FBO::Draw);
 | 
							GLMeta::blitBegin(gpTex);
 | 
				
			||||||
		FBO::bind(p->gl.fbo, FBO::Read);
 | 
							GLMeta::blitSource(p->gl);
 | 
				
			||||||
		FBO::blit(destRect.x, destRect.y, 0, 0, destRect.w, destRect.h);
 | 
							GLMeta::blitRectangle(destRect, Vec2i());
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FloatRect bltSubRect((float) sourceRect.x / source.width(),
 | 
							FloatRect bltSubRect((float) sourceRect.x / source.width(),
 | 
				
			||||||
		                     (float) sourceRect.y / source.height(),
 | 
							                     (float) sourceRect.y / source.height(),
 | 
				
			||||||
| 
						 | 
					@ -544,7 +544,7 @@ void Bitmap::blur()
 | 
				
			||||||
	glState.viewport.pushSet(IntRect(0, 0, width(), height()));
 | 
						glState.viewport.pushSet(IntRect(0, 0, width(), height()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TEX::bind(p->gl.tex);
 | 
						TEX::bind(p->gl.tex);
 | 
				
			||||||
	FBO::bind(auxTex.fbo, FBO::Draw);
 | 
						FBO::bind(auxTex.fbo, FBO::Generic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pass1.bind();
 | 
						pass1.bind();
 | 
				
			||||||
	pass1.setTexSize(Vec2i(width(), height()));
 | 
						pass1.setTexSize(Vec2i(width(), height()));
 | 
				
			||||||
| 
						 | 
					@ -553,7 +553,7 @@ void Bitmap::blur()
 | 
				
			||||||
	quad.draw();
 | 
						quad.draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TEX::bind(auxTex.tex);
 | 
						TEX::bind(auxTex.tex);
 | 
				
			||||||
	FBO::bind(p->gl.fbo, FBO::Draw);
 | 
						p->bindFBO();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pass2.bind();
 | 
						pass2.bind();
 | 
				
			||||||
	pass2.setTexSize(Vec2i(width(), height()));
 | 
						pass2.setTexSize(Vec2i(width(), height()));
 | 
				
			||||||
| 
						 | 
					@ -625,7 +625,7 @@ void Bitmap::radialBlur(int angle, int divisions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TEXFBO newTex = shState->texPool().request(_width, _height);
 | 
						TEXFBO newTex = shState->texPool().request(_width, _height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FBO::bind(newTex.fbo, FBO::Draw);
 | 
						FBO::bind(newTex.fbo, FBO::Generic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glState.clearColor.pushSet(Vec4());
 | 
						glState.clearColor.pushSet(Vec4());
 | 
				
			||||||
	FBO::clear();
 | 
						FBO::clear();
 | 
				
			||||||
| 
						 | 
					@ -698,7 +698,7 @@ Color Bitmap::getPixel(int x, int y) const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		p->allocSurface();
 | 
							p->allocSurface();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FBO::bind(p->gl.fbo, FBO::Read);
 | 
							FBO::bind(p->gl.fbo, FBO::Generic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glState.viewport.pushSet(IntRect(0, 0, width(), height()));
 | 
							glState.viewport.pushSet(IntRect(0, 0, width(), height()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -764,7 +764,7 @@ void Bitmap::hueChange(int hue)
 | 
				
			||||||
	shader.bind();
 | 
						shader.bind();
 | 
				
			||||||
	shader.setHueAdjust(hueAdj);
 | 
						shader.setHueAdjust(hueAdj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FBO::bind(newTex.fbo, FBO::Draw);
 | 
						FBO::bind(newTex.fbo, FBO::Generic);
 | 
				
			||||||
	p->pushSetViewport(shader);
 | 
						p->pushSetViewport(shader);
 | 
				
			||||||
	p->bindTexture(shader);
 | 
						p->bindTexture(shader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -918,12 +918,11 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 | 
				
			||||||
			TEX::bind(gpTF.tex);
 | 
								TEX::bind(gpTF.tex);
 | 
				
			||||||
			TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA);
 | 
								TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			FBO::bind(gpTF.fbo, FBO::Read);
 | 
								GLMeta::blitBegin(p->gl);
 | 
				
			||||||
			p->bindFBO();
 | 
								GLMeta::blitSource(gpTF);
 | 
				
			||||||
 | 
								GLMeta::blitRectangle(IntRect(0, 0, txtSurf->w, txtSurf->h),
 | 
				
			||||||
			FBO::blit(0, 0, txtSurf->w, txtSurf->h,
 | 
								                      posRect, FBO::Linear);
 | 
				
			||||||
			          posRect.x, posRect.y, posRect.w, posRect.h,
 | 
								GLMeta::blitFinish();
 | 
				
			||||||
			          FBO::Linear);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -932,9 +931,10 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 | 
				
			||||||
		 * buffer we're about to render to */
 | 
							 * buffer we're about to render to */
 | 
				
			||||||
		TEXFBO &gpTex2 = shState->gpTexFBO(posRect.w, posRect.h);
 | 
							TEXFBO &gpTex2 = shState->gpTexFBO(posRect.w, posRect.h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FBO::bind(gpTex2.fbo, FBO::Draw);
 | 
							GLMeta::blitBegin(gpTex2);
 | 
				
			||||||
		FBO::bind(p->gl.fbo, FBO::Read);
 | 
							GLMeta::blitSource(p->gl);
 | 
				
			||||||
		FBO::blit(posRect.x, posRect.y, 0, 0, posRect.w, posRect.h);
 | 
							GLMeta::blitRectangle(posRect, Vec2i());
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FloatRect bltRect(0, 0,
 | 
							FloatRect bltRect(0, 0,
 | 
				
			||||||
		                  (float) gpTexSize.x / gpTex2.width,
 | 
							                  (float) gpTexSize.x / gpTex2.width,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,12 +120,7 @@ typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, co
 | 
				
			||||||
	GL_FUN(BindFramebuffer, PFNGLBINDFRAMEBUFFERPROC) \
 | 
						GL_FUN(BindFramebuffer, PFNGLBINDFRAMEBUFFERPROC) \
 | 
				
			||||||
	GL_FUN(FramebufferTexture2D, PFNGLFRAMEBUFFERTEXTURE2DPROC) \
 | 
						GL_FUN(FramebufferTexture2D, PFNGLFRAMEBUFFERTEXTURE2DPROC) \
 | 
				
			||||||
	GL_FUN(FramebufferRenderbuffer, PFNGLFRAMEBUFFERRENDERBUFFERPROC) \
 | 
						GL_FUN(FramebufferRenderbuffer, PFNGLFRAMEBUFFERRENDERBUFFERPROC) \
 | 
				
			||||||
	GL_FUN(BlitFramebuffer, PFNGLBLITFRAMEBUFFERPROC) \
 | 
						GL_FUN(BlitFramebuffer, PFNGLBLITFRAMEBUFFERPROC)
 | 
				
			||||||
	/* Renderbuffer object */ \
 | 
					 | 
				
			||||||
	GL_FUN(GenRenderbuffers, PFNGLGENRENDERBUFFERSPROC) \
 | 
					 | 
				
			||||||
	GL_FUN(DeleteRenderbuffers, PFNGLDELETERENDERBUFFERSPROC) \
 | 
					 | 
				
			||||||
	GL_FUN(BindRenderbuffer, PFNGLBINDRENDERBUFFERPROC) \
 | 
					 | 
				
			||||||
	GL_FUN(RenderbufferStorage, PFNGLRENDERBUFFERSTORAGEPROC)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GL_VAO_FUN \
 | 
					#define GL_VAO_FUN \
 | 
				
			||||||
	/* Vertex array object */ \
 | 
						/* Vertex array object */ \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gl-meta.h"
 | 
					#include "gl-meta.h"
 | 
				
			||||||
#include "gl-fun.h"
 | 
					#include "gl-fun.h"
 | 
				
			||||||
 | 
					#include "sharedstate.h"
 | 
				
			||||||
 | 
					#include "glstate.h"
 | 
				
			||||||
 | 
					#include "quad.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace GLMeta
 | 
					namespace GLMeta
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -121,4 +124,81 @@ void vaoUnbind(VAO &vao)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HAVE_NATIVE_BLIT gl.BlitFramebuffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void _blitBegin(FBO::ID fbo, const Vec2i &size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (HAVE_NATIVE_BLIT)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FBO::bind(fbo, FBO::Draw);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FBO::bind(fbo, FBO::Generic);
 | 
				
			||||||
 | 
							glState.viewport.pushSet(IntRect(0, 0, size.x, size.y));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SimpleShader &shader = shState->shaders().simple;
 | 
				
			||||||
 | 
							shader.bind();
 | 
				
			||||||
 | 
							shader.applyViewportProj();
 | 
				
			||||||
 | 
							shader.setTranslation(Vec2i());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blitBegin(TEXFBO &target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						_blitBegin(target.fbo, Vec2i(target.width, target.height));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blitBeginScreen(const Vec2i &size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						_blitBegin(FBO::ID(0), size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blitSource(TEXFBO &source)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (HAVE_NATIVE_BLIT)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FBO::bind(source.fbo, FBO::Read);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SimpleShader &shader = shState->shaders().simple;
 | 
				
			||||||
 | 
							shader.setTexSize(Vec2i(source.width, source.height));
 | 
				
			||||||
 | 
							TEX::bind(source.tex);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blitRectangle(const IntRect &src, const Vec2i &dstPos, FBO::BlitMode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						blitRectangle(src, IntRect(dstPos.x, dstPos.y, src.w, src.h), mode);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blitRectangle(const IntRect &src, const IntRect &dst, FBO::BlitMode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (HAVE_NATIVE_BLIT)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FBO::blit(src.x, src.y, src.w, src.h,
 | 
				
			||||||
 | 
							          dst.x, dst.y, dst.w, dst.h,
 | 
				
			||||||
 | 
							          mode);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (mode == FBO::Linear)
 | 
				
			||||||
 | 
								TEX::setSmooth(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Quad &quad = shState->gpQuad();
 | 
				
			||||||
 | 
							quad.setTexPosRect(src, dst);
 | 
				
			||||||
 | 
							quad.draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mode == FBO::Linear)
 | 
				
			||||||
 | 
								TEX::setSmooth(false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blitFinish()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!HAVE_NATIVE_BLIT)
 | 
				
			||||||
 | 
							glState.viewport.pop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,16 @@ void vaoFini(VAO &vao);
 | 
				
			||||||
void vaoBind(VAO &vao);
 | 
					void vaoBind(VAO &vao);
 | 
				
			||||||
void vaoUnbind(VAO &vao);
 | 
					void vaoUnbind(VAO &vao);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* EXT_framebuffer_blit */
 | 
				
			||||||
 | 
					void blitBegin(TEXFBO &target);
 | 
				
			||||||
 | 
					void blitBeginScreen(const Vec2i &size);
 | 
				
			||||||
 | 
					void blitSource(TEXFBO &source);
 | 
				
			||||||
 | 
					void blitRectangle(const IntRect &src, const Vec2i &dstPos,
 | 
				
			||||||
 | 
					                   FBO::BlitMode mode = FBO::Nearest);
 | 
				
			||||||
 | 
					void blitRectangle(const IntRect &src, const IntRect &dst,
 | 
				
			||||||
 | 
					                   FBO::BlitMode mode = FBO::Nearest);
 | 
				
			||||||
 | 
					void blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // GLMETA_H
 | 
					#endif // GLMETA_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,40 +100,6 @@ namespace TEX
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Renderbuffer Object */
 | 
					 | 
				
			||||||
namespace RBO
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DEF_GL_ID
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline ID gen()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ID id;
 | 
					 | 
				
			||||||
		gl.GenRenderbuffers(1, &id.gl);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return id;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void del(ID id)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		gl.DeleteRenderbuffers(1, &id.gl);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void bind(ID id)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		gl.BindRenderbuffer(GL_RENDERBUFFER, id.gl);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void unbind()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		bind(ID(0));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void allocEmpty(GLsizei width, GLsizei height)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		gl.RenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Framebuffer Object */
 | 
					/* Framebuffer Object */
 | 
				
			||||||
namespace FBO
 | 
					namespace FBO
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -142,7 +108,8 @@ namespace FBO
 | 
				
			||||||
	enum Mode
 | 
						enum Mode
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Draw = 0,
 | 
							Draw = 0,
 | 
				
			||||||
		Read = 1
 | 
							Read = 1,
 | 
				
			||||||
 | 
							Generic = 2
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum BlitMode
 | 
						enum BlitMode
 | 
				
			||||||
| 
						 | 
					@ -169,7 +136,8 @@ namespace FBO
 | 
				
			||||||
		static const GLenum modes[] =
 | 
							static const GLenum modes[] =
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			GL_DRAW_FRAMEBUFFER,
 | 
								GL_DRAW_FRAMEBUFFER,
 | 
				
			||||||
			GL_READ_FRAMEBUFFER
 | 
								GL_READ_FRAMEBUFFER,
 | 
				
			||||||
 | 
								GL_FRAMEBUFFER
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gl.BindFramebuffer(modes[mode], id.gl);
 | 
							gl.BindFramebuffer(modes[mode], id.gl);
 | 
				
			||||||
| 
						 | 
					@ -185,11 +153,6 @@ namespace FBO
 | 
				
			||||||
		gl.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_TEXTURE_2D, target.gl, 0);
 | 
							gl.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_TEXTURE_2D, target.gl, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void setTarget(RBO::ID target, unsigned colorAttach = 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		gl.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_RENDERBUFFER, target.gl);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void blit(int srcX, int srcY,
 | 
						inline void blit(int srcX, int srcY,
 | 
				
			||||||
	                 int srcW, int srcH,
 | 
						                 int srcW, int srcH,
 | 
				
			||||||
	                 int dstX, int dstY,
 | 
						                 int dstX, int dstY,
 | 
				
			||||||
| 
						 | 
					@ -367,43 +330,4 @@ struct TEXFBO
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Convenience struct wrapping a framebuffer
 | 
					 | 
				
			||||||
 * and a renderbuffer as its target */
 | 
					 | 
				
			||||||
struct RBOFBO
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	RBO::ID rbo;
 | 
					 | 
				
			||||||
	FBO::ID fbo;
 | 
					 | 
				
			||||||
	int width, height;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	RBOFBO()
 | 
					 | 
				
			||||||
	    : rbo(0), fbo(0), width(0), height(0)
 | 
					 | 
				
			||||||
	{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static inline void init(RBOFBO &obj)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		obj.rbo = RBO::gen();
 | 
					 | 
				
			||||||
		obj.fbo = FBO::gen();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static inline void allocEmpty(RBOFBO &obj, int width, int height)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		RBO::bind(obj.rbo);
 | 
					 | 
				
			||||||
		RBO::allocEmpty(width, height);
 | 
					 | 
				
			||||||
		obj.width = width;
 | 
					 | 
				
			||||||
		obj.height = height;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static inline void linkFBO(RBOFBO &obj)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		FBO::bind(obj.fbo, FBO::Draw);
 | 
					 | 
				
			||||||
		FBO::setTarget(obj.rbo);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static inline void fini(RBOFBO &obj)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		FBO::del(obj.fbo);
 | 
					 | 
				
			||||||
		RBO::del(obj.rbo);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // GLUTIL_H
 | 
					#endif // GLUTIL_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										144
									
								
								src/graphics.cpp
									
										
									
									
									
								
							
							
						
						
									
										144
									
								
								src/graphics.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -70,10 +70,14 @@ struct PingPong
 | 
				
			||||||
			TEXFBO::fini(rt[i]);
 | 
								TEXFBO::fini(rt[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Binds FBO of last good buffer for reading */
 | 
						TEXFBO &backBuffer()
 | 
				
			||||||
	void bindLastBuffer()
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		FBO::bind(rt[dstInd].fbo, FBO::Read);
 | 
							return rt[srcInd];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TEXFBO &frontBuffer()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return rt[dstInd];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Better not call this during render cycles */
 | 
						/* Better not call this during render cycles */
 | 
				
			||||||
| 
						 | 
					@ -100,23 +104,10 @@ struct PingPong
 | 
				
			||||||
		bind();
 | 
							bind();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void blitFBOs()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		FBO::blit(0, 0, 0, 0, screenW, screenH);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void finishRender()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		FBO::unbind(FBO::Draw);
 | 
					 | 
				
			||||||
		FBO::bind(rt[dstInd].fbo, FBO::Read);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void bind()
 | 
						void bind()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		TEX::bind(rt[srcInd].tex);
 | 
							FBO::bind(rt[dstInd].fbo, FBO::Generic);
 | 
				
			||||||
		FBO::bind(rt[srcInd].fbo, FBO::Read);
 | 
					 | 
				
			||||||
		FBO::bind(rt[dstInd].fbo, FBO::Draw);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,8 +151,6 @@ public:
 | 
				
			||||||
			brightnessQuad.draw();
 | 
								brightnessQuad.draw();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
		pp.finishRender();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void requestViewportRender(Vec4 &c, Vec4 &f, Vec4 &t)
 | 
						void requestViewportRender(Vec4 &c, Vec4 &f, Vec4 &t)
 | 
				
			||||||
| 
						 | 
					@ -172,7 +161,12 @@ public:
 | 
				
			||||||
		 * and since we're inside the draw cycle, it will
 | 
							 * and since we're inside the draw cycle, it will
 | 
				
			||||||
		 * be turned on, so turn it off temporarily */
 | 
							 * be turned on, so turn it off temporarily */
 | 
				
			||||||
		glState.scissorTest.pushSet(false);
 | 
							glState.scissorTest.pushSet(false);
 | 
				
			||||||
		pp.blitFBOs();
 | 
					
 | 
				
			||||||
 | 
							GLMeta::blitBegin(pp.frontBuffer());
 | 
				
			||||||
 | 
							GLMeta::blitSetSource(pp.backBuffer());
 | 
				
			||||||
 | 
							GLMeta::blitRectangle(geometry.rect, Vec2i());
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glState.scissorTest.pop();
 | 
							glState.scissorTest.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PlaneShader &shader = shState->shaders().plane;
 | 
							PlaneShader &shader = shState->shaders().plane;
 | 
				
			||||||
| 
						 | 
					@ -184,6 +178,8 @@ public:
 | 
				
			||||||
		shader.applyViewportProj();
 | 
							shader.applyViewportProj();
 | 
				
			||||||
		shader.setTexSize(geometry.rect.size());
 | 
							shader.setTexSize(geometry.rect.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TEX::bind(pp.backBuffer().tex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glState.blendMode.pushSet(BlendNone);
 | 
							glState.blendMode.pushSet(BlendNone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		screenQuad.draw();
 | 
							screenQuad.draw();
 | 
				
			||||||
| 
						 | 
					@ -399,7 +395,7 @@ struct GraphicsPrivate
 | 
				
			||||||
	TEXFBO frozenScene;
 | 
						TEXFBO frozenScene;
 | 
				
			||||||
	TEXFBO currentScene;
 | 
						TEXFBO currentScene;
 | 
				
			||||||
	Quad screenQuad;
 | 
						Quad screenQuad;
 | 
				
			||||||
	RBOFBO transBuffer;
 | 
						TEXFBO transBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GraphicsPrivate(RGSSThreadData *rtData)
 | 
						GraphicsPrivate(RGSSThreadData *rtData)
 | 
				
			||||||
	    : scRes(640, 480),
 | 
						    : scRes(640, 480),
 | 
				
			||||||
| 
						 | 
					@ -429,9 +425,9 @@ struct GraphicsPrivate
 | 
				
			||||||
		FloatRect screenRect(0, 0, scRes.x, scRes.y);
 | 
							FloatRect screenRect(0, 0, scRes.x, scRes.y);
 | 
				
			||||||
		screenQuad.setTexPosRect(screenRect, screenRect);
 | 
							screenQuad.setTexPosRect(screenRect, screenRect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RBOFBO::init(transBuffer);
 | 
							TEXFBO::init(transBuffer);
 | 
				
			||||||
		RBOFBO::allocEmpty(transBuffer, scRes.x, scRes.y);
 | 
							TEXFBO::allocEmpty(transBuffer, scRes.x, scRes.y);
 | 
				
			||||||
		RBOFBO::linkFBO(transBuffer);
 | 
							TEXFBO::linkFBO(transBuffer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~GraphicsPrivate()
 | 
						~GraphicsPrivate()
 | 
				
			||||||
| 
						 | 
					@ -439,7 +435,7 @@ struct GraphicsPrivate
 | 
				
			||||||
		TEXFBO::fini(frozenScene);
 | 
							TEXFBO::fini(frozenScene);
 | 
				
			||||||
		TEXFBO::fini(currentScene);
 | 
							TEXFBO::fini(currentScene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RBOFBO::fini(transBuffer);
 | 
							TEXFBO::fini(transBuffer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updateScreenResoRatio(RGSSThreadData *rtData)
 | 
						void updateScreenResoRatio(RGSSThreadData *rtData)
 | 
				
			||||||
| 
						 | 
					@ -503,25 +499,34 @@ struct GraphicsPrivate
 | 
				
			||||||
		threadData->ethread->notifyFrame();
 | 
							threadData->ethread->notifyFrame();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void compositeToBuffer(FBO::ID fbo)
 | 
						void compositeToBuffer(TEXFBO &buffer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		screen.composite();
 | 
							screen.composite();
 | 
				
			||||||
		FBO::bind(fbo, FBO::Draw);
 | 
					
 | 
				
			||||||
		FBO::blit(0, 0, 0, 0, scRes.x, scRes.y);
 | 
							GLMeta::blitBegin(buffer);
 | 
				
			||||||
 | 
							GLMeta::blitSetSource(screen.getPP().frontBuffer());
 | 
				
			||||||
 | 
							GLMeta::blitRectangle(IntRect(0, 0, scRes.x, scRes.y), Vec2i());
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void blitBufferFlippedScaled()
 | 
						void metaBlitBufferFlippedScaled()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		FBO::blit(0, 0, scRes.x, scRes.y,
 | 
							GLMeta::blitRectangle(IntRect(0, 0, scRes.x, scRes.y),
 | 
				
			||||||
		          scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y,
 | 
							                      IntRect(scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y),
 | 
				
			||||||
		          threadData->config.smoothScaling ? FBO::Linear : FBO::Nearest);
 | 
							                      threadData->config.smoothScaling ? FBO::Linear : FBO::Nearest);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void redrawScreen()
 | 
						void redrawScreen()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		screen.composite();
 | 
							screen.composite();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							GLMeta::blitBeginScreen(winSize);
 | 
				
			||||||
 | 
							GLMeta::blitSetSource(screen.getPP().frontBuffer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FBO::clear();
 | 
							FBO::clear();
 | 
				
			||||||
		blitBufferFlippedScaled();
 | 
							metaBlitBufferFlippedScaled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		swapGLBuffer();
 | 
							swapGLBuffer();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -579,7 +584,7 @@ void Graphics::freeze()
 | 
				
			||||||
	p->checkResize();
 | 
						p->checkResize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Capture scene into frozen buffer */
 | 
						/* Capture scene into frozen buffer */
 | 
				
			||||||
	p->compositeToBuffer(p->frozenScene.fbo);
 | 
						p->compositeToBuffer(p->frozenScene);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::transition(int duration,
 | 
					void Graphics::transition(int duration,
 | 
				
			||||||
| 
						 | 
					@ -594,13 +599,16 @@ void Graphics::transition(int duration,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Capture new scene */
 | 
						/* Capture new scene */
 | 
				
			||||||
	p->compositeToBuffer(p->currentScene.fbo);
 | 
						p->compositeToBuffer(p->currentScene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If no transition bitmap is provided,
 | 
						/* If no transition bitmap is provided,
 | 
				
			||||||
	 * we can use a simplified shader */
 | 
						 * we can use a simplified shader */
 | 
				
			||||||
 | 
						TransShader &transShader = shState->shaders().trans;
 | 
				
			||||||
 | 
						SimpleTransShader &simpleShader = shState->shaders().simpleTrans;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (transMap)
 | 
						if (transMap)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		TransShader &shader = shState->shaders().trans;
 | 
							TransShader &shader = transShader;
 | 
				
			||||||
		shader.bind();
 | 
							shader.bind();
 | 
				
			||||||
		shader.applyViewportProj();
 | 
							shader.applyViewportProj();
 | 
				
			||||||
		shader.setFrozenScene(p->frozenScene.tex);
 | 
							shader.setFrozenScene(p->frozenScene.tex);
 | 
				
			||||||
| 
						 | 
					@ -611,7 +619,7 @@ void Graphics::transition(int duration,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SimpleTransShader &shader = shState->shaders().simpleTrans;
 | 
							SimpleTransShader &shader = simpleShader;
 | 
				
			||||||
		shader.bind();
 | 
							shader.bind();
 | 
				
			||||||
		shader.applyViewportProj();
 | 
							shader.applyViewportProj();
 | 
				
			||||||
		shader.setFrozenScene(p->frozenScene.tex);
 | 
							shader.setFrozenScene(p->frozenScene.tex);
 | 
				
			||||||
| 
						 | 
					@ -632,23 +640,32 @@ void Graphics::transition(int duration,
 | 
				
			||||||
		const float prog = i * (1.0 / duration);
 | 
							const float prog = i * (1.0 / duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (transMap)
 | 
							if (transMap)
 | 
				
			||||||
			shState->shaders().trans.setProg(prog);
 | 
							{
 | 
				
			||||||
 | 
								transShader.bind();
 | 
				
			||||||
 | 
								transShader.setProg(prog);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			shState->shaders().simpleTrans.setProg(prog);
 | 
							{
 | 
				
			||||||
 | 
								simpleShader.bind();
 | 
				
			||||||
 | 
								simpleShader.setProg(prog);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Draw the composed frame to a buffer first
 | 
							/* Draw the composed frame to a buffer first
 | 
				
			||||||
		 * (we need this because we're skipping PingPong) */
 | 
							 * (we need this because we're skipping PingPong) */
 | 
				
			||||||
		FBO::bind(p->transBuffer.fbo, FBO::Draw);
 | 
							FBO::bind(p->transBuffer.fbo, FBO::Generic);
 | 
				
			||||||
		FBO::clear();
 | 
							FBO::clear();
 | 
				
			||||||
		p->screenQuad.draw();
 | 
							p->screenQuad.draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p->checkResize();
 | 
							p->checkResize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Then blit it flipped and scaled to the screen */
 | 
							/* Then blit it flipped and scaled to the screen */
 | 
				
			||||||
		FBO::bind(p->transBuffer.fbo, FBO::Read);
 | 
							FBO::unbind(FBO::Generic);
 | 
				
			||||||
		FBO::unbind(FBO::Draw);
 | 
					 | 
				
			||||||
		FBO::clear();
 | 
							FBO::clear();
 | 
				
			||||||
		p->blitBufferFlippedScaled();
 | 
					
 | 
				
			||||||
 | 
							GLMeta::blitBeginScreen(Vec2i(p->winSize));
 | 
				
			||||||
 | 
							GLMeta::blitSetSource(p->transBuffer);
 | 
				
			||||||
 | 
							p->metaBlitBufferFlippedScaled();
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p->swapGLBuffer();
 | 
							p->swapGLBuffer();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -699,10 +716,7 @@ void Graphics::wait(int duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::fadeout(int duration)
 | 
					void Graphics::fadeout(int duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (p->frozen)
 | 
						FBO::unbind(FBO::Generic);
 | 
				
			||||||
		FBO::bind(p->frozenScene.fbo, FBO::Read);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	FBO::unbind(FBO::Draw);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = duration-1; i > -1; --i)
 | 
						for (int i = duration-1; i > -1; --i)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -710,8 +724,14 @@ void Graphics::fadeout(int duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (p->frozen)
 | 
							if (p->frozen)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								GLMeta::blitBeginScreen(p->scSize);
 | 
				
			||||||
 | 
								GLMeta::blitSetSource(p->frozenScene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			FBO::clear();
 | 
								FBO::clear();
 | 
				
			||||||
			p->blitBufferFlippedScaled();
 | 
								p->metaBlitBufferFlippedScaled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			p->swapGLBuffer();
 | 
								p->swapGLBuffer();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -723,10 +743,7 @@ void Graphics::fadeout(int duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::fadein(int duration)
 | 
					void Graphics::fadein(int duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (p->frozen)
 | 
						FBO::unbind(FBO::Generic);
 | 
				
			||||||
		FBO::bind(p->frozenScene.fbo, FBO::Read);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	FBO::unbind(FBO::Draw);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = 0; i < duration; ++i)
 | 
						for (int i = 0; i < duration; ++i)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -734,8 +751,14 @@ void Graphics::fadein(int duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (p->frozen)
 | 
							if (p->frozen)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								GLMeta::blitBeginScreen(p->scSize);
 | 
				
			||||||
 | 
								GLMeta::blitSetSource(p->frozenScene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			FBO::clear();
 | 
								FBO::clear();
 | 
				
			||||||
			p->blitBufferFlippedScaled();
 | 
								p->metaBlitBufferFlippedScaled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			p->swapGLBuffer();
 | 
								p->swapGLBuffer();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -749,7 +772,7 @@ Bitmap *Graphics::snapToBitmap()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Bitmap *bitmap = new Bitmap(width(), height());
 | 
						Bitmap *bitmap = new Bitmap(width(), height());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->compositeToBuffer(bitmap->getGLTypes().fbo);
 | 
						p->compositeToBuffer(bitmap->getGLTypes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Taint entire bitmap */
 | 
						/* Taint entire bitmap */
 | 
				
			||||||
	bitmap->taintArea(IntRect(0, 0, width(), height()));
 | 
						bitmap->taintArea(IntRect(0, 0, width(), height()));
 | 
				
			||||||
| 
						 | 
					@ -791,8 +814,8 @@ void Graphics::resizeScreen(int width, int height)
 | 
				
			||||||
	FloatRect screenRect(0, 0, width, height);
 | 
						FloatRect screenRect(0, 0, width, height);
 | 
				
			||||||
	p->screenQuad.setTexPosRect(screenRect, screenRect);
 | 
						p->screenQuad.setTexPosRect(screenRect, screenRect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RBO::bind(p->transBuffer.rbo);
 | 
						TEX::bind(p->transBuffer.tex);
 | 
				
			||||||
	RBO::allocEmpty(width, height);
 | 
						TEX::allocEmpty(width, height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->updateScreenResoRatio(p->threadData);
 | 
						p->updateScreenResoRatio(p->threadData);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -843,18 +866,21 @@ void Graphics::repaintWait(volatile bool *exitCond)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Repaint the screen with the last good frame we drew */
 | 
						/* Repaint the screen with the last good frame we drew */
 | 
				
			||||||
	p->screen.getPP().bindLastBuffer();
 | 
						TEXFBO &lastFrame = p->screen.getPP().frontBuffer();
 | 
				
			||||||
	FBO::unbind(FBO::Draw);
 | 
						GLMeta::blitBeginScreen(p->winSize);
 | 
				
			||||||
 | 
						GLMeta::blitSetSource(lastFrame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (!*exitCond)
 | 
						while (!*exitCond)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		shState->checkShutdown();
 | 
							shState->checkShutdown();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FBO::clear();
 | 
							FBO::clear();
 | 
				
			||||||
		p->blitBufferFlippedScaled();
 | 
							p->metaBlitBufferFlippedScaled();
 | 
				
			||||||
		SDL_GL_SwapWindow(p->threadData->window);
 | 
							SDL_GL_SwapWindow(p->threadData->window);
 | 
				
			||||||
		p->fpsLimiter.delay();
 | 
							p->fpsLimiter.delay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p->threadData->ethread->notifyFrame();
 | 
							p->threadData->ethread->notifyFrame();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GLMeta::blitFinish();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -294,17 +294,17 @@ TransShader::TransShader()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TransShader::setCurrentScene(TEX::ID tex)
 | 
					void TransShader::setCurrentScene(TEX::ID tex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setTexUniform(u_currentScene, 0, tex);
 | 
						setTexUniform(u_currentScene, 1, tex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TransShader::setFrozenScene(TEX::ID tex)
 | 
					void TransShader::setFrozenScene(TEX::ID tex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setTexUniform(u_frozenScene, 1, tex);
 | 
						setTexUniform(u_frozenScene, 2, tex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TransShader::setTransMap(TEX::ID tex)
 | 
					void TransShader::setTransMap(TEX::ID tex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setTexUniform(u_transMap, 2, tex);
 | 
						setTexUniform(u_transMap, 3, tex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TransShader::setProg(float value)
 | 
					void TransShader::setProg(float value)
 | 
				
			||||||
| 
						 | 
					@ -331,12 +331,12 @@ SimpleTransShader::SimpleTransShader()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SimpleTransShader::setCurrentScene(TEX::ID tex)
 | 
					void SimpleTransShader::setCurrentScene(TEX::ID tex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setTexUniform(u_currentScene, 0, tex);
 | 
						setTexUniform(u_currentScene, 1, tex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SimpleTransShader::setFrozenScene(TEX::ID tex)
 | 
					void SimpleTransShader::setFrozenScene(TEX::ID tex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setTexUniform(u_frozenScene, 1, tex);
 | 
						setTexUniform(u_frozenScene, 2, tex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SimpleTransShader::setProg(float value)
 | 
					void SimpleTransShader::setProg(float value)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,7 +551,7 @@ struct TilemapPrivate
 | 
				
			||||||
		TileAtlas::BlitVec blits = TileAtlas::calcBlits(atlas.efTilesetH, atlas.size);
 | 
							TileAtlas::BlitVec blits = TileAtlas::calcBlits(atlas.efTilesetH, atlas.size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Clear atlas */
 | 
							/* Clear atlas */
 | 
				
			||||||
		FBO::bind(atlas.gl.fbo, FBO::Draw);
 | 
							FBO::bind(atlas.gl.fbo, FBO::Generic);
 | 
				
			||||||
		glState.clearColor.pushSet(Vec4());
 | 
							glState.clearColor.pushSet(Vec4());
 | 
				
			||||||
		glState.scissorTest.pushSet(false);
 | 
							glState.scissorTest.pushSet(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -560,6 +560,8 @@ struct TilemapPrivate
 | 
				
			||||||
		glState.scissorTest.pop();
 | 
							glState.scissorTest.pop();
 | 
				
			||||||
		glState.clearColor.pop();
 | 
							glState.clearColor.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							GLMeta::blitBegin(atlas.gl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Blit autotiles */
 | 
							/* Blit autotiles */
 | 
				
			||||||
		for (size_t i = 0; i < atlas.usableATs.size(); ++i)
 | 
							for (size_t i = 0; i < atlas.usableATs.size(); ++i)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -569,26 +571,29 @@ struct TilemapPrivate
 | 
				
			||||||
			int blitW = std::min(autotile->width(), atAreaW);
 | 
								int blitW = std::min(autotile->width(), atAreaW);
 | 
				
			||||||
			int blitH = std::min(autotile->height(), atAreaH);
 | 
								int blitH = std::min(autotile->height(), atAreaH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			FBO::bind(autotile->getGLTypes().fbo, FBO::Read);
 | 
								GLMeta::blitSource(autotile->getGLTypes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (blitW <= autotileW && tiles.animated)
 | 
								if (blitW <= autotileW && tiles.animated)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				/* Static autotile */
 | 
									/* Static autotile */
 | 
				
			||||||
				for (int j = 0; j < 4; ++j)
 | 
									for (int j = 0; j < 4; ++j)
 | 
				
			||||||
					FBO::blit(0, 0, autotileW*j, atInd*autotileH, blitW, blitH);
 | 
										GLMeta::blitRectangle(IntRect(0, 0, blitW, blitH),
 | 
				
			||||||
 | 
										                      Vec2i(autotileW*j, atInd*autotileH));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				/* Animated autotile */
 | 
									/* Animated autotile */
 | 
				
			||||||
				FBO::blit(0, 0, 0, atInd*autotileH, blitW, blitH);
 | 
									GLMeta::blitRectangle(IntRect(0, 0, blitW, blitH),
 | 
				
			||||||
 | 
									                      Vec2i(0, atInd*autotileH));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							GLMeta::blitFinish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Blit tileset */
 | 
							/* Blit tileset */
 | 
				
			||||||
		if (tileset->megaSurface())
 | 
							if (tileset->megaSurface())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* Mega surface tileset */
 | 
								/* Mega surface tileset */
 | 
				
			||||||
			FBO::unbind(FBO::Draw);
 | 
					 | 
				
			||||||
			TEX::bind(atlas.gl.tex);
 | 
								TEX::bind(atlas.gl.tex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			SDL_Surface *tsSurf = tileset->megaSurface();
 | 
								SDL_Surface *tsSurf = tileset->megaSurface();
 | 
				
			||||||
| 
						 | 
					@ -606,14 +611,18 @@ struct TilemapPrivate
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* Regular tileset */
 | 
								/* Regular tileset */
 | 
				
			||||||
			FBO::bind(tileset->getGLTypes().fbo, FBO::Read);
 | 
								GLMeta::blitBegin(atlas.gl);
 | 
				
			||||||
 | 
								GLMeta::blitSource(tileset->getGLTypes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (size_t i = 0; i < blits.size(); ++i)
 | 
								for (size_t i = 0; i < blits.size(); ++i)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				const TileAtlas::Blit &blitOp = blits[i];
 | 
									const TileAtlas::Blit &blitOp = blits[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				FBO::blit(blitOp.src.x, blitOp.src.y, blitOp.dst.x, blitOp.dst.y, tsLaneW, blitOp.h);
 | 
									GLMeta::blitRectangle(IntRect(blitOp.src.x, blitOp.src.y, tsLaneW, blitOp.h),
 | 
				
			||||||
 | 
									                      blitOp.dst);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								GLMeta::blitFinish();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -416,7 +416,7 @@ struct WindowPrivate
 | 
				
			||||||
		TEX::allocEmpty(baseTex.width, baseTex.height);
 | 
							TEX::allocEmpty(baseTex.width, baseTex.height);
 | 
				
			||||||
		TEX::unbind();
 | 
							TEX::unbind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FBO::bind(baseTex.fbo, FBO::Draw);
 | 
							FBO::bind(baseTex.fbo, FBO::Generic);
 | 
				
			||||||
		glState.viewport.pushSet(IntRect(0, 0, baseTex.width, baseTex.height));
 | 
							glState.viewport.pushSet(IntRect(0, 0, baseTex.width, baseTex.height));
 | 
				
			||||||
		glState.clearColor.pushSet(Vec4());
 | 
							glState.clearColor.pushSet(Vec4());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue