From cb4b696e1260cb4193936ef7499e9201d361c769 Mon Sep 17 00:00:00 2001
From: Anselme <anselme.francois@gmail.com>
Date: Thu, 21 Jul 2016 17:30:03 +0200
Subject: [PATCH] added picking

---
 shaders/gbuffer.frag.glsl  | 16 ++++++++++------
 shaders/lighting.frag.glsl | 12 ++++++------
 src/deferredpipeline.cpp   | 36 +++++++++++++++++++++++-------------
 src/deferredpipeline.h     |  4 +++-
 src/trackballcamera.cpp    |  7 +++++++
 src/trackballcamera.h      |  1 +
 6 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/shaders/gbuffer.frag.glsl b/shaders/gbuffer.frag.glsl
index 1ddf6fa..4061260 100644
--- a/shaders/gbuffer.frag.glsl
+++ b/shaders/gbuffer.frag.glsl
@@ -1,11 +1,11 @@
-// - Normal buffer
-layout (location = 0) out vec3 outNormal;
+// - Position in view space
+layout (location = 0) out vec4 outPosition;
 // - Color + objectId buffer
 layout (location = 1) out vec4 outColor;
+// - Normal buffer
+layout (location = 2) out vec3 outNormal;
 // - Specular color + Specular exponent buffer
-layout (location = 2) out vec4 outSpecular;
-// - Position in view space
-layout (location = 3) out vec4 outPosition;
+layout (location = 3) out vec4 outSpecular;
 
 uniform float materialNs;
 
@@ -69,7 +69,11 @@ void main()
 	 outColor.rgb = materialKd;
 #endif
 
-	 outColor.a = float(object_identifier)/255;
+#ifdef INSTANCED
+    outColor.a = float(object_identifier+instanceId)/255;
+#else
+    outColor.a = float(object_identifier)/255;
+#endif
 
 #ifdef SPECULAR_TEXTURE
 	 outSpecular.rgb = texture(specularTexture, varTexCoord).rgb;
diff --git a/shaders/lighting.frag.glsl b/shaders/lighting.frag.glsl
index 2f15600..0fe2714 100644
--- a/shaders/lighting.frag.glsl
+++ b/shaders/lighting.frag.glsl
@@ -1,13 +1,13 @@
 // G-BUFFER
 
-// - Normal buffer
-uniform sampler2DRect normalBuffer;
-// - Color + objectId buffer
-uniform sampler2DRect colorBuffer;
-// - Specular color + Specular exponent buffer
-uniform sampler2DRect specularBuffer;
 // - Position in view space
 uniform sampler2DRect positionBuffer;
+// - Color + objectId buffer
+uniform sampler2DRect colorBuffer;
+// - Normal buffer
+uniform sampler2DRect normalBuffer;
+// - Specular color + Specular exponent buffer
+uniform sampler2DRect specularBuffer;
 // - depth buffer
 uniform sampler2DRect depthBuffer;
 
diff --git a/src/deferredpipeline.cpp b/src/deferredpipeline.cpp
index 927de58..55e279c 100644
--- a/src/deferredpipeline.cpp
+++ b/src/deferredpipeline.cpp
@@ -15,28 +15,29 @@ RESOURCE_PACK(shaders)
 GBuffer::GBuffer(int width, int height) : FrameBuffer()
 {
     Texture* tex;
-    // - Normal buffer
-    tex = new Texture(GL_RGB, GL_RGB16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
+    
+    // - Position buffer
+    tex = new Texture(GL_RGBA, GL_RGBA16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
     tex->setFiltering(GL_NEAREST);
-    tex->setUnit(NORMAL);
+    tex->setUnit(POSITION);
     addTexture(tex, GL_COLOR_ATTACHMENT0);
-
+    
     // - Color + objectId buffer
     tex = new Texture(GL_RGBA, GL_RGBA, width, height, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE);
     tex->setFiltering(GL_NEAREST);
     tex->setUnit(DIFFUSE);
     addTexture(tex, GL_COLOR_ATTACHMENT1);
+    
+    // - Normal buffer
+    tex = new Texture(GL_RGB, GL_RGB16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
+    tex->setFiltering(GL_NEAREST);
+    tex->setUnit(NORMAL);
+    addTexture(tex, GL_COLOR_ATTACHMENT2);
 
     // - Specular color + Specular exponent buffer
     tex = new Texture(GL_RGBA, GL_RGBA, width, height, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE);
     tex->setFiltering(GL_NEAREST);
     tex->setUnit(SPECULAR);
-    addTexture(tex, GL_COLOR_ATTACHMENT2);
-
-    // - Position buffer
-    tex = new Texture(GL_RGBA, GL_RGBA16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
-    tex->setFiltering(GL_NEAREST);
-    tex->setUnit(POSITION);
     addTexture(tex, GL_COLOR_ATTACHMENT3);
 
     // - depth buffer
@@ -163,10 +164,10 @@ void DeferredPipeline::renderGL(Scene *scene)
         shader->bind();
 
         // bind GBuffer
-        shader->bindInteger(shader->getLocation("normalBuffer"), GBuffer::NORMAL);
-        shader->bindInteger(shader->getLocation("colorBuffer"), GBuffer::DIFFUSE);
-        shader->bindInteger(shader->getLocation("specularBuffer"), GBuffer::SPECULAR);
         shader->bindInteger(shader->getLocation("positionBuffer"), GBuffer::POSITION);
+        shader->bindInteger(shader->getLocation("colorBuffer"), GBuffer::DIFFUSE);
+        shader->bindInteger(shader->getLocation("normalBuffer"), GBuffer::NORMAL);
+        shader->bindInteger(shader->getLocation("specularBuffer"), GBuffer::SPECULAR);
         shader->bindInteger(shader->getLocation("depthBuffer"), GBuffer::DEPTH);
 
         // bind light
@@ -261,3 +262,12 @@ void DeferredPipeline::refreshScene(Scene *scene)
     for(unsigned int type : m_lightTypes)
         m_lightShaders[type] = m_lightingSource->compile(0, type);
 }
+
+glm::vec4 DeferredPipeline::pick(int x, int y)
+{
+	m_gBuffer->bindFBO();
+	glm::vec4 pos;
+    glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, glm::value_ptr(pos));
+	FrameBuffer::screen->bindFBO();
+	return pos;
+}
diff --git a/src/deferredpipeline.h b/src/deferredpipeline.h
index e9184c2..c252412 100644
--- a/src/deferredpipeline.h
+++ b/src/deferredpipeline.h
@@ -12,7 +12,7 @@ class Camera;
 class GBuffer : public FrameBuffer
 {
 public:
-    enum Buffers { NORMAL, DIFFUSE, SPECULAR, POSITION, DEPTH, NB_BUFFERS };
+    enum Buffers { POSITION, DIFFUSE, NORMAL, SPECULAR, DEPTH, NB_BUFFERS };
     GBuffer(int width, int height);
     void bindTextures();
     void unbindTextures();
@@ -61,6 +61,8 @@ public:
     
     virtual void renderGL(Scene *scene);
     virtual void resizeGL(int w, int h);
+	
+	glm::vec4 pick(int x, int y);
 };
 
 #endif // DEFERREDPIPELINE_H
diff --git a/src/trackballcamera.cpp b/src/trackballcamera.cpp
index af75d4d..0409b42 100644
--- a/src/trackballcamera.cpp
+++ b/src/trackballcamera.cpp
@@ -42,6 +42,13 @@ void TrackBallCamera::moveCamera(const glm::vec3 &diff)
     computeView();
 }
 
+void TrackBallCamera::lookAt(const glm::vec3 &pos)
+{
+	m_dist = glm::length(target);
+	m_center = pos;
+	computeView();
+}
+
 void TrackBallCamera::reset()
 {
     m_center = glm::vec3(0, 4, 0);
diff --git a/src/trackballcamera.h b/src/trackballcamera.h
index 17cc7c5..455cdc5 100644
--- a/src/trackballcamera.h
+++ b/src/trackballcamera.h
@@ -21,6 +21,7 @@ public:
     void rotateCamera(float dx, float dy);
     void moveCamera(float dx, float dy);
     void moveCamera(const glm::vec3 &diff);
+	void lookAt(const glm::vec3 &pos);
 	void zoom(int nbScrolls);
     void reset();
     glm::vec3 getDefaultPxInfo();