Пример #1
0
 GLColorBuffer GLLensDustFilter::GaussianBlur(GLColorBuffer tex, bool vertical) {
     SPADES_MARK_FUNCTION();
     GLProgram *program = gauss1d;
     IGLDevice *dev = renderer->GetGLDevice();
     GLQuadRenderer qr(dev);
     int w = tex.GetWidth();
     int h = tex.GetHeight();
     
     static GLProgramAttribute blur_positionAttribute("positionAttribute");
     static GLProgramUniform blur_textureUniform("mainTexture");
     static GLProgramUniform blur_unitShift("unitShift");
     program->Use();
     blur_positionAttribute(program);
     
     blur_textureUniform(program);
     blur_textureUniform.SetValue(0);
     dev->ActiveTexture(0);
     dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture());
     
     blur_unitShift(program);
     blur_unitShift.SetValue(vertical ? 0.f : 1.f / w,
                             vertical ? 1.f / h : 0.f);
     
     qr.SetCoordAttributeIndex(blur_positionAttribute());
     dev->Enable(IGLDevice::Blend, false);
     
     GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false);
     dev->Viewport(0, 0, buf2.GetWidth(), buf2.GetHeight());
     dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
     qr.Draw();
     return buf2;
 }
Пример #2
0
		GLColorBuffer GLDepthOfFieldFilter::FinalMix(GLColorBuffer tex,
													 GLColorBuffer blur1,
													 GLColorBuffer blur2,
													 GLColorBuffer coc) {
			SPADES_MARK_FUNCTION();
			// do gaussian blur
			GLProgram *program = finalMix;
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			int w = tex.GetWidth();
			int h = tex.GetHeight();
			
			static GLProgramAttribute blur_positionAttribute("positionAttribute");
			static GLProgramUniform blur_textureUniform1("texture");
			static GLProgramUniform blur_textureUniform2("blurTexture1");
			static GLProgramUniform blur_textureUniform3("blurTexture2");
			static GLProgramUniform blur_textureUniform4("cocTexture");
			program->Use();
			blur_positionAttribute(program);
			
			blur_textureUniform1(program);
			blur_textureUniform1.SetValue(3);
			dev->ActiveTexture(3);
			dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture());
			
			blur_textureUniform2(program);
			blur_textureUniform2.SetValue(2);
			dev->ActiveTexture(2);
			dev->BindTexture(IGLDevice::Texture2D, blur1.GetTexture());
			
			blur_textureUniform3(program);
			blur_textureUniform3.SetValue(1);
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, blur2.GetTexture());
			
			blur_textureUniform4(program);
			blur_textureUniform4.SetValue(0);
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, coc.GetTexture());
			
			
			qr.SetCoordAttributeIndex(blur_positionAttribute());
			dev->Enable(IGLDevice::Blend, false);
			
			// x-direction
			GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false);
			dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
			qr.Draw();
			return buf2;
		}
Пример #3
0
		GLColorBuffer GLLensDustFilter::DownSample(GLColorBuffer tex,
												   bool linearize) {
			SPADES_MARK_FUNCTION();
			GLProgram *program = thru;
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			int w = tex.GetWidth();
			int h = tex.GetHeight();
			
			static GLProgramAttribute blur_positionAttribute("positionAttribute");
			static GLProgramUniform blur_textureUniform("mainTexture");
            static GLProgramUniform blur_colorUniform("colorUniform");
            static GLProgramUniform blur_texCoordRangeUniform("texCoordRange");
            static GLProgramUniform blur_texCoordOffsetUniform("texCoordOffset");
			program->Use();
			blur_positionAttribute(program);
			
			blur_textureUniform(program);
			blur_textureUniform.SetValue(0);
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture());
            
            blur_texCoordOffsetUniform(program);
            blur_texCoordOffsetUniform.SetValue(1.f / w, 1.f / h, -1.f / w, -1.f / h);
			
			blur_colorUniform(program);
			blur_colorUniform.SetValue(1.f,1.f,1.f,1.f);
			
			blur_texCoordRangeUniform(program);
			blur_texCoordRangeUniform.SetValue(0.f, 0.f,
                                               (float)((w + 1) & ~1) / w,
                                               (float)((h + 1) & ~1) / h);
			
			qr.SetCoordAttributeIndex(blur_positionAttribute());
			if(linearize){
				dev->Enable(IGLDevice::Blend, true);
				dev->BlendFunc(IGLDevice::SrcColor,
							   IGLDevice::Zero);
			}else{
				dev->Enable(IGLDevice::Blend, false);
			}
			
			GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle((w+1)/2, (h+1)/2, false);
			dev->Viewport(0, 0, buf2.GetWidth(), buf2.GetHeight());
			dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
			qr.Draw();
			return buf2;
		}
Пример #4
0
		GLColorBuffer GLLensFilter::Filter(GLColorBuffer input) {
			SPADES_MARK_FUNCTION();
			
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			
			static GLProgramAttribute lensPosition("positionAttribute");
			static GLProgramUniform lensTexture("mainTexture");
			static GLProgramUniform lensFov("fov");
			
			dev->Enable(IGLDevice::Blend, false);
			
			lensPosition(lens);
			lensTexture(lens);
			lensFov(lens);
			
			lens->Use();
			
			client::SceneDefinition def = renderer->GetSceneDef();
			lensFov.SetValue(tanf(def.fovX * .5f),
							 tanf(def.fovY * .5f));
			lensTexture.SetValue(0);
			
			// composite to the final image
			GLColorBuffer output = input.GetManager()->CreateBufferHandle();
			
			
			qr.SetCoordAttributeIndex(lensPosition());
			dev->BindTexture(IGLDevice::Texture2D, input.GetTexture());
			dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer());
			dev->Viewport(0, 0, output.GetWidth(), output.GetHeight());
			qr.Draw();
			dev->BindTexture(IGLDevice::Texture2D, 0);
			
			
			return output;
		}
Пример #5
0
		GLColorBuffer GLDepthOfFieldFilter::AddMix(GLColorBuffer buffer1, GLColorBuffer buffer2) {
			SPADES_MARK_FUNCTION();
			// do gaussian blur
			GLProgram *program = gammaMix;
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			int w = buffer1.GetWidth();
			int h = buffer1.GetHeight();
			
			static GLProgramAttribute blur_positionAttribute("positionAttribute");
			static GLProgramUniform blur_textureUniform1("texture1");
			static GLProgramUniform blur_textureUniform2("texture2");
			static GLProgramUniform blur_unitShift("unitShift");
			static GLProgramUniform blur_mix1("mix1");
			static GLProgramUniform blur_mix2("mix2");
			program->Use();
			blur_positionAttribute(program);
			
			blur_textureUniform1(program);
			blur_textureUniform1.SetValue(1);
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, buffer1.GetTexture());
			
			blur_textureUniform2(program);
			blur_textureUniform2.SetValue(0);
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, buffer2.GetTexture());
			
			blur_mix1(program);
			blur_mix2(program);
			
			blur_mix1.SetValue(.5f, .5f, .5f);
			blur_mix2.SetValue(.5f, .5f, .5f);
			
			qr.SetCoordAttributeIndex(blur_positionAttribute());
			dev->Enable(IGLDevice::Blend, false);
			
			// x-direction
			GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false);
			dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
			qr.Draw();
			return buf2;
		}
Пример #6
0
		GLColorBuffer GLDepthOfFieldFilter::Blur(GLColorBuffer buffer,
													
												 GLColorBuffer coc,
												 Vector2 offset,
												 int divide) {
			SPADES_MARK_FUNCTION();
			// do gaussian blur
			GLProgram *program = blurProgram;
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			int w = buffer.GetWidth();
			int h = buffer.GetHeight();
			int w2 = w / divide;
			int h2 = h / divide;
			
			static GLProgramAttribute blur_positionAttribute("positionAttribute");
			static GLProgramUniform blur_textureUniform("texture");
			static GLProgramUniform blur_cocUniform("cocTexture");
			static GLProgramUniform blur_offset("offset");
			program->Use();
			blur_positionAttribute(program);
			blur_textureUniform(program);
			blur_cocUniform(program);
			blur_offset(program);
			
			blur_cocUniform.SetValue(1);
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, coc.GetTexture());
			
			blur_textureUniform.SetValue(0);
			dev->ActiveTexture(0);
			
			qr.SetCoordAttributeIndex(blur_positionAttribute());
			
			// x-direction
			float len = offset.GetLength();
			float sX = 1.f / (float)w, sY = 1.f / (float)h;
			while(len > .5f){
				GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w2, h2, false);
				dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
				dev->BindTexture(IGLDevice::Texture2D, buffer.GetTexture());
				blur_offset.SetValue(offset.x * sX, offset.y * sY);
				qr.Draw();
				buffer = buf2;
				
				offset *= .125f;
				len *= .125f;
			}
			
			return buffer;
		}
Пример #7
0
		GLColorBuffer GLDepthOfFieldFilter::UnderSample(GLColorBuffer tex) {
			SPADES_MARK_FUNCTION();
			// do gaussian blur
			GLProgram *program = passthrough;
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			int w = tex.GetWidth();
			int h = tex.GetHeight();
			
			static GLProgramAttribute blur_positionAttribute("positionAttribute");
			static GLProgramUniform blur_textureUniform("texture");
			static GLProgramUniform blur_colorUniform("colorUniform");
			static GLProgramUniform blur_texCoordRangeUniform("texCoordRange");
			program->Use();
			blur_positionAttribute(program);
			
			blur_textureUniform(program);
			blur_textureUniform.SetValue(0);
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture());
			
			blur_colorUniform(program);
			blur_colorUniform.SetValue(1.f,1.f,1.f,1.f);
			
			blur_texCoordRangeUniform(program);
			blur_texCoordRangeUniform.SetValue(0.f, 0.f, 1.f, 1.f);
			
			qr.SetCoordAttributeIndex(blur_positionAttribute());
			dev->Enable(IGLDevice::Blend, false);
			
			GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w/2, h/2, false);
			dev->Viewport(0, 0, w/2, h/2);
			dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
			qr.Draw();
			return buf2;
		}
Пример #8
0
		GLColorBuffer GLCameraBlurFilter::Filter(GLColorBuffer input, float radialBlur) {
			SPADES_MARK_FUNCTION();
			
			if(radialBlur > 0.f)
				radialBlur = 1.f - radialBlur;
			else
				radialBlur = 1.f;
			
			bool hasRadialBlur = radialBlur < .9999f;
			
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			
			
			
			dev->Enable(IGLDevice::Blend, false);
			
			static GLProgramAttribute programPosition("positionAttribute");
			static GLProgramUniform programTexture("texture");
			static GLProgramUniform programDepthTexture("depthTexture");
			static GLProgramUniform programReverseMatrix("reverseMatrix");
			static GLProgramUniform programShutterTimeScale("shutterTimeScale");
			
			programPosition(program);
			programTexture(program);
			programDepthTexture(program);
			programReverseMatrix(program);
			programShutterTimeScale(program);
			
			const client::SceneDefinition& def = renderer->GetSceneDef();
			Matrix4 newMatrix = Matrix4::Identity();
			newMatrix.m[0] = def.viewAxis[0].x;
			newMatrix.m[1] = def.viewAxis[1].x;
			newMatrix.m[2] = def.viewAxis[2].x;
			newMatrix.m[4] = def.viewAxis[0].y;
			newMatrix.m[5] = def.viewAxis[1].y;
			newMatrix.m[6] = def.viewAxis[2].y;
			newMatrix.m[8] = def.viewAxis[0].z;
			newMatrix.m[9] = def.viewAxis[1].z;
			newMatrix.m[10] = def.viewAxis[2].z;
			
			// othrogonal matrix can be reversed fast
			Matrix4 inverseNewMatrix = newMatrix.Transposed();
			Matrix4 diffMatrix = prevMatrix * inverseNewMatrix;
			prevMatrix = newMatrix;
			Matrix4 reverseMatrix = ReverseMatrix(diffMatrix);
			
			if(diffMatrix.m[0] < .3f ||
			   diffMatrix.m[5] < .3f ||
			   diffMatrix.m[10] < .3f){
				// too much change
				if(hasRadialBlur) {
					diffMatrix = Matrix4::Identity();
				}else{
					// skip blur
					return input;
				}
			}
			
			float movePixels = MyACos(diffMatrix.m[0]);
			float shutterTimeScale = .3f;
			movePixels = std::max(movePixels, MyACos(diffMatrix.m[5]));
			movePixels = std::max(movePixels, MyACos(diffMatrix.m[10]));
			movePixels = tanf(movePixels) / tanf(def.fovX * .5f);
			movePixels *= (float)dev->ScreenWidth() * .5f;
			movePixels *= shutterTimeScale;
			
			movePixels = std::max(movePixels,
								  (1.f - radialBlur) * dev->ScreenWidth() * 0.5f);
			
			if(movePixels < 1.f){
				// too less change, skip camera blur
				return input;
			}
			
			int levels = (int)ceilf(logf(movePixels) / logf(5.f));
			if(levels <= 0)
				levels = 1;
			
			if(hasRadialBlur)
				radialBlur *= radialBlur;
			reverseMatrix = Matrix4::Scale(radialBlur, radialBlur, 1.f)
				* reverseMatrix;
			
			program->Use();
			
			programTexture.SetValue(0);
			programDepthTexture.SetValue(1);
			programReverseMatrix.SetValue(reverseMatrix);
			
			// composite to the final image
			GLColorBuffer buf = input;
			
			qr.SetCoordAttributeIndex(programPosition());
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, renderer->GetFramebufferManager()->GetDepthTexture());
			dev->ActiveTexture(0);
			
			for(int i = 0; i < levels; i++){
				GLProfiler measure(dev, "Apply [%d / %d]", i+1,levels);
				GLColorBuffer output = input.GetManager()->CreateBufferHandle();
				programShutterTimeScale.SetValue(shutterTimeScale);
				dev->BindTexture(IGLDevice::Texture2D, buf.GetTexture());
				dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer());
				dev->Viewport(0, 0, output.GetWidth(), output.GetHeight());
				qr.Draw();
				dev->BindTexture(IGLDevice::Texture2D, 0);
				shutterTimeScale /= 5.f;
				buf = output;
			}
			
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, 0);
			dev->ActiveTexture(0);
			
			
			return buf;
		}
Пример #9
0
		GLColorBuffer GLLensDustFilter::Filter(GLColorBuffer input) {
			SPADES_MARK_FUNCTION();
			
			UpdateNoise();
			
			std::vector<Level> levels;
			
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			
			static GLProgramAttribute thruPosition("positionAttribute");
			static GLProgramUniform thruColor("colorUniform");
			static GLProgramUniform thruTexture("mainTexture");
			static GLProgramUniform thruTexCoordRange("texCoordRange");
			
			thruPosition(thru);
			thruColor(thru);
			thruTexture(thru);
			thruTexCoordRange(thru);
						
			GLColorBuffer downSampled = DownSample(input, r_hdr ? false : true);
            downSampled = GaussianBlur(downSampled, false);
            downSampled = GaussianBlur(downSampled, true);
			
			thru->Use();
			thruColor.SetValue(1.f, 1.f, 1.f, 1.f);
			thruTexture.SetValue(0);
			dev->Enable(IGLDevice::Blend, false);
			
			levels.reserve(10);
			
			// create downsample levels
			for(int i = 0; i < 10; i++){
				GLColorBuffer prevLevel;
				if(i == 0){
					prevLevel = downSampled;
				}else{
					prevLevel = levels.back().buffer;
				}
				
				int prevW = prevLevel.GetWidth();
				int prevH = prevLevel.GetHeight();
				int newW = (prevW + 1) / 2;
				int newH = (prevH + 1) / 2;
				if(newW <= 1 || newH <= 1)
					break;
                GLColorBuffer newLevel = DownSample(prevLevel);
                newLevel = GaussianBlur(newLevel, false);
                newLevel = GaussianBlur(newLevel, true);
				
				Level lv;
				lv.w = newW; lv.h = newH;
				lv.buffer = newLevel;
				levels.push_back(lv);
			}
			
			dev->Enable(IGLDevice::Blend, true);
			dev->BlendFunc(IGLDevice::SrcAlpha,
						   IGLDevice::OneMinusSrcAlpha);
			
			// composite levels in the opposite direction
			thru->Use();
			qr.SetCoordAttributeIndex(thruPosition());
			for(int i = (int)levels.size() - 1; i >= 1; i--){
				int cnt = (int)levels.size() - i;
				float alpha = (float)cnt / (float)(cnt + 1);
                alpha = alpha;
				
				GLColorBuffer curLevel = levels[i].buffer;
				
				float sx = .25f / curLevel.GetWidth();
				float sy = .25f / curLevel.GetHeight();
				
				for(int j = 0; j < 4; j++) {
					if(i < (int)levels.size() - 1) {
						curLevel = levels[i].retBuf[j];
					}
					GLColorBuffer targLevel = levels[i - 1].buffer;
					GLColorBuffer targRet = input.GetManager()->CreateBufferHandle(targLevel.GetWidth(),
																	   targLevel.GetHeight(),
																	   false);
					levels[i - 1].retBuf[j] = targRet;
					
					dev->BindFramebuffer(IGLDevice::Framebuffer, targRet.GetFramebuffer());
					dev->Viewport(0, 0, targRet.GetWidth(), targRet.GetHeight());
					
					dev->BindTexture(IGLDevice::Texture2D, targLevel.GetTexture());
					thruColor.SetValue(1.f, 1.f, 1.f, 1.f);
					thruTexCoordRange.SetValue(0.f, 0.f, 1.f, 1.f);
					dev->Enable(IGLDevice::Blend, false);
					qr.Draw();
					
					float cx = 0.f, cy = 0.f;
					switch(j){
						case 0: cx = sx; break;
						case 1: cx = -sx; break;
						case 2: cy = sy; break;
						case 3: cy = -sy; break;
					}
					
					dev->BindTexture(IGLDevice::Texture2D, curLevel.GetTexture());
					thruColor.SetValue(1.f, 1.f, 1.f, alpha);
					thruTexCoordRange.SetValue(cx, cy, 1.f, 1.f);
					dev->Enable(IGLDevice::Blend, true);
					qr.Draw();
					
					dev->BindTexture(IGLDevice::Texture2D, 0);
				}
				
			}
			
			static GLProgramAttribute dustPosition("positionAttribute");
			static GLProgramUniform dustDustTexture("dustTexture");
			static GLProgramUniform dustBlurTexture1("blurTexture1");
			static GLProgramUniform dustBlurTexture2("blurTexture2");
			static GLProgramUniform dustBlurTexture3("blurTexture3");
			static GLProgramUniform dustBlurTexture4("blurTexture4");
			static GLProgramUniform dustInputTexture("inputTexture");
			static GLProgramUniform dustNoiseTexture("noiseTexture");
			static GLProgramUniform dustNoiseTexCoordFactor("noiseTexCoordFactor");
			
			dustPosition(dust);
			dustDustTexture(dust);
			dustBlurTexture1(dust);
			dustBlurTexture2(dust);
			dustBlurTexture3(dust);
			dustBlurTexture4(dust);
			dustInputTexture(dust);
			dustNoiseTexture(dust);
			dustNoiseTexCoordFactor(dust);
			
			dust->Use();
			
			float facX = renderer->ScreenWidth() / 128.f;
			float facY = renderer->ScreenHeight() / 128.f;
			dustNoiseTexCoordFactor.SetValue(facX, facY,
											 facX / 128.f,
											 facY / 128.f);
			
			// composite to the final image
			GLColorBuffer output = input.GetManager()->CreateBufferHandle();
			GLColorBuffer topLevel1 = levels[0].retBuf[0];
			GLColorBuffer topLevel2 = levels[0].retBuf[1];
			GLColorBuffer topLevel3 = levels[0].retBuf[2];
			GLColorBuffer topLevel4 = levels[0].retBuf[3];
			
			qr.SetCoordAttributeIndex(dustPosition());
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, input.GetTexture());
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, topLevel1.GetTexture());
			dev->ActiveTexture(2);
			dev->BindTexture(IGLDevice::Texture2D, topLevel2.GetTexture());
			dev->ActiveTexture(3);
			dev->BindTexture(IGLDevice::Texture2D, topLevel3.GetTexture());
			dev->ActiveTexture(4);
			dev->BindTexture(IGLDevice::Texture2D, topLevel4.GetTexture());
			dev->ActiveTexture(5);
			dustImg->Bind(IGLDevice::Texture2D);
			dev->ActiveTexture(6);
			dev->BindTexture(IGLDevice::Texture2D, noiseTex);
			dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer());
			dev->Viewport(0, 0, output.GetWidth(), output.GetHeight());
			dustBlurTexture1.SetValue(2);
			dustBlurTexture2.SetValue(1);
			dustBlurTexture3.SetValue(3);
			dustBlurTexture4.SetValue(4);
			dustDustTexture.SetValue(5);
			dustNoiseTexture.SetValue(6);
			dustInputTexture.SetValue(0);
			qr.Draw();
			dev->BindTexture(IGLDevice::Texture2D, 0);
			
			dev->ActiveTexture(0);
			
			return output;
		}
Пример #10
0
		GLColorBuffer GLBloomFilter::Filter(GLColorBuffer input) {
			SPADES_MARK_FUNCTION();
			
			
			
			std::vector<Level> levels;
			
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			
			static GLProgramAttribute thruPosition("positionAttribute");
			static GLProgramUniform thruColor("colorUniform");
			static GLProgramUniform thruTexture("texture");
			static GLProgramUniform thruTexCoordRange("texCoordRange");
			
			thruPosition(thru);
			thruColor(thru);
			thruTexture(thru);
			thruTexCoordRange(thru);
			
			GLProgram *gammaMix = renderer->RegisterProgram("Shaders/PostFilters/GammaMix.program");
			static GLProgramAttribute gammaMixPosition("positionAttribute");
			static GLProgramUniform gammaMixTexture1("texture1");
			static GLProgramUniform gammaMixTexture2("texture2");
			static GLProgramUniform gammaMixMix1("mix1");
			static GLProgramUniform gammaMixMix2("mix2");
			
			gammaMixPosition(gammaMix);
			gammaMixTexture1(gammaMix);
			gammaMixTexture2(gammaMix);
			gammaMixMix1(gammaMix);
			gammaMixMix2(gammaMix);
			
			thru->Use();
			thruColor.SetValue(1.f, 1.f, 1.f, 1.f);
			thruTexture.SetValue(0);
			dev->Enable(IGLDevice::Blend, false);
			
			// create downsample levels
			for(int i = 0; i < 6; i++){
				GLColorBuffer prevLevel;
				if(i == 0){
					prevLevel = input;
				}else{
					prevLevel = levels.back().buffer;
				}
				
				int prevW = prevLevel.GetWidth();
				int prevH = prevLevel.GetHeight();
				int newW = (prevW + 1) / 2;
				int newH = (prevH + 1) / 2;
				GLColorBuffer newLevel = input.GetManager()->CreateBufferHandle(newW, newH);
				
				thru->Use();
				qr.SetCoordAttributeIndex(thruPosition());
				dev->BindTexture(IGLDevice::Texture2D, prevLevel.GetTexture());
				dev->BindFramebuffer(IGLDevice::Framebuffer, newLevel.GetFramebuffer());
				dev->Viewport(0, 0, newLevel.GetWidth(), newLevel.GetHeight());
				thruTexCoordRange.SetValue(0.f, 0.f,
										   (float)newLevel.GetWidth() * 2.f / (float)prevW,
										   (float)newLevel.GetHeight() * 2.f / (float)prevH);
				qr.Draw();
				dev->BindTexture(IGLDevice::Texture2D, 0);
				
				Level lv;
				lv.w = newW; lv.h = newH;
				lv.buffer = newLevel;
				levels.push_back(lv);
			}
			
			dev->Enable(IGLDevice::Blend, true);
			dev->BlendFunc(IGLDevice::SrcAlpha,
						   IGLDevice::OneMinusSrcAlpha);
			
			// composite levels in the opposite direction
			thruTexCoordRange.SetValue(0.f, 0.f, 1.f, 1.f);
			for(int i = (int)levels.size() - 1; i >= 1; i--){
				int cnt = (int)levels.size() - i;
				float alpha = (float)cnt / (float)(cnt + 1);
				alpha = sqrtf(alpha);
				GLColorBuffer curLevel = levels[i].buffer;
				GLColorBuffer targLevel = levels[i - 1].buffer;
			
				thru->Use();
				qr.SetCoordAttributeIndex(thruPosition());
				dev->BindTexture(IGLDevice::Texture2D, curLevel.GetTexture());
				dev->BindFramebuffer(IGLDevice::Framebuffer, targLevel.GetFramebuffer());
				dev->Viewport(0, 0, targLevel.GetWidth(), targLevel.GetHeight());
				thruColor.SetValue(1.f, 1.f, 1.f, alpha);
				qr.Draw();
				dev->BindTexture(IGLDevice::Texture2D, 0);
			}
			
			// composite to the final image
			GLColorBuffer output = input.GetManager()->CreateBufferHandle();
			GLColorBuffer topLevel = levels[0].buffer;
			
			gammaMix->Use();
			qr.SetCoordAttributeIndex(gammaMixPosition());
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, input.GetTexture());
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, topLevel.GetTexture());
			dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer());
			dev->Viewport(0, 0, output.GetWidth(), output.GetHeight());
			gammaMixTexture1.SetValue(0);
			gammaMixTexture2.SetValue(1);
			gammaMixMix1.SetValue(.8f, .8f, .8f);
			gammaMixMix2.SetValue(.2f, .2f, .2f);
			qr.Draw();
			dev->BindTexture(IGLDevice::Texture2D, 0);
			
			dev->ActiveTexture(0);
			
			return output;
		}
Пример #11
0
		void GLVoxelModel::RenderSunlightPass(std::vector<client::ModelRenderParam> params) {
			SPADES_MARK_FUNCTION();

			device->ActiveTexture(0);
			aoImage->Bind(IGLDevice::Texture2D);
			device->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureMinFilter,
			                     IGLDevice::Linear);

			device->Enable(IGLDevice::CullFace, true);
			device->Enable(IGLDevice::DepthTest, true);

			program->Use();

			static GLShadowShader shadowShader;
			shadowShader(renderer, program, 1);

			static GLProgramUniform fogDistance("fogDistance");
			fogDistance(program);
			fogDistance.SetValue(renderer->GetFogDistance());

			static GLProgramUniform fogColor("fogColor");
			fogColor(program);
			Vector3 fogCol = renderer->GetFogColorForSolidPass();
			fogCol *= fogCol;
			fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z);

			static GLProgramUniform aoUniform("ambientOcclusionTexture");
			aoUniform(program);
			aoUniform.SetValue(0);

			static GLProgramUniform modelOrigin("modelOrigin");
			modelOrigin(program);
			modelOrigin.SetValue(origin.x, origin.y, origin.z);

			static GLProgramUniform sunLightDirection("sunLightDirection");
			sunLightDirection(program);
			Vector3 sunPos = MakeVector3(0, -1, -1);
			sunPos = sunPos.Normalize();
			sunLightDirection.SetValue(sunPos.x, sunPos.y, sunPos.z);

			static GLProgramUniform viewOriginVector("viewOriginVector");
			viewOriginVector(program);
			const auto &viewOrigin = renderer->GetSceneDef().viewOrigin;
			viewOriginVector.SetValue(viewOrigin.x, viewOrigin.y, viewOrigin.z);

			// setup attributes
			static GLProgramAttribute positionAttribute("positionAttribute");
			static GLProgramAttribute textureCoordAttribute("textureCoordAttribute");
			static GLProgramAttribute colorAttribute("colorAttribute");
			static GLProgramAttribute normalAttribute("normalAttribute");

			positionAttribute(program);
			textureCoordAttribute(program);
			colorAttribute(program);
			normalAttribute(program);

			device->BindBuffer(IGLDevice::ArrayBuffer, buffer);
			device->VertexAttribPointer(positionAttribute(), 4, IGLDevice::UnsignedByte, false,
			                            sizeof(Vertex), (void *)0);
			device->VertexAttribPointer(textureCoordAttribute(), 2, IGLDevice::UnsignedShort, false,
			                            sizeof(Vertex), (void *)4);
			device->VertexAttribPointer(colorAttribute(), 4, IGLDevice::UnsignedByte, true,
			                            sizeof(Vertex), (void *)8);
			device->VertexAttribPointer(normalAttribute(), 3, IGLDevice::Byte, false,
			                            sizeof(Vertex), (void *)12);
			device->BindBuffer(IGLDevice::ArrayBuffer, 0);

			device->EnableVertexAttribArray(positionAttribute(), true);
			device->EnableVertexAttribArray(textureCoordAttribute(), true);
			device->EnableVertexAttribArray(colorAttribute(), true);
			device->EnableVertexAttribArray(normalAttribute(), true);

			device->BindBuffer(IGLDevice::ElementArrayBuffer, idxBuffer);

			for (size_t i = 0; i < params.size(); i++) {
				const client::ModelRenderParam &param = params[i];

				// frustrum cull
				float rad = radius;
				rad *= param.matrix.GetAxis(0).GetLength();
				if (!renderer->SphereFrustrumCull(param.matrix.GetOrigin(), rad)) {
					continue;
				}

				static GLProgramUniform customColor("customColor");
				customColor(program);
				customColor.SetValue(param.customColor.x, param.customColor.y, param.customColor.z);

				Matrix4 modelMatrix = param.matrix;
				static GLProgramUniform projectionViewModelMatrix("projectionViewModelMatrix");
				projectionViewModelMatrix(program);
				projectionViewModelMatrix.SetValue(renderer->GetProjectionViewMatrix() *
				                                   modelMatrix);

				static GLProgramUniform viewModelMatrix("viewModelMatrix");
				viewModelMatrix(program);
				viewModelMatrix.SetValue(renderer->GetViewMatrix() * modelMatrix);

				static GLProgramUniform modelMatrixU("modelMatrix");
				modelMatrixU(program);
				modelMatrixU.SetValue(modelMatrix);

				modelMatrix.m[12] = 0.f;
				modelMatrix.m[13] = 0.f;
				modelMatrix.m[14] = 0.f;
				static GLProgramUniform modelNormalMatrix("modelNormalMatrix");
				modelNormalMatrix(program);
				modelNormalMatrix.SetValue(modelMatrix);

				if (param.depthHack) {
					device->DepthRange(0.f, 0.1f);
				}

				device->DrawElements(IGLDevice::Triangles, numIndices, IGLDevice::UnsignedInt,
				                     (void *)0);
				if (param.depthHack) {
					device->DepthRange(0.f, 1.f);
				}
			}

			device->BindBuffer(IGLDevice::ElementArrayBuffer, 0);

			device->EnableVertexAttribArray(positionAttribute(), false);
			device->EnableVertexAttribArray(textureCoordAttribute(), false);
			device->EnableVertexAttribArray(colorAttribute(), false);
			device->EnableVertexAttribArray(normalAttribute(), false);

			device->ActiveTexture(0);
			device->BindTexture(IGLDevice::Texture2D, 0);
		}
Пример #12
0
		void GLVoxelModel::RenderDynamicLightPass(std::vector<client::ModelRenderParam> params,
		                                          std::vector<GLDynamicLight> lights) {
			SPADES_MARK_FUNCTION();

			device->ActiveTexture(0);

			device->Enable(IGLDevice::CullFace, true);
			device->Enable(IGLDevice::DepthTest, true);

			dlightProgram->Use();

			static GLDynamicLightShader dlightShader;

			static GLProgramUniform fogDistance("fogDistance");
			fogDistance(dlightProgram);
			fogDistance.SetValue(renderer->GetFogDistance());

			static GLProgramUniform modelOrigin("modelOrigin");
			modelOrigin(dlightProgram);
			modelOrigin.SetValue(origin.x, origin.y, origin.z);

			static GLProgramUniform sunLightDirection("sunLightDirection");
			sunLightDirection(dlightProgram);
			Vector3 sunPos = MakeVector3(0, -1, -1);
			sunPos = sunPos.Normalize();
			sunLightDirection.SetValue(sunPos.x, sunPos.y, sunPos.z);

			static GLProgramUniform viewOriginVector("viewOriginVector");
			viewOriginVector(dlightProgram);
			const auto &viewOrigin = renderer->GetSceneDef().viewOrigin;
			viewOriginVector.SetValue(viewOrigin.x, viewOrigin.y, viewOrigin.z);

			// setup attributes
			static GLProgramAttribute positionAttribute("positionAttribute");
			static GLProgramAttribute colorAttribute("colorAttribute");
			static GLProgramAttribute normalAttribute("normalAttribute");

			positionAttribute(dlightProgram);
			colorAttribute(dlightProgram);
			normalAttribute(dlightProgram);

			device->BindBuffer(IGLDevice::ArrayBuffer, buffer);
			device->VertexAttribPointer(positionAttribute(), 4, IGLDevice::UnsignedByte, false,
			                            sizeof(Vertex), (void *)0);
			device->VertexAttribPointer(colorAttribute(), 4, IGLDevice::UnsignedByte, true,
			                            sizeof(Vertex), (void *)8);
			device->VertexAttribPointer(normalAttribute(), 3, IGLDevice::Byte, false,
			                            sizeof(Vertex), (void *)12);
			device->BindBuffer(IGLDevice::ArrayBuffer, 0);

			device->EnableVertexAttribArray(positionAttribute(), true);
			device->EnableVertexAttribArray(colorAttribute(), true);
			device->EnableVertexAttribArray(normalAttribute(), true);

			device->BindBuffer(IGLDevice::ElementArrayBuffer, idxBuffer);

			for (size_t i = 0; i < params.size(); i++) {
				const client::ModelRenderParam &param = params[i];

				// frustrum cull
				float rad = radius;
				rad *= param.matrix.GetAxis(0).GetLength();
				if (!renderer->SphereFrustrumCull(param.matrix.GetOrigin(), rad)) {
					continue;
				}

				static GLProgramUniform customColor("customColor");
				customColor(dlightProgram);
				customColor.SetValue(param.customColor.x, param.customColor.y, param.customColor.z);

				Matrix4 modelMatrix = param.matrix;
				static GLProgramUniform projectionViewModelMatrix("projectionViewModelMatrix");
				projectionViewModelMatrix(dlightProgram);
				projectionViewModelMatrix.SetValue(renderer->GetProjectionViewMatrix() *
				                                   modelMatrix);

				static GLProgramUniform viewModelMatrix("viewModelMatrix");
				viewModelMatrix(dlightProgram);
				viewModelMatrix.SetValue(renderer->GetViewMatrix() * modelMatrix);

				static GLProgramUniform modelMatrixU("modelMatrix");
				modelMatrixU(dlightProgram);
				modelMatrixU.SetValue(modelMatrix);

				modelMatrix.m[12] = 0.f;
				modelMatrix.m[13] = 0.f;
				modelMatrix.m[14] = 0.f;
				static GLProgramUniform modelNormalMatrix("modelNormalMatrix");
				modelNormalMatrix(dlightProgram);
				modelNormalMatrix.SetValue(modelMatrix);

				if (param.depthHack) {
					device->DepthRange(0.f, 0.1f);
				}
				for (size_t i = 0; i < lights.size(); i++) {
					if (!GLDynamicLightShader::SphereCull(lights[i], param.matrix.GetOrigin(), rad))
						continue;

					dlightShader(renderer, dlightProgram, lights[i], 0);

					device->DrawElements(IGLDevice::Triangles, numIndices, IGLDevice::UnsignedInt,
					                     (void *)0);
				}
				if (param.depthHack) {
					device->DepthRange(0.f, 1.f);
				}
			}

			device->BindBuffer(IGLDevice::ElementArrayBuffer, 0);

			device->EnableVertexAttribArray(positionAttribute(), false);
			device->EnableVertexAttribArray(colorAttribute(), false);
			device->EnableVertexAttribArray(normalAttribute(), false);

			device->ActiveTexture(0);
		}
		GLColorBuffer GLColorCorrectionFilter::Filter(GLColorBuffer input, Vector3 tintVal) {
			SPADES_MARK_FUNCTION();

			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);

			static GLProgramAttribute lensPosition("positionAttribute");
			static GLProgramUniform lensTexture("mainTexture");

			static GLProgramUniform saturation("saturation");
			static GLProgramUniform enhancement("enhancement");
			static GLProgramUniform tint("tint");

			saturation(lens);
			enhancement(lens);
			tint(lens);

			dev->Enable(IGLDevice::Blend, false);

			lensPosition(lens);
			lensTexture(lens);

			lens->Use();

			tint.SetValue(tintVal.x, tintVal.y, tintVal.z);

			const client::SceneDefinition &def = renderer->GetSceneDef();

			if (settings.r_hdr) {
				// when HDR is enabled ACES tone mapping is applied first, so
				// lower enhancement value is required
				if (settings.r_bloom) {
					saturation.SetValue(0.8f * def.saturation * settings.r_saturation);
					enhancement.SetValue(0.1f);
				} else {
					saturation.SetValue(0.9f * def.saturation * settings.r_saturation);
					enhancement.SetValue(0.0f);
				}
			} else {
				if (settings.r_bloom) {
					// make image sharper
					saturation.SetValue(.85f * def.saturation * settings.r_saturation);
					enhancement.SetValue(0.7f);
				} else {
					saturation.SetValue(1.f * def.saturation * settings.r_saturation);
					enhancement.SetValue(0.3f);
				}
			}

			lensTexture.SetValue(0);

			// composite to the final image
			GLColorBuffer output = input.GetManager()->CreateBufferHandle();

			qr.SetCoordAttributeIndex(lensPosition());
			dev->BindTexture(IGLDevice::Texture2D, input.GetTexture());
			dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer());
			dev->Viewport(0, 0, output.GetWidth(), output.GetHeight());
			qr.Draw();
			dev->BindTexture(IGLDevice::Texture2D, 0);

			return output;
		}
Пример #14
0
		void GLVoxelModel::RenderShadowMapPass(std::vector<client::ModelRenderParam> params) {
			SPADES_MARK_FUNCTION();

			device->Enable(IGLDevice::CullFace, true);
			device->Enable(IGLDevice::DepthTest, true);

			shadowMapProgram->Use();

			static GLShadowMapShader shadowMapShader;
			shadowMapShader(renderer, shadowMapProgram, 0);

			static GLProgramUniform modelOrigin("modelOrigin");
			modelOrigin(shadowMapProgram);
			modelOrigin.SetValue(origin.x, origin.y, origin.z);

			// setup attributes
			static GLProgramAttribute positionAttribute("positionAttribute");
			static GLProgramAttribute normalAttribute("normalAttribute");

			positionAttribute(shadowMapProgram);
			normalAttribute(shadowMapProgram);

			device->BindBuffer(IGLDevice::ArrayBuffer, buffer);
			device->VertexAttribPointer(positionAttribute(), 4, IGLDevice::UnsignedByte, false,
			                            sizeof(Vertex), (void *)0);
			if (normalAttribute() != -1) {
				device->VertexAttribPointer(normalAttribute(), 3, IGLDevice::Byte, false,
				                            sizeof(Vertex), (void *)12);
			}
			device->BindBuffer(IGLDevice::ArrayBuffer, 0);

			device->EnableVertexAttribArray(positionAttribute(), true);
			if (normalAttribute() != -1)
				device->EnableVertexAttribArray(normalAttribute(), true);

			device->BindBuffer(IGLDevice::ElementArrayBuffer, idxBuffer);

			for (size_t i = 0; i < params.size(); i++) {
				const client::ModelRenderParam &param = params[i];

				// frustrum cull
				float rad = radius;
				rad *= param.matrix.GetAxis(0).GetLength();

				if (param.depthHack)
					continue;

				if (!renderer->GetShadowMapRenderer()->SphereCull(param.matrix.GetOrigin(), rad)) {
					continue;
				}

				Matrix4 modelMatrix = param.matrix;

				static GLProgramUniform modelMatrixU("modelMatrix");
				modelMatrixU(shadowMapProgram);
				modelMatrixU.SetValue(modelMatrix);

				modelMatrix.m[12] = 0.f;
				modelMatrix.m[13] = 0.f;
				modelMatrix.m[14] = 0.f;
				static GLProgramUniform modelNormalMatrix("modelNormalMatrix");
				modelNormalMatrix(shadowMapProgram);
				modelNormalMatrix.SetValue(modelMatrix);

				device->DrawElements(IGLDevice::Triangles, numIndices, IGLDevice::UnsignedInt,
				                     (void *)0);
			}

			device->BindBuffer(IGLDevice::ElementArrayBuffer, 0);

			device->EnableVertexAttribArray(positionAttribute(), false);
			if (normalAttribute() != -1)
				device->EnableVertexAttribArray(normalAttribute(), false);

			device->ActiveTexture(0);
			device->BindTexture(IGLDevice::Texture2D, 0);
		}
Пример #15
0
		GLColorBuffer GLFogFilter::Filter(GLColorBuffer input) {
			SPADES_MARK_FUNCTION();
			
			IGLDevice *dev = renderer->GetGLDevice();
			GLQuadRenderer qr(dev);
			
			GLProgram *lens = renderer->RegisterProgram("Shaders/PostFilters/Fog.program");
			static GLProgramAttribute lensPosition("positionAttribute");
			static GLProgramUniform lensShadowMapTexture("shadowMapTexture");
			static GLProgramUniform lensCoarseShadowMapTexture("coarseShadowMapTexture");
			static GLProgramUniform lensColorTexture("colorTexture");
			static GLProgramUniform lensDepthTexture("depthTexture");
			static GLProgramUniform lensFov("fov");
			static GLProgramUniform lensViewOrigin("viewOrigin");
			static GLProgramUniform lensViewAxisUp("viewAxisUp");
			static GLProgramUniform lensViewAxisSide("viewAxisSide");
			static GLProgramUniform lensViewAxisFront("viewAxisFront");
			static GLProgramUniform zNearFar("zNearFar");;
			static GLProgramUniform fogColor("fogColor");
			static GLProgramUniform fogDistance("fogDistance");
			
			dev->Enable(IGLDevice::Blend, false);
			
			lensPosition(lens);
			lensShadowMapTexture(lens);
			lensCoarseShadowMapTexture(lens);
			lensColorTexture(lens);
			lensDepthTexture(lens);
			lensFov(lens);
			lensViewOrigin(lens);
			lensViewAxisUp(lens);
			lensViewAxisSide(lens);
			lensViewAxisFront(lens);
			zNearFar(lens);
			fogColor(lens);
			fogDistance(lens);
			
			lens->Use();
			
			client::SceneDefinition def = renderer->GetSceneDef();
			lensFov.SetValue(tanf(def.fovX * .5f),
							 tanf(def.fovY * .5f));
			lensViewOrigin.SetValue(def.viewOrigin.x,
									def.viewOrigin.y,
									def.viewOrigin.z);
			lensViewAxisUp.SetValue(def.viewAxis[1].x,
									def.viewAxis[1].y,
									def.viewAxis[1].z);
			lensViewAxisSide.SetValue(def.viewAxis[0].x,
									def.viewAxis[0].y,
									  def.viewAxis[0].z);
			lensViewAxisFront.SetValue(def.viewAxis[2].x,
									  def.viewAxis[2].y,
									   def.viewAxis[2].z);
			zNearFar.SetValue(def.zNear, def.zFar);
			
			
			Vector3 fogCol = renderer->GetFogColor();
			fogCol *= fogCol; // linearize
			fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z);
			
			fogDistance.SetValue(128.f);
			
			lensColorTexture.SetValue(0);
			lensDepthTexture.SetValue(1);
			lensShadowMapTexture.SetValue(2);
			lensCoarseShadowMapTexture.SetValue(3);
			
			// composite to the final image
			GLColorBuffer output = input.GetManager()->CreateBufferHandle();
			
			
			dev->Enable(IGLDevice::Blend, false);
			qr.SetCoordAttributeIndex(lensPosition());
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, input.GetTexture());
			dev->ActiveTexture(1);
			dev->BindTexture(IGLDevice::Texture2D, input.GetManager()->GetDepthTexture());
			dev->ActiveTexture(2);
			dev->BindTexture(IGLDevice::Texture2D, renderer->GetMapShadowRenderer()->GetTexture());
			dev->ActiveTexture(3);
			dev->BindTexture(IGLDevice::Texture2D, renderer->GetMapShadowRenderer()->GetCoarseTexture());
			dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer());
			dev->Viewport(0, 0, output.GetWidth(), output.GetHeight());
			qr.Draw();
			dev->ActiveTexture(0);
			dev->BindTexture(IGLDevice::Texture2D, 0);
			
			
			return output;
		}
Пример #16
0
		void GLMapRenderer::RenderSunlightPass() {
			SPADES_MARK_FUNCTION();
			GLProfiler profiler(device, "Map");
			
			Vector3 eye = renderer->GetSceneDef().viewOrigin;
			
			// draw back face to avoid cheating.
			// without this, players can see through blocks by
			// covering themselves by ones.
			RenderBackface();
			
			device->ActiveTexture(0);
			aoImage->Bind(IGLDevice::Texture2D);
			device->TexParamater(IGLDevice::Texture2D,
								 IGLDevice::TextureMinFilter,
								 IGLDevice::Linear);
			
			device->ActiveTexture(1);
			detailImage->Bind(IGLDevice::Texture2D);
			
			
			device->Enable(IGLDevice::CullFace, true);
			device->Enable(IGLDevice::DepthTest, true);
			
			basicProgram->Use();
			
			static GLShadowShader shadowShader;
			shadowShader(renderer, basicProgram, 2);
			
			static GLProgramUniform fogDistance("fogDistance");
			fogDistance(basicProgram);
			fogDistance.SetValue(renderer->GetFogDistance());
			
			static GLProgramUniform viewSpaceLight("viewSpaceLight");
			viewSpaceLight(basicProgram);
			Vector3 vspLight = (renderer->GetViewMatrix() * MakeVector4(0, -1, -1, 0)).GetXYZ();
			viewSpaceLight.SetValue(vspLight.x, vspLight.y, vspLight.z);
			
			static GLProgramUniform fogColor("fogColor");
			fogColor(basicProgram);
			Vector3 fogCol = renderer->GetFogColorForSolidPass();
			fogCol *= fogCol; // linearize
			fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z);
			
			static GLProgramUniform aoUniform("ambientOcclusionTexture");
			aoUniform(basicProgram);
			aoUniform.SetValue(0);
			
			static GLProgramUniform detailTextureUnif("detailTexture");
			detailTextureUnif(basicProgram);
			detailTextureUnif.SetValue(1);
			
			device->BindBuffer(IGLDevice::ArrayBuffer, 0);
			
			static GLProgramAttribute positionAttribute("positionAttribute");
			static GLProgramAttribute ambientOcclusionCoordAttribute("ambientOcclusionCoordAttribute");
			static GLProgramAttribute colorAttribute("colorAttribute");
			static GLProgramAttribute normalAttribute("normalAttribute");
			static GLProgramAttribute fixedPositionAttribute("fixedPositionAttribute");
			
			positionAttribute(basicProgram);
			ambientOcclusionCoordAttribute(basicProgram);
			colorAttribute(basicProgram);
			normalAttribute(basicProgram);
			fixedPositionAttribute(basicProgram);
			
			device->EnableVertexAttribArray(positionAttribute(), true);
			if(ambientOcclusionCoordAttribute() != -1)
				device->EnableVertexAttribArray(ambientOcclusionCoordAttribute(), true);
			device->EnableVertexAttribArray(colorAttribute(), true);
			if(normalAttribute() != -1)
				device->EnableVertexAttribArray(normalAttribute(), true);
			device->EnableVertexAttribArray(fixedPositionAttribute(), true);
			
			static GLProgramUniform projectionViewMatrix("projectionViewMatrix");
			projectionViewMatrix(basicProgram);
			projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix());
			
			static GLProgramUniform viewMatrix("viewMatrix");
			viewMatrix(basicProgram);
			viewMatrix.SetValue(renderer->GetViewMatrix());
			
			RealizeChunks(eye);
			
			// draw from nearest to farthest
			int cx = (int)floorf(eye.x) / GLMapChunk::Size;
			int cy = (int)floorf(eye.y) / GLMapChunk::Size;
			int cz = (int)floorf(eye.z) / GLMapChunk::Size;
			DrawColumnSunlight(cx, cy, cz, eye);
			for(int dist = 1; dist <= 128 / GLMapChunk::Size; dist++) {
				for(int x = cx - dist; x <= cx + dist; x++){
					DrawColumnSunlight(x, cy + dist, cz, eye);
					DrawColumnSunlight(x, cy - dist, cz, eye);
				}
				for(int y = cy - dist + 1; y <= cy + dist - 1; y++){
					DrawColumnSunlight(cx + dist, y, cz, eye);
					DrawColumnSunlight(cx - dist, y, cz, eye);
				}
			}
			
				
			device->EnableVertexAttribArray(positionAttribute(), false);
			if(ambientOcclusionCoordAttribute() != -1)
				device->EnableVertexAttribArray(ambientOcclusionCoordAttribute(), false);
			device->EnableVertexAttribArray(colorAttribute(), false);
			if(normalAttribute() != -1)
				device->EnableVertexAttribArray(normalAttribute(), false);
			device->EnableVertexAttribArray(fixedPositionAttribute(), false);
			
			device->ActiveTexture(1);
			device->BindTexture(IGLDevice::Texture2D, 0);
			device->ActiveTexture(0);
			device->BindTexture(IGLDevice::Texture2D, 0);
		}
Пример #17
0
		void GLSoftSpriteRenderer::Render() {
			SPADES_MARK_FUNCTION();
			lastImage = NULL;
			program->Use();

			device->Enable(IGLDevice::Blend, true);
			device->BlendFunc(IGLDevice::One, IGLDevice::OneMinusSrcAlpha);

			projectionViewMatrix(program);
			rightVector(program);
			frontVector(program);
			viewOriginVector(program);
			upVector(program);
			texture(program);
			depthTexture(program);
			viewMatrix(program);
			fogDistance(program);
			fogColor(program);
			zNearFar(program);

			positionAttribute(program);
			spritePosAttribute(program);
			colorAttribute(program);

			projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix());
			viewMatrix.SetValue(renderer->GetViewMatrix());

			fogDistance.SetValue(renderer->GetFogDistance());

			Vector3 fogCol = renderer->GetFogColor();
			fogCol *= fogCol; // linearize
			fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z);

			const client::SceneDefinition &def = renderer->GetSceneDef();
			rightVector.SetValue(def.viewAxis[0].x, def.viewAxis[0].y, def.viewAxis[0].z);
			upVector.SetValue(def.viewAxis[1].x, def.viewAxis[1].y, def.viewAxis[1].z);
			frontVector.SetValue(def.viewAxis[2].x, def.viewAxis[2].y, def.viewAxis[2].z);

			viewOriginVector.SetValue(def.viewOrigin.x, def.viewOrigin.y, def.viewOrigin.z);
			texture.SetValue(0);
			depthTexture.SetValue(1);
			zNearFar.SetValue(def.zNear, def.zFar);

			device->ActiveTexture(1);
			device->BindTexture(IGLDevice::Texture2D,
			                    renderer->GetFramebufferManager()->GetDepthTexture());
			device->ActiveTexture(0);

			device->EnableVertexAttribArray(positionAttribute(), true);
			device->EnableVertexAttribArray(spritePosAttribute(), true);
			device->EnableVertexAttribArray(colorAttribute(), true);

			thresLow = tanf(def.fovX * .5f) * tanf(def.fovY * .5f) * 1.8f;
			thresRange = thresLow * .5f;

			// full-resolution sprites
			{
				GLProfiler::Context measure(renderer->GetGLProfiler(), "Full Resolution");
				for (size_t i = 0; i < sprites.size(); i++) {
					Sprite &spr = sprites[i];
					float layer = LayerForSprite(spr);
					if (layer == 1.f)
						continue;
					if (spr.image != lastImage) {
						Flush();
						lastImage = spr.image;
						SPAssert(vertices.empty());
					}

					Vertex v;
					v.x = spr.center.x;
					v.y = spr.center.y;
					v.z = spr.center.z;
					v.radius = spr.radius;
					v.angle = spr.angle;
					v.r = spr.color.x;
					v.g = spr.color.y;
					v.b = spr.color.z;
					v.a = spr.color.w;

					float fade = 1.f - layer;
					v.r *= fade;
					v.g *= fade;
					v.b *= fade;
					v.a *= fade;

					uint32_t idx = (uint32_t)vertices.size();
					v.sx = -1;
					v.sy = -1;
					vertices.push_back(v);
					v.sx = 1;
					v.sy = -1;
					vertices.push_back(v);
					v.sx = -1;
					v.sy = 1;
					vertices.push_back(v);
					v.sx = 1;
					v.sy = 1;
					vertices.push_back(v);

					indices.push_back(idx);
					indices.push_back(idx + 1);
					indices.push_back(idx + 2);
					indices.push_back(idx + 1);
					indices.push_back(idx + 3);
					indices.push_back(idx + 2);
				}

				Flush();
			}

			// low-res sprites
			IGLDevice::UInteger lastFb = device->GetInteger(IGLDevice::FramebufferBinding);
			int sW = device->ScreenWidth(), sH = device->ScreenHeight();
			int lW = (sW + 3) / 4, lH = (sH + 3) / 4;
			int numLowResSprites = 0;
			GLColorBuffer buf = renderer->GetFramebufferManager()->CreateBufferHandle(lW, lH, true);
			device->BindFramebuffer(IGLDevice::Framebuffer, buf.GetFramebuffer());
			device->ClearColor(0.f, 0.f, 0.f, 0.f);
			device->Clear(IGLDevice::ColorBufferBit);
			device->BlendFunc(IGLDevice::One, IGLDevice::OneMinusSrcAlpha);
			device->Viewport(0, 0, lW, lH);
			{
				GLProfiler::Context measure(renderer->GetGLProfiler(), "Low Resolution");
				for (size_t i = 0; i < sprites.size(); i++) {
					Sprite &spr = sprites[i];
					float layer = LayerForSprite(spr);
					if (layer == 0.f)
						continue;
					if (spr.image != lastImage) {
						Flush();
						lastImage = spr.image;
						SPAssert(vertices.empty());
					}

					numLowResSprites++;

					Vertex v;
					v.x = spr.center.x;
					v.y = spr.center.y;
					v.z = spr.center.z;
					v.radius = spr.radius;
					v.angle = spr.angle;
					v.r = spr.color.x;
					v.g = spr.color.y;
					v.b = spr.color.z;
					v.a = spr.color.w;

					float fade = layer;
					v.r *= fade;
					v.g *= fade;
					v.b *= fade;
					v.a *= fade;

					uint32_t idx = (uint32_t)vertices.size();
					v.sx = -1;
					v.sy = -1;
					vertices.push_back(v);
					v.sx = 1;
					v.sy = -1;
					vertices.push_back(v);
					v.sx = -1;
					v.sy = 1;
					vertices.push_back(v);
					v.sx = 1;
					v.sy = 1;
					vertices.push_back(v);

					indices.push_back(idx);
					indices.push_back(idx + 1);
					indices.push_back(idx + 2);
					indices.push_back(idx + 1);
					indices.push_back(idx + 3);
					indices.push_back(idx + 2);
				}
				Flush();
			}

			// finalize

			device->ActiveTexture(1);
			device->BindTexture(IGLDevice::Texture2D, 0);
			device->ActiveTexture(0);
			device->BindTexture(IGLDevice::Texture2D, 0);
			device->EnableVertexAttribArray(positionAttribute(), false);
			device->EnableVertexAttribArray(spritePosAttribute(), false);
			device->EnableVertexAttribArray(colorAttribute(), false);

			// composite downsampled sprite
			device->BlendFunc(IGLDevice::One, IGLDevice::OneMinusSrcAlpha);
			if (numLowResSprites > 0) {
				GLProfiler::Context measure(renderer->GetGLProfiler(), "Finalize");
				GLQuadRenderer qr(device);

				// do gaussian blur
				GLProgram *program =
				  renderer->RegisterProgram("Shaders/PostFilters/Gauss1D.program");
				static GLProgramAttribute blur_positionAttribute("positionAttribute");
				static GLProgramUniform blur_textureUniform("mainTexture");
				static GLProgramUniform blur_unitShift("unitShift");
				program->Use();
				blur_positionAttribute(program);
				blur_textureUniform(program);
				blur_unitShift(program);
				blur_textureUniform.SetValue(0);
				device->ActiveTexture(0);
				qr.SetCoordAttributeIndex(blur_positionAttribute());
				device->Enable(IGLDevice::Blend, false);

				// x-direction
				GLColorBuffer buf2 =
				  renderer->GetFramebufferManager()->CreateBufferHandle(lW, lH, true);
				device->BindTexture(IGLDevice::Texture2D, buf.GetTexture());
				device->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
				blur_unitShift.SetValue(1.f / lW, 0.f);
				qr.Draw();
				buf.Release();

				// x-direction
				GLColorBuffer buf3 =
				  renderer->GetFramebufferManager()->CreateBufferHandle(lW, lH, true);
				device->BindTexture(IGLDevice::Texture2D, buf2.GetTexture());
				device->BindFramebuffer(IGLDevice::Framebuffer, buf3.GetFramebuffer());
				blur_unitShift.SetValue(0.f, 1.f / lH);
				qr.Draw();
				buf2.Release();

				buf = buf3;

				device->Enable(IGLDevice::Blend, true);

				// composite
				program = renderer->RegisterProgram("Shaders/PostFilters/PassThrough.program");
				static GLProgramAttribute positionAttribute("positionAttribute");
				static GLProgramUniform colorUniform("colorUniform");
				static GLProgramUniform textureUniform("mainTexture");
				static GLProgramUniform texCoordRange("texCoordRange");

				positionAttribute(program);
				textureUniform(program);
				texCoordRange(program);
				colorUniform(program);

				program->Use();

				textureUniform.SetValue(0);
				texCoordRange.SetValue(0.f, 0.f, 1.f, 1.f);
				colorUniform.SetValue(1.f, 1.f, 1.f, 1.f);

				qr.SetCoordAttributeIndex(positionAttribute());
				device->BindFramebuffer(IGLDevice::Framebuffer, lastFb);
				device->BindTexture(IGLDevice::Texture2D, buf.GetTexture());
				device->Viewport(0, 0, sW, sH);
				qr.Draw();
				device->BindTexture(IGLDevice::Texture2D, 0);

			} else {
				device->Viewport(0, 0, sW, sH);

				device->BindFramebuffer(IGLDevice::Framebuffer, lastFb);
			}

			buf.Release();
		}
Пример #18
0
		void GLMapRenderer::RenderBackface() {
			GLProfiler profiler(device, "Back-face");
			
			IntVector3 eye = renderer->GetSceneDef().viewOrigin.Floor();
			std::vector<BFVertex> vertices;
			std::vector<uint16_t> indices;
			client::GameMap *m = gameMap;
			
			int x, y, z;
			const int range = 1;
			for(x = eye.x - range; x <= eye.x + range; x++) {
				for(y = eye.y - range; y <= eye.y + range; y++) {
					for(z = eye.z - range; z <= eye.z + range; z++) {
						if(z >= 63) continue;
						if(z < 0) continue;
						if(!m->IsSolidWrapped(x, y, z))
							continue;
						SPAssert(m->IsSolidWrapped(x, y, z));
						
						if(m->IsSolidWrapped(x-1, y, z)) {
							EmitBackFace(x, y, z,
										 0, 1, 0,
										 0, 0, 1,
										 vertices, indices);
						}
						if(m->IsSolidWrapped(x+1, y, z)) {
							EmitBackFace(x+1, y, z,
										 0, 1, 0,
										 0, 0, 1,
										 vertices, indices);
						}
						if(m->IsSolidWrapped(x, y-1, z)) {
							EmitBackFace(x, y, z,
										 1, 0, 0,
										 0, 0, 1,
										 vertices, indices);
						}
						if(m->IsSolidWrapped(x, y+1, z)) {
							EmitBackFace(x, y+1, z,
										 1, 0, 0,
										 0, 0, 1,
										 vertices, indices);
						}
						if(m->IsSolidWrapped(x, y, z-1)) {
							EmitBackFace(x, y, z,
										 1, 0, 0,
										 0, 1, 0,
										 vertices, indices);
						}
						if(m->IsSolidWrapped(x, y, z+1)) {
							EmitBackFace(x, y, z+1,
										 1, 0, 0,
										 0, 1, 0,
										 vertices, indices);
						}
					}
				}
			}
			
			if(vertices.empty())
				return;
			
			device->Enable(IGLDevice::CullFace, false);
			
			backfaceProgram->Use();
			
			static GLProgramAttribute positionAttribute("positionAttribute");
			static GLProgramUniform projectionViewMatrix("projectionViewMatrix");
			
			positionAttribute(backfaceProgram);
			projectionViewMatrix(backfaceProgram);
			
			projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix());
			
			device->BindBuffer(IGLDevice::ArrayBuffer, 0);
			device->VertexAttribPointer(positionAttribute(),
										3, IGLDevice::Short,
										false, sizeof(BFVertex),
										vertices.data());
			
			device->EnableVertexAttribArray(positionAttribute(), true);
			
			device->BindBuffer(IGLDevice::ElementArrayBuffer, 0);
			device->DrawElements(IGLDevice::Triangles, indices.size(),
								 IGLDevice::UnsignedShort, indices.data());
			
			device->EnableVertexAttribArray(positionAttribute(), false);
			
			device->Enable(IGLDevice::CullFace, true);
			
		}
Пример #19
0
		void GLMapRenderer::RenderDynamicLightPass(std::vector<GLDynamicLight> lights) {
			SPADES_MARK_FUNCTION();
			
			GLProfiler profiler(device, "Map");
			
			if(lights.empty())
				return;
			
			
			Vector3 eye = renderer->GetSceneDef().viewOrigin;
			
			device->ActiveTexture(0);
			detailImage->Bind(IGLDevice::Texture2D);
			
			device->Enable(IGLDevice::CullFace, true);
			device->Enable(IGLDevice::DepthTest, true);
			
			dlightProgram->Use();
			
			static GLProgramUniform fogDistance("fogDistance");
			fogDistance(dlightProgram);
			fogDistance.SetValue(renderer->GetFogDistance());
			
			static GLProgramUniform detailTextureUnif("detailTexture");
			detailTextureUnif(dlightProgram);
			detailTextureUnif.SetValue(0);
			
			device->BindBuffer(IGLDevice::ArrayBuffer, 0);
			
			static GLProgramAttribute positionAttribute("positionAttribute");
			static GLProgramAttribute colorAttribute("colorAttribute");
			static GLProgramAttribute normalAttribute("normalAttribute");
			
			positionAttribute(dlightProgram);
			colorAttribute(dlightProgram);
			normalAttribute(dlightProgram);
			
			device->EnableVertexAttribArray(positionAttribute(), true);
			device->EnableVertexAttribArray(colorAttribute(), true);
			device->EnableVertexAttribArray(normalAttribute(), true);
			
			static GLProgramUniform projectionViewMatrix("projectionViewMatrix");
			projectionViewMatrix(dlightProgram);
			projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix());
			
			static GLProgramUniform viewMatrix("viewMatrix");
			viewMatrix(dlightProgram);
			viewMatrix.SetValue(renderer->GetViewMatrix());
			
			RealizeChunks(eye);
			
			// draw from nearest to farthest
			int cx = (int)floorf(eye.x) / GLMapChunk::Size;
			int cy = (int)floorf(eye.y) / GLMapChunk::Size;
			int cz = (int)floorf(eye.z) / GLMapChunk::Size;
			DrawColumnDLight(cx, cy, cz, eye, lights);
			// TODO: optimize call
			//       ex. don't call a chunk'r render method if
			//           no dlight lights it
			for(int dist = 1; dist <= 128 / GLMapChunk::Size; dist++) {
				for(int x = cx - dist; x <= cx + dist; x++){
					DrawColumnDLight(x, cy + dist, cz, eye, lights);
					DrawColumnDLight(x, cy - dist, cz, eye, lights);
				}
				for(int y = cy - dist + 1; y <= cy + dist - 1; y++){
					DrawColumnDLight(cx + dist, y, cz, eye, lights);
					DrawColumnDLight(cx - dist, y, cz, eye, lights);
				}
			}
			
			
			device->EnableVertexAttribArray(positionAttribute(), false);
			device->EnableVertexAttribArray(colorAttribute(), false);
			device->EnableVertexAttribArray(normalAttribute(), false);
			
			device->ActiveTexture(0);
			device->BindTexture(IGLDevice::Texture2D, 0);
		}