|  | @@ -55,6 +55,8 @@ static Button modeToggle{GLFW_KEY_C, "mode toggle"};
 | 
	
		
			
				|  |  |  static Button primaryMouse{GLFW_MOUSE_BUTTON_1, "primary click"};
 | 
	
		
			
				|  |  |  static Button timeUp{GLFW_KEY_N, "time up"};
 | 
	
		
			
				|  |  |  static Button timeDown{GLFW_KEY_M, "time down"};
 | 
	
		
			
				|  |  | +static Button tesselationUp{GLFW_KEY_4, "time up"};
 | 
	
		
			
				|  |  | +static Button tesselationDown{GLFW_KEY_5, "time down"};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static Vector3 oldPosition;
 | 
	
		
			
				|  |  |  static Vector3 position{-32.0f, 0.0f, -120.0f};
 | 
	
	
		
			
				|  | @@ -65,6 +67,7 @@ static int steps = 1;
 | 
	
		
			
				|  |  |  static int fineSteps = 1;
 | 
	
		
			
				|  |  |  static bool mode = false;
 | 
	
		
			
				|  |  |  static float timeTicks = 0.0f;
 | 
	
		
			
				|  |  | +static int tesselation = 1;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static Vector3 emitterPos;
 | 
	
		
			
				|  |  |  static float emitterAge = 999999.0f;
 | 
	
	
		
			
				|  | @@ -132,10 +135,23 @@ static void tickParallaxSettings() {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void tickTesselation() {
 | 
	
		
			
				|  |  | +    if(tesselationUp.isDown()) {
 | 
	
		
			
				|  |  | +        tesselation++;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if(tesselationDown.isDown() && tesselation > 1) {
 | 
	
		
			
				|  |  | +        tesselation--;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void tickGame() {
 | 
	
		
			
				|  |  |      tickTimeFactors();
 | 
	
		
			
				|  |  |      tickMovement();
 | 
	
		
			
				|  |  |      tickParallaxSettings();
 | 
	
		
			
				|  |  | +    tickTesselation();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    printf("\rFPS: %.2f", window.getFrameClock().getUpdatesPerSecond());
 | 
	
		
			
				|  |  | +    fflush(stdout);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void prepareMatrices(float lag) {
 | 
	
	
		
			
				|  | @@ -180,9 +196,6 @@ static void renderCubes(Matrix& view) {
 | 
	
		
			
				|  |  |      cubeShader.setInt("fineSteps", fineSteps);
 | 
	
		
			
				|  |  |      cubeShader.setInt("kajetan", mode);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if(toggle.isDown()) {
 | 
	
		
			
				|  |  | -        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |      noiceBuffer.bindTextureTo(0);
 | 
	
		
			
				|  |  |      bricks.bindTo(1);
 | 
	
		
			
				|  |  |      bricksBump.bindTo(2);
 | 
	
	
		
			
				|  | @@ -195,7 +208,6 @@ static void renderCubes(Matrix& view) {
 | 
	
		
			
				|  |  |          cubeShader.setMatrix("model", model.getValues());
 | 
	
		
			
				|  |  |          emptyBuffer.drawPoints(64 * 64 * 64);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void pickParticleCenter() {
 | 
	
	
		
			
				|  | @@ -257,7 +269,7 @@ static void renderParticles(float lag) {
 | 
	
		
			
				|  |  |      particleShader.setFloat("age", emitterAge);
 | 
	
		
			
				|  |  |      particleShader.setVector("color", Vector4(1.0f, 0.0f, 0.0f, 1.0f));
 | 
	
		
			
				|  |  |      particleShader.setInt("seedBase", 0);
 | 
	
		
			
				|  |  | -    emptyBuffer.drawPoints(2000000);
 | 
	
		
			
				|  |  | +    emptyBuffer.drawPoints(200000);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      particleShader.setVector("position", emitterPos);
 | 
	
		
			
				|  |  |      particleShader.setFloat("age", emitterAge + 5);
 | 
	
	
		
			
				|  | @@ -287,15 +299,24 @@ static void renderBackground(Matrix& view) {
 | 
	
		
			
				|  |  |      backgroundShader.setMatrix("proj", frustum.updateProjection().getValues());
 | 
	
		
			
				|  |  |      backgroundShader.setMatrix("view", view.getValues());
 | 
	
		
			
				|  |  |      model.translateTo(Vector3(0.0f, 0.0f, 0.0f));
 | 
	
		
			
				|  |  | -    model.scale(Vector3(260.0f, 120.0f, 1.0f));
 | 
	
		
			
				|  |  | -    model.translate(Vector3(0.0f, 20.0f, -200.0f));
 | 
	
		
			
				|  |  | +    model.scale(Vector3(520.0f, 180.0f, 1.0f));
 | 
	
		
			
				|  |  | +    model.translate(Vector3(-260.0f, -40.0f, -200.0f));
 | 
	
		
			
				|  |  |      model.rotateX(-5.0f);
 | 
	
		
			
				|  |  |      backgroundShader.setMatrix("model", model.getValues());
 | 
	
		
			
				|  |  |      backgroundShader.setMatrix("shadow", shadowProjectionView.getValues());
 | 
	
		
			
				|  |  | -    rectangleBuffer.draw(6);
 | 
	
		
			
				|  |  | +    backgroundShader.setInt("splits", tesselation);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    glPatchParameteri(GL_PATCH_VERTICES, 1);
 | 
	
		
			
				|  |  | +    glDrawArrays(GL_PATCHES, 0, 1);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void renderGame(float lag) {
 | 
	
		
			
				|  |  | +    if(toggle.isDown()) {
 | 
	
		
			
				|  |  | +        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      GL::enableDepthTesting();
 | 
	
		
			
				|  |  |      prepareMatrices(lag);
 | 
	
		
			
				|  |  |      renderNoise();
 | 
	
	
		
			
				|  | @@ -330,8 +351,7 @@ void Game::init() {
 | 
	
		
			
				|  |  |          error.message.printLine();
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    error = noiseShader.compile("resources/noise.vs", nullptr,
 | 
	
		
			
				|  |  | -                                "resources/noise.fs");
 | 
	
		
			
				|  |  | +    error = noiseShader.compile("resources/noise.vs", "resources/noise.fs");
 | 
	
		
			
				|  |  |      if(error.has()) {
 | 
	
		
			
				|  |  |          error.message.printLine();
 | 
	
		
			
				|  |  |          return;
 | 
	
	
		
			
				|  | @@ -343,14 +363,14 @@ void Game::init() {
 | 
	
		
			
				|  |  |          error.message.printLine();
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    error = backgroundShader.compile("resources/background.vs", nullptr,
 | 
	
		
			
				|  |  | -                                     "resources/background.fs");
 | 
	
		
			
				|  |  | +    error = backgroundShader.compile(
 | 
	
		
			
				|  |  | +        "resources/background.vs", "resources/background.fs",
 | 
	
		
			
				|  |  | +        "resources/background.tcs", "resources/background.tes");
 | 
	
		
			
				|  |  |      if(error.has()) {
 | 
	
		
			
				|  |  |          error.message.printLine();
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    error =
 | 
	
		
			
				|  |  | -        blurShader.compile("resources/blur.vs", nullptr, "resources/blur.fs");
 | 
	
		
			
				|  |  | +    error = blurShader.compile("resources/blur.vs", "resources/blur.fs");
 | 
	
		
			
				|  |  |      if(error.has()) {
 | 
	
		
			
				|  |  |          error.message.printLine();
 | 
	
		
			
				|  |  |          return;
 | 
	
	
		
			
				|  | @@ -398,6 +418,8 @@ void Game::init() {
 | 
	
		
			
				|  |  |      window.buttons.add(modeToggle);
 | 
	
		
			
				|  |  |      window.buttons.add(timeUp);
 | 
	
		
			
				|  |  |      window.buttons.add(timeDown);
 | 
	
		
			
				|  |  | +    window.buttons.add(tesselationUp);
 | 
	
		
			
				|  |  | +    window.buttons.add(tesselationDown);
 | 
	
		
			
				|  |  |      window.buttons.addMouse(primaryMouse);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      bricks.setLinearFilter();
 |