Multiple glViewPort calls making triangles glitch out!?

Please help somebody!!

I’ve got a bug I can’t figure out - I’ve been working on it all day and I’m going in circles.

Triangles randomly disappear on some frames, sometimes. It’s not reproducible so occasionally it’s really bad but most of the time it doesn’t show up so it’s hard to test. Here is a video of the bug showing up particularly badly (start at 50 seconds in).

Here is the diff that introduces the error:


diff --git a/rendering_pipeline/advanced_shader.xml b/rendering_pipeline/advanced_shader.xml
index bc0420e..6f860d0 100644
--- a/rendering_pipeline/advanced_shader.xml
+++ b/rendering_pipeline/advanced_shader.xml
@@ -7,12 +7,14 @@
     <num_color_layers> 2 </num_color_layers>
     <color_layer0> color_buffer </color_layer1>
     <color_layer1> normal_buffer </color_layer0>
+    <resolution_multiplier> 4 </resolution_multiplier>
     <!-- color_layer2, "depth_buffer", is implicit if using_depth == true -->
   </world_scene_image>
   <pixelation>
     <using_depth_buffer> false </using_depth_buffer>
     <num_color_layers> 1 </num_color_layers>
     <color_layer0> pixel_buffer </color_layer1>
+    <resolution_multiplier> 4 </resolution_multiplier>
   </pixelation>
 </resources>
 
diff --git a/rendering_pipeline/basic_shader.xml b/rendering_pipeline/basic_shader.xml
index 10fe1b3..49e78fa 100644
--- a/rendering_pipeline/basic_shader.xml
+++ b/rendering_pipeline/basic_shader.xml
@@ -8,6 +8,7 @@
     <color_layer0> color_buffer </color_layer1>
     <color_layer1> normal_buffer </color_layer0>
     <!-- color_layer2, "depth_buffer", is implicit if using_depth == true -->
+    <resolution_multiplier> 1 </resolution_multiplier>
   </world_scene_image>
 </resources>
 
diff --git a/shaders/fragment/pixelation.fs b/shaders/fragment/pixelation.fs
index 8a06c7a..8980ee9 100644
--- a/shaders/fragment/pixelation.fs
+++ b/shaders/fragment/pixelation.fs
@@ -6,5 +6,14 @@ uniform int width;
 uniform int height;
 
 void main() {
-  gl_FragColor = 1-texture2D(pixel_buffer, gl_TexCoord[0].st);
+  gl_FragColor = vec4(0,0,0,0);
+  int counter = 0;
+  int size = 4;
+  for(int x = 0;x < size;x++) {
+    for(int y = 0;y < size;y++) {
+      gl_FragColor += texture2D(pixel_buffer, vec2(gl_TexCoord[0].s + x*(1.0 / (width*size)), gl_TexCoord[0].t + y*(1.0 / (height*size))));
+      counter++;
+    }
+  }
+  gl_FragColor /= counter;
 }
diff --git a/src/renderer/image_buffer.h b/src/renderer/image_buffer.h
index c43c709..ef76f2f 100644
--- a/src/renderer/image_buffer.h
+++ b/src/renderer/image_buffer.h
@@ -19,13 +19,16 @@
 
 class ImageBuffer {
 public:
-  ImageBuffer(int width, int height, XMLTree buffer_info) {
+  ImageBuffer(int port_width, int port_height, XMLTree buffer_info) {
     if(buffer_info.IsInvalid()) {
       std::cout << "Invalid image buffer.
";
       return;
     }
 
     name = buffer_info.GetName();
+    resolution_multiplier = buffer_info.GetFloatValueOf("resolution_multiplier");
+    port_width *= resolution_multiplier;
+    port_height *= resolution_multiplier;
     num_colour_buffers = buffer_info.GetIntValueOf("num_color_layers");
     if(num_colour_buffers < 1 || num_colour_buffers > 3) {
       std::cout << "This is not a valid buffer count: " << num_colour_buffers << "
";
@@ -33,7 +36,7 @@ public:
     }
 
     bool using_depth_buffer = buffer_info.GetBoolValueOf("using_depth_buffer");
-    Setup(width, height, using_depth_buffer);
+    Setup(port_width, port_height, using_depth_buffer);
 
     for(int i = 0;i < num_colour_buffers;i++) {
       std::string new_color_layer_name = buffer_info.GetStringValueOf("color_layer" + std::to_string(i));
@@ -42,6 +45,7 @@ public:
 
     if(using_depth_buffer)
       layer_names.AddItem("depth_buffer");
+
   }
 
   ~ImageBuffer() {
@@ -67,6 +71,7 @@ public:
   SimpleContainer<std::string> GetLayerNames() { return layer_names; }
   GLuint GetColorBuffer(int index) { return colour_buffers[index]; }
   GLuint GetDepthBuffer() { return depth_buffer; }
+  float GetResolutionMultiplier() { return resolution_multiplier; }
 
 private:
   void Setup(int port_width, int port_height, bool has_depth_buffer) {
@@ -102,12 +109,12 @@ private:
 
     glBindTexture(GL_TEXTURE_2D, previous_texture_binding);
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, previous_frame_buffer_binding);
-
   }
 
   int width, height;
   int num_colour_buffers;
   bool using_depth_buffer;
+  float resolution_multiplier;
 
   std::string attachment_names[4];
   std::string name;
diff --git a/src/renderer/pipeline/render_stage.h b/src/renderer/pipeline/render_stage.h
index e2695b8..ad2a403 100644
--- a/src/renderer/pipeline/render_stage.h
+++ b/src/renderer/pipeline/render_stage.h
@@ -49,10 +49,13 @@ private:
 
   void SetupOutputSource() {
     std::string output_location_name = render_stage_output->GetOutputLocationName();
-    if(output_location_name == "SCREEN")
+    if(output_location_name == "SCREEN") {
+      glViewport(0, 0, viewport->GetWidth(), viewport->GetHeight());
       ImageBuffer::RenderToScreen();
-    else {
+    } else {
       ImageBuffer* output_image = GetImage(output_location_name);
+      float resolution_multiplier = output_image->GetResolutionMultiplier();
+      glViewport(0, 0, viewport->GetWidth()*resolution_multiplier, viewport->GetHeight()*resolution_multiplier);
       output_image->RenderToImageBuffer();
     }
   }

It seems that the glViewport calls are messing with it. When I get rid of them, I’m fairly sure the bug goes away. But why would calling glViewport create such a non-viewport related bug? Does anyone have any idea what I’m doing wrong? Please help!