Browse Source

- PPS blending
- UI

Panagiotis Christopoulos Charitos 14 years ago
parent
commit
16aaec0f10

File diff suppressed because it is too large
+ 0 - 1
build/debug/Makefile


File diff suppressed because it is too large
+ 1 - 1
build/release/Makefile


BIN
engine-rsrc/fontmap.png


+ 6 - 3
shaders/PpsSideBlur.glsl

@@ -6,13 +6,16 @@
 
 #pragma anki fragShaderBegins
 
-uniform sampler2D tex;
 in vec2 vTexCoords;
+
+uniform sampler2D tex;
+uniform float factor = 1.0;
+
 layout(location = 0) out vec3 fFragColor;
 
 
 void main()
 {
-	float factor = texture2D(tex, vTexCoords).r;
-	fFragColor = vec3(0.0, 0.0, factor * 2.0);
+	float f = texture2D(tex, vTexCoords).r;
+	fFragColor = vec3(0.0, 0.0, f * factor);
 }

+ 5 - 3
shaders/Ui.glsl → shaders/UiText.glsl

@@ -2,7 +2,7 @@
 
 layout(location = 0) in vec2 position;
 
-uniform mat3 tranformation; ///< Position transformation
+uniform mat3 transformation; ///< Position transformation
 uniform mat3 textureTranformation; ///< Texture transformation
 
 out vec2 vTexCoords;
@@ -10,8 +10,9 @@ out vec2 vTexCoords;
 
 void main(void)
 {
-	vTexCoords = (textureTranformation * vec3(position, 1.0)).xy;
-	gl_Position = vec4(tranformation * position, 1.0);
+	vec3 pos3d = vec3(position, 1.0);
+	vTexCoords = (textureTranformation * pos3d).xy;
+	gl_Position = vec4(transformation * pos3d, 1.0);
 }
 
 #pragma anki fragShaderBegins
@@ -29,4 +30,5 @@ void main()
 	vec4 texCol = texture2D(texture, vTexCoords).rgba * color;
 
 	fColor = texCol;
+	//fColor = texCol - texCol + vec4(1.0, 0.0, 1.0, 0.1);
 }

+ 3 - 2
src/Core/App.cpp

@@ -217,8 +217,9 @@ void App::initRenderer()
 	initializer.pps.ssao.blurringIterationsNum = 4;
 	initializer.pps.ssao.enabled = true;
 	initializer.pps.ssao.renderingQuality = 0.3;
-	initializer.pps.blurringEnabled = true;
-	initializer.pps.blurringIterationsNum = 2;
+	initializer.pps.bl.enabled = true;
+	initializer.pps.bl.blurringIterationsNum = 2;
+	initializer.pps.bl.sideBlurFactor = 1.0;
 	initializer.mainRendererQuality = 1.0;
 
 	MainRendererSingleton::getInstance().init(initializer);

+ 11 - 16
src/Main.cpp

@@ -51,6 +51,8 @@ SpotLight* spot_lights[2];
 ParticleEmitter* partEmitter;
 PhyCharacter* character;
 
+Ui::Painter* painter;
+
 
 // Physics
 Vec<btRigidBody*> boxes;
@@ -120,7 +122,7 @@ void init()
 
 	srand(unsigned(time(NULL)));
 
-	//Ui::init();
+	painter = new Ui::Painter;
 
 	// camera
 	PerspectiveCamera* cam = new PerspectiveCamera(false, NULL);
@@ -293,7 +295,8 @@ void mainLoopExtra()
 	if(InputSingleton::getInstance().getKey(SDL_SCANCODE_PAGEUP)) mover->getLocalTransform().getScale() += scale ;
 	if(InputSingleton::getInstance().getKey(SDL_SCANCODE_PAGEDOWN)) mover->getLocalTransform().getScale() -= scale ;
 
-	if(InputSingleton::getInstance().getKey(SDL_SCANCODE_K)) AppSingleton::getInstance().getActiveCam()->lookAtPoint(point_lights[0]->getWorldTransform().getOrigin());
+	if(InputSingleton::getInstance().getKey(SDL_SCANCODE_K))
+		AppSingleton::getInstance().getActiveCam()->lookAtPoint(point_lights[0]->getWorldTransform().getOrigin());
 
 	if(InputSingleton::getInstance().getKey(SDL_SCANCODE_I))
 		character->moveForward(0.1);
@@ -364,6 +367,12 @@ void mainLoop()
 
 		MainRendererSingleton::getInstance().render(*AppSingleton::getInstance().getActiveCam());
 
+		painter->setPosition(Vec2(0.0, 0.0));
+		painter->setFontSize(Vec2(0.03, 0.03 * MainRendererSingleton::getInstance().getAspectRatio()));
+		painter->setColor(Vec4(1.0));
+
+		painter->drawText("Once upon a time in a place\ncalled \"Kickapoo\"");
+
 		if(InputSingleton::getInstance().getKey(SDL_SCANCODE_ESCAPE))
 		{
 			break;
@@ -422,20 +431,6 @@ void mainLoop()
 //======================================================================================================================
 int main(int argc, char* argv[])
 {
-	/*float depth = 0.5;
-
-	Vec3 vViewVector(1.0264, 0.57735, -1);
-	Vec2 planes(-1.00251, -0.501253);
-
-	Vec3 fragPosVspace;
-	Vec3 vposn = vViewVector.getNormalized();
-	fragPosVspace.z() = -planes.y() / (planes.x() + depth);
-	fragPosVspace.x() = vposn.x() * (fragPosVspace.z() / vposn.z());
-	fragPosVspace.y() = vposn.y() * (fragPosVspace.z() / vposn.z());
-	std::cout << fragPosVspace << std::endl;
-
-	return 0;*/
-
 	try
 	{
 		AppSingleton::getInstance().init(argc, argv);

+ 153 - 0
src/Renderer/Bl.cpp

@@ -0,0 +1,153 @@
+#include "Bl.h"
+#include "RendererInitializer.h"
+#include "Renderer.h"
+#include "ShaderProg.h"
+
+
+//======================================================================================================================
+// Constructor                                                                                                         =
+//======================================================================================================================
+Bl::Bl(Renderer& r_):
+	RenderingPass(r_)
+{}
+
+
+//======================================================================================================================
+// init                                                                                                                =
+//======================================================================================================================
+void Bl::init(const RendererInitializer& initializer)
+{
+	enabled = initializer.pps.bl.enabled;
+	blurringIterationsNum = initializer.pps.bl.blurringIterationsNum;
+	sideBlurFactor = initializer.pps.bl.sideBlurFactor;
+
+	if(!enabled)
+	{
+		return;
+	}
+
+	// Horizontal
+	try
+	{
+		Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB, GL_FLOAT, blurFai);
+
+		hBlurFbo.create();
+		hBlurFbo.bind();
+		hBlurFbo.setNumOfColorAttachements(1);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurFai.getGlId(), 0);
+	}
+	catch(std::exception& e)
+	{
+		throw EXCEPTION("Cannot create horizontal blur post-processing stage FBO: " + e.what());
+	}
+
+	hBlurSProg.loadRsrc(ShaderProg::createSrcCodeToCache("shaders/PpsBlurGeneric.glsl", "#define HPASS\n",
+														 "h").c_str());
+
+	// Vertical
+	try
+	{
+		vBlurFbo.create();
+		vBlurFbo.bind();
+		vBlurFbo.setNumOfColorAttachements(1);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+		                       r.getPps().getPostPassFai().getGlId(), 0);
+	}
+	catch(std::exception& e)
+	{
+		throw EXCEPTION("Cannot create vertical blur post-processing stage FBO: " + e.what());
+	}
+
+	vBlurSProg.loadRsrc(ShaderProg::createSrcCodeToCache("shaders/PpsBlurGeneric.glsl", "#define VPASS\n",
+														 "v").c_str());
+
+	// Side blur
+	try
+	{
+		sideBlurFbo.create();
+		sideBlurFbo.bind();
+		sideBlurFbo.setNumOfColorAttachements(1);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+							   r.getMs().getNormalFai().getGlId(), 0);
+	}
+	catch(std::exception& e)
+	{
+		throw EXCEPTION("Cannot create side blur post-processing stage FBO: " + e.what());
+	}
+
+	sideBlurMap.loadRsrc("engine-rsrc/side-blur.png");
+	sideBlurSProg.loadRsrc("shaders/PpsSideBlur.glsl");
+}
+
+
+//======================================================================================================================
+// runSideBlur                                                                                                         =
+//======================================================================================================================
+void Bl::runSideBlur()
+{
+	if(sideBlurFactor == 0.0)
+	{
+		return;
+	}
+
+	sideBlurFbo.bind();
+
+	GlStateMachineSingleton::getInstance().enable(GL_BLEND);
+	glBlendFunc(GL_ONE, GL_ONE);
+
+	sideBlurSProg->bind();
+	sideBlurSProg->findUniVar("tex")->set(*sideBlurMap, 0);
+	sideBlurSProg->findUniVar("factor")->set(&sideBlurFactor);
+
+	r.drawQuad();
+}
+
+
+//======================================================================================================================
+// runBlur                                                                                                             =
+//======================================================================================================================
+void Bl::runBlur()
+{
+	GlStateMachineSingleton::getInstance().disable(GL_BLEND);
+
+	for(uint i = 0; i < blurringIterationsNum; i++)
+	{
+		// hpass
+		hBlurFbo.bind();
+
+		hBlurSProg->bind();
+		hBlurSProg->findUniVar("img")->set(r.getPps().getPostPassFai(), 0);
+		hBlurSProg->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 1);
+		float tmp = r.getWidth();
+		hBlurSProg->findUniVar("imgDimension")->set(&tmp);
+
+		r.drawQuad();
+
+		// vpass
+		vBlurFbo.bind();
+
+		vBlurSProg->bind();
+		vBlurSProg->findUniVar("img")->set(blurFai, 0);
+		vBlurSProg->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 1);
+		tmp = r.getHeight();
+		vBlurSProg->findUniVar("imgDimension")->set(&tmp);
+
+		r.drawQuad();
+	}
+}
+
+
+//======================================================================================================================
+// run                                                                                                                 =
+//======================================================================================================================
+void Bl::run()
+{
+	if(!enabled)
+	{
+		return;
+	}
+
+	runSideBlur();
+	runBlur();
+}
+

+ 49 - 0
src/Renderer/Bl.h

@@ -0,0 +1,49 @@
+#ifndef BL_H
+#define BL_H
+
+#include "RenderingPass.h"
+#include "Accessors.h"
+#include "Texture.h"
+#include "RsrcPtr.h"
+#include "Fbo.h"
+
+
+class ShaderProg;
+
+
+class Bl: private RenderingPass
+{
+	public:
+		Bl(Renderer& r_);
+		void init(const RendererInitializer& initializer);
+		void run();
+
+		/// @name Accessors
+		/// @{
+		GETTER_SETTER_BY_VAL(bool, enabled, isEnabled, setEnabled)
+		GETTER_SETTER_BY_VAL(uint, blurringIterationsNum, getBlurringIterationsNum, setBlurringIterationsNum)
+		GETTER_SETTER_BY_VAL(float, sideBlurFactor, getSideBlurFactor, setSideBlurFactor)
+		/// @}
+
+	private:
+		Fbo hBlurFbo; ///< Fbo that writes to blurFai
+		Fbo vBlurFbo; ///< Fbo that writes to postPassSProg
+		Fbo sideBlurFbo;
+
+		RsrcPtr<ShaderProg> hBlurSProg;
+		RsrcPtr<ShaderProg> vBlurSProg;
+		RsrcPtr<ShaderProg> sideBlurSProg;
+
+		Texture blurFai; ///< Temp FAI for blurring
+		RsrcPtr<Texture> sideBlurMap;
+
+		bool enabled;
+		uint blurringIterationsNum;
+		float sideBlurFactor;
+
+		void runBlur();
+		void runSideBlur();
+};
+
+
+#endif

+ 5 - 114
src/Renderer/Pps.cpp

@@ -11,7 +11,8 @@
 Pps::Pps(Renderer& r_):
 	RenderingPass(r_),
 	hdr(r_),
-	ssao(r_)
+	ssao(r_),
+	bl(r_)
 {}
 
 
@@ -22,8 +23,6 @@ void Pps::init(const RendererInitializer& initializer)
 {
 	ssao.init(initializer);
 	hdr.init(initializer);
-	blurringEnabled = initializer.pps.blurringEnabled;
-	blurringIterationsNum = initializer.pps.blurringIterationsNum;
 
 	//
 	// Init pre pass
@@ -90,63 +89,10 @@ void Pps::init(const RendererInitializer& initializer)
 	postPassSProg.loadRsrc(ShaderProg::createSrcCodeToCache("shaders/PpsPostPass.glsl", pps.c_str(),
 	                                                        prefix.c_str()).c_str());
 
-
 	//
-	// Blurring
+	// Init Bl after
 	//
-	if(blurringEnabled)
-	{
-		Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB, GL_FLOAT, blurFai);
-
-		// Horizontal
-		try
-		{
-			hBlurFbo.create();
-			hBlurFbo.bind();
-			hBlurFbo.setNumOfColorAttachements(1);
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurFai.getGlId(), 0);
-		}
-		catch(std::exception& e)
-		{
-			throw EXCEPTION("Cannot create horizontal blur post-processing stage FBO: " + e.what());
-		}
-
-		hBlurSProg.loadRsrc(ShaderProg::createSrcCodeToCache("shaders/PpsBlurGeneric.glsl", "#define HPASS\n",
-															 "h").c_str());
-
-		// Vertical
-		try
-		{
-			vBlurFbo.create();
-			vBlurFbo.bind();
-			vBlurFbo.setNumOfColorAttachements(1);
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, postPassFai.getGlId(), 0);
-		}
-		catch(std::exception& e)
-		{
-			throw EXCEPTION("Cannot create vertical blur post-processing stage FBO: " + e.what());
-		}
-
-		vBlurSProg.loadRsrc(ShaderProg::createSrcCodeToCache("shaders/PpsBlurGeneric.glsl", "#define VPASS\n",
-															 "v").c_str());
-
-		// Side blur
-		try
-		{
-			sideBlurFbo.create();
-			sideBlurFbo.bind();
-			sideBlurFbo.setNumOfColorAttachements(1);
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-								   r.getMs().getNormalFai().getGlId(), 0);
-		}
-		catch(std::exception& e)
-		{
-			throw EXCEPTION("Cannot create side blur post-processing stage FBO: " + e.what());
-		}
-
-		sideBlur.loadRsrc("engine-rsrc/side-blur.png");
-		sideBlurSProg.loadRsrc("shaders/PpsSideBlur.glsl");
-	} // end blurring enabled
+	bl.init(initializer);
 }
 
 
@@ -178,57 +124,6 @@ void Pps::runPrePass()
 }
 
 
-//======================================================================================================================
-// runBlur                                                                                                             =
-//======================================================================================================================
-void Pps::runBlur()
-{
-	GlStateMachineSingleton::getInstance().enable(GL_BLEND, false);
-
-	for(uint i = 0; i < blurringIterationsNum; i++)
-	{
-		// hpass
-		hBlurFbo.bind();
-
-		hBlurSProg->bind();
-		hBlurSProg->findUniVar("img")->set(postPassFai, 0);
-		hBlurSProg->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 1);
-		float tmp = r.getWidth();
-		hBlurSProg->findUniVar("imgDimension")->set(&tmp);
-
-		r.drawQuad();
-
-		// vpass
-		vBlurFbo.bind();
-
-		vBlurSProg->bind();
-		vBlurSProg->findUniVar("img")->set(blurFai, 0);
-		vBlurSProg->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 1);
-		tmp = r.getHeight();
-		vBlurSProg->findUniVar("imgDimension")->set(&tmp);
-
-		r.drawQuad();
-	}
-}
-
-
-//======================================================================================================================
-// runSideBlur                                                                                                         =
-//======================================================================================================================
-void Pps::runSideBlur()
-{
-	sideBlurFbo.bind();
-
-	GlStateMachineSingleton::getInstance().enable(GL_BLEND, true);
-	glBlendFunc(GL_ONE, GL_ONE);
-
-	sideBlurSProg->bind();
-	sideBlurSProg->findUniVar("tex")->set(*sideBlur, 0);
-
-	r.drawQuad();
-}
-
-
 //======================================================================================================================
 // runPostPass                                                                                                         =
 //======================================================================================================================
@@ -260,9 +155,5 @@ void Pps::runPostPass()
 	//
 	// Blurring
 	//
-	if(blurringEnabled)
-	{
-		runSideBlur();
-		runBlur();
-	}
+	bl.run();
 }

+ 5 - 14
src/Renderer/Pps.h

@@ -7,6 +7,7 @@
 #include "RsrcPtr.h"
 #include "Hdr.h"
 #include "Ssao.h"
+#include "Bl.h"
 
 
 class ShaderProg;
@@ -27,9 +28,9 @@ class Pps: private RenderingPass
 		/// @{
 		GETTER_R(Hdr, hdr, getHdr)
 		GETTER_R(Ssao, ssao, getSsao)
+		GETTER_R(Bl, bl, getBl)
 		GETTER_R(Texture, prePassFai, getPrePassFai)
 		GETTER_R(Texture, postPassFai, getPostPassFai)
-		GETTER_SETTER_BY_VAL(bool, blurringEnabled, isBlurringEnabled, setBlurringEnabled)
 		/// @}
 
 	private:
@@ -37,27 +38,17 @@ class Pps: private RenderingPass
 		/// @{
 		Hdr hdr;
 		Ssao ssao;
+		Bl bl;
 		/// @}
 
 		Fbo prePassFbo;
 		Fbo postPassFbo;
-		Fbo hBlurFbo; ///< Fbo that writes to blurFai
-		Fbo vBlurFbo; ///< Fbo that writes to postPassSProg
-		Fbo sideBlurFbo;
+
 		RsrcPtr<ShaderProg> prePassSProg;
 		RsrcPtr<ShaderProg> postPassSProg;
-		RsrcPtr<ShaderProg> hBlurSProg;
-		RsrcPtr<ShaderProg> vBlurSProg;
-		RsrcPtr<ShaderProg> sideBlurSProg;
+
 		Texture prePassFai; ///< FAI #1
 		Texture postPassFai; ///< FAI #2
-		Texture blurFai; ///< Temp FAI for blurring
-		RsrcPtr<Texture> sideBlur;
-		bool blurringEnabled;
-		uint blurringIterationsNum;
-
-		void runBlur();
-		void runSideBlur();
 };
 
 

+ 7 - 2
src/Renderer/RendererInitializer.h

@@ -51,8 +51,13 @@ struct RendererInitializer
 			float blurringIterationsNum;
 		} ssao;
 
-		bool blurringEnabled;
-		uint blurringIterationsNum;
+		// Bl
+		struct Bl
+		{
+			bool enabled;
+			uint blurringIterationsNum;
+			float sideBlurFactor;
+		} bl;
 	} pps;
 
 	// Dbg

+ 2 - 3
src/Scripting/BoostPythonInterfaces.cpp

@@ -1,6 +1,5 @@
 #include <boost/python.hpp>
 #include "ScriptingCommon.h"
-#include "App.h"
 
 
 BOOST_PYTHON_MODULE(Anki)
@@ -20,6 +19,7 @@ BOOST_PYTHON_MODULE(Anki)
 	CALL_WRAP(Scene);
 
 	CALL_WRAP(Hdr);
+	CALL_WRAP(Bl);
 	CALL_WRAP(Pps);
 	CALL_WRAP(Renderer);
 	CALL_WRAP(Dbg);
@@ -29,6 +29,5 @@ BOOST_PYTHON_MODULE(Anki)
 
 	CALL_WRAP(Input);
 
-	extern void wrapAllGlobals();
-	wrapAllGlobals();
+	CALL_WRAP(AllGlobals);
 }

+ 1 - 1
src/Scripting/Core/Globals.bpi.cpp

@@ -14,7 +14,7 @@ WRAP_SINGLETON(SceneSingleton)
 WRAP_SINGLETON(AppSingleton)
 
 
-void wrapAllGlobals()
+void boostPythonWrapAllGlobals()
 {
 	CALL_WRAP(LoggerSingleton);
 	CALL_WRAP(MainRendererSingleton);

+ 17 - 0
src/Scripting/Renderer/Bl.bpi.cpp

@@ -0,0 +1,17 @@
+#include "ScriptingCommon.h"
+#include "Bl.h"
+
+
+WRAP(Bl)
+{
+	class_<Bl, noncopyable>("Bl", no_init)
+		.def("isEnabled", (bool (Bl::*)() const)(&Bl::isEnabled))
+		.def("setEnabled", &Bl::setEnabled)
+
+		.def("getBlurringIterationsNum", (uint (Bl::*)() const)(&Bl::getBlurringIterationsNum))
+		.def("setBlurringIterationsNum", &Bl::setBlurringIterationsNum)
+
+		.def("getSideBlurFactor", (float (Bl::*)() const)(&Bl::getSideBlurFactor))
+		.def("setSideBlurFactor", &Bl::setSideBlurFactor)
+	;
+}

+ 2 - 2
src/Scripting/Renderer/Pps.bpi.cpp

@@ -1,13 +1,13 @@
 #include "ScriptingCommon.h"
 #include "Pps.h"
 #include "Hdr.h"
+#include "Bl.h"
 
 
 WRAP(Pps)
 {
 	class_<Pps, noncopyable>("Pps", no_init)
 		.def("getHdr", &Pps::getHdr, return_value_policy<reference_existing_object>())
-		.def("isBlurringEnabled", (bool (Pps::*)() const)(&Pps::isBlurringEnabled))
-		.def("setBlurringEnabled", &Pps::setBlurringEnabled)
+		.def("getBl", &Pps::getBl, return_value_policy<reference_existing_object>())
 	;
 }

+ 59 - 7
src/Ui/UiPainter.cpp

@@ -23,15 +23,16 @@ Painter::Painter()
 void Painter::init()
 {
 	// Map
-	fontMap.loadRsrc("engine-rsrc/fontmap.png");
+	fontMap.loadRsrc("engine-rsrc/fontmap-big.png");
 	columns = 16;
 	rows = 8;
+	tabSize = 4;
 
 	// SProg
-	sProg.loadRsrc("shaders/Ui.glsl");
+	sProg.loadRsrc("shaders/UiText.glsl");
 
 	// Geom
-	float quadVertCoords[][2] = {{1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}};
+	float quadVertCoords[][2] = {{1.0, 0.0}, {0.0, 0.0}, {0.0, -1.0}, {1.0, -1.0}};
 	qPositionsVbo.create(GL_ARRAY_BUFFER, sizeof(quadVertCoords), quadVertCoords, GL_STATIC_DRAW);
 
 	ushort quadVertIndeces[2][3] = {{0, 1, 3}, {1, 2, 3}}; // 2 triangles
@@ -50,7 +51,8 @@ void Painter::drawText(const char* text)
 {
 	// Set GL
 	GlStateMachineSingleton::getInstance().enable(GL_BLEND);
-	GlStateMachineSingleton::getInstance().disable(GL_DEPTH);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	GlStateMachineSingleton::getInstance().disable(GL_DEPTH_TEST);
 
 	// SProg (some)
 	sProg->bind();
@@ -62,31 +64,81 @@ void Painter::drawText(const char* text)
 	qVao.bind();
 
 	// Iterate
+	float horizontalMoving = fontSize.x() * 0.65;
+	float verticalMoving = fontSize.y() /* * 0.7*/;
 	Vec2 p = pos;
 	const char* c = text;
 	while(*c != '\0')
 	{
+		char cc = *c;
+		// Check if special
+		if(cc == '\n')
+		{
+			p.y() += verticalMoving;
+			p.x() = pos.x();
+			++c;
+			continue;
+		}
+		if(cc == '\t') // tab
+		{
+			p.x() += horizontalMoving * (tabSize - 1);
+			cc = ' ';
+		}
+		if(cc < ' ' || cc > '~') // out of range
+		{
+			cc = '~' + 1;
+		}
+
 		// Pos trf
 		Mat3 trf = Mat3::getIdentity();
 		trf(0, 0) = fontSize.x() * 2.0;
 		trf(1, 1) = fontSize.y() * 2.0;
 		trf(0, 2) = p.x() * 2.0 - 1.0;
-		trf(1, 2) = p.y() * 2.0 - 1.0;
+		trf(1, 2) = -p.y() * 2.0 + 1.0;
 
 		sProg->findUniVar("transformation")->set(&trf);
 
 		// Tex trf
+		uint i = cc - 32;
+		uint crntRow = i / columns;
+		uint crntColumn = i % columns;
+
+		//INFO(crntRow << " " << crntColumn);
+
 		Mat3 texTrf = Mat3::getIdentity();
-		sProg->findUniVar("textureTranformation")->set(&trf);
+		texTrf(0, 0) = 1.0 / columns;
+		texTrf(1, 1) = 1.0 / rows;
+		texTrf(0, 2) = crntColumn / float(columns);
+		texTrf(1, 2) = 1.0 - crntRow / float(rows);
+
+		sProg->findUniVar("textureTranformation")->set(&texTrf);
 
 		// Render
 		glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
 
 		// Inc
 		++c;
-		p.x() += fontSize.x();
+		p.x() += horizontalMoving;
 	}
 }
 
 
+//======================================================================================================================
+// drawFormatedText                                                                                                    =
+//======================================================================================================================
+void Painter::drawFormatedText(const char* format, ...)
+{
+	va_list ap;
+	char text[512];
+
+	va_start(ap, format);
+	vsprintf(text, format, ap);
+	va_end(ap);
+
+	ASSERT(strlen(text) < 512);
+
+	drawText(text);
+}
+
+
 } // end namespace

+ 1 - 0
src/Ui/UiPainter.h

@@ -37,6 +37,7 @@ class Painter
 		Vec2 pos;
 		Vec2 fontSize;
 		Vec4 col;
+		uint tabSize;
 
 		Vbo qPositionsVbo;
 		Vbo qIndecesVbo;

+ 25 - 0
src/Ui/UiPainterDevice.h

@@ -0,0 +1,25 @@
+#ifndef UI_PAINDER_DEVICE_H
+#define UI_PAINDER_DEVICE_H
+
+#include "Fbo.h"
+#include "Math.h"
+
+
+class Texture;
+
+
+namespace Ui {
+
+
+/// @todo
+class PainterDevice: public Fbo
+{
+	public:
+		PainterDevice(const Vec2& size, Texture& colorFai);
+};
+
+
+} // end namesapce
+
+
+#endif

Some files were not shown because too many files changed in this diff