Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Resizing the picking buffers to match the viewport.

  • Loading branch information...
commit fbb6adf8d5d62ef7dcb9de2a3bc8fca0fcccc105 1 parent 55ea08b
Vilya Harvey authored October 14, 2010

Showing 1 changed file with 41 additions and 16 deletions. Show diff stats Hide diff stats

  1. 57  example/picking.cpp
57  example/picking.cpp
... ...
@@ -1,5 +1,7 @@
1 1
 #include "vgl.h"
2 2
 #include <cstring> // for memcpy
  3
+#include <vector>
  4
+
3 5
 
4 6
 //
5 7
 // Constants
@@ -53,7 +55,7 @@ class PickingRenderer : public vgl::Renderer
53 55
   GLuint _pbo;        // Pixel buffer for reading the pick data back into CPU memory.
54 56
 
55 57
   unsigned int _mode; // The user-selected drawing mode.
56  
-  BufType* _pickData; // The local copy of the pick data.
  58
+  std::vector<BufType> _pickData; // The local copy of the pick data.
57 59
 };
58 60
 
59 61
 
@@ -99,9 +101,8 @@ PickingRenderer::PickingRenderer() :
99 101
   _pickDepth(0),
100 102
   _pbo(0),
101 103
   _mode(0),
102  
-  _pickData(NULL)
  104
+  _pickData()
103 105
 {
104  
-  _pickData = new BufType[3 * kBufferWidth * kBufferHeight];
105 106
 }
106 107
 
107 108
 
@@ -115,24 +116,27 @@ PickingRenderer::~PickingRenderer()
115 116
     glDeleteRenderbuffers(1, &_pickDepth);
116 117
   if (_pbo)
117 118
     glDeleteBuffers(1, &_pbo);
118  
-
119  
-  delete[] _pickData;
120 119
 }
121 120
 
122 121
 
123 122
 void PickingRenderer::setup()
124 123
 {
125 124
   glEnable(GL_DEPTH_TEST);
  125
+
  126
+  GLint vp[4];
  127
+  glGetIntegerv(GL_VIEWPORT, vp);
  128
+  unsigned int width = vp[2];
  129
+  unsigned int height = vp[3];
126 130
  
127 131
   // Set up the pick buffer.
128 132
   glGenRenderbuffers(1, &_pickBuffer);
129 133
   glBindRenderbuffer(GL_RENDERBUFFER, _pickBuffer);
130  
-  glRenderbufferStorage(GL_RENDERBUFFER, kBufInternalFormat, kBufferWidth, kBufferHeight);
  134
+  glRenderbufferStorage(GL_RENDERBUFFER, kBufInternalFormat, width, height);
131 135
 
132 136
   // Set up the depth buffer.
133 137
   glGenRenderbuffers(1, &_pickDepth);
134 138
   glBindRenderbuffer(GL_RENDERBUFFER, _pickDepth);
135  
-  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, kBufferWidth, kBufferHeight);
  139
+  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
136 140
 
137 141
   // Set up the FBO.
138 142
   glGenFramebuffers(1, &_fbo);
@@ -143,7 +147,7 @@ void PickingRenderer::setup()
143 147
   // Set up the PBO for reading back the pick data from the FBO.
144 148
   glGenBuffers(1, &_pbo);
145 149
   glBindBuffer(GL_PIXEL_PACK_BUFFER, _pbo);
146  
-  glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(BufType) * 3 * kBufferWidth * kBufferWidth, NULL, GL_DYNAMIC_READ);
  150
+  glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(BufType) * 3 * width * height, NULL, GL_DYNAMIC_READ);
147 151
 
148 152
   // Check that everything is OK.
149 153
   GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -156,13 +160,31 @@ void PickingRenderer::setup()
156 160
 
157 161
 void PickingRenderer::render()
158 162
 {
  163
+  GLint vp[4];
  164
+  glGetIntegerv(GL_VIEWPORT, vp);
  165
+  unsigned int width = vp[2];
  166
+  unsigned int height = vp[3];
  167
+
  168
+  fprintf(stderr, "width = %u, height = %u\n", width, height);
  169
+
  170
+  unsigned int newBufSize = width * height * 3;
  171
+  if (newBufSize != _pickData.size()) {
  172
+    _pickData.resize(newBufSize);
  173
+    glBindRenderbuffer(GL_RENDERBUFFER, _pickBuffer);
  174
+    glRenderbufferStorage(GL_RENDERBUFFER, kBufInternalFormat, width, height);
  175
+    glBindRenderbuffer(GL_RENDERBUFFER, _pickDepth);
  176
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
  177
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, _pbo);
  178
+    glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(BufType) * 3 * width * height, NULL, GL_DYNAMIC_READ);
  179
+  }
  180
+
159 181
   // Render the selectable data
160 182
   glBindFramebuffer(GL_FRAMEBUFFER, _pickBuffer);
161 183
   renderPickImage();
162 184
 
163 185
   // Start reading the selectable data back asynchronously
164 186
   glBindBuffer(GL_PIXEL_PACK_BUFFER, _pbo);
165  
-  glReadPixels(0, 0, kBufferWidth, kBufferHeight, kBufFormat, kBufType, (void*)0);
  187
+  glReadPixels(0, 0, width, height, kBufFormat, kBufType, (void*)0);
166 188
 
167 189
   // Render the visual data
168 190
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -174,17 +196,22 @@ void PickingRenderer::render()
174 196
   // Map the selectable data so we can use it.
175 197
   float* buf = (float*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
176 198
   if (buf) {
177  
-    memcpy(_pickData, buf, sizeof(BufType) * 3 * kBufferWidth * kBufferHeight);
  199
+    memcpy(_pickData.data(), buf, sizeof(BufType) * 3 * width * height);
178 200
     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
179 201
   }
180 202
   glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
181 203
 }
182 204
 
183 205
 
184  
-bool PickingRenderer::objectAt(unsigned int sx, unsigned int sy, unsigned int& type, unsigned int& id)
  206
+bool PickingRenderer::objectAt(unsigned int x, unsigned int y, unsigned int& type, unsigned int& id)
185 207
 {
186  
-  sy = kBufferHeight + 1 - sy;
187  
-  unsigned int index = (sy * kBufferWidth + sx) * 3;
  208
+  GLint vp[4];
  209
+  glGetIntegerv(GL_VIEWPORT, vp);
  210
+  unsigned int width = vp[2];
  211
+  unsigned int height = vp[3];
  212
+
  213
+  y = height + 1 - y;
  214
+  unsigned int index = (y * width + x) * 3;
188 215
 
189 216
   if (_pickData[index] == 0)
190 217
     return false;
@@ -400,9 +427,7 @@ int PickingViewer::actionForMousePress(int button, int state, int x, int y)
400 427
     unsigned int type = 0;
401 428
     unsigned int id = 0;
402 429
     if (x >= 0 && x < _width && y >= 0 && y < _height) {
403  
-      unsigned int sx = (unsigned int)x * kBufferWidth / _width;
404  
-      unsigned int sy = (unsigned int)y * kBufferHeight / _height;
405  
-      if (picker->objectAt(sx, sy, type, id)) {
  430
+      if (picker->objectAt(x, y, type, id)) {
406 431
         switch (type) {
407 432
           case 1: _selectedFace = id;   return ACTION_PICK_FACE;
408 433
           case 2: _selectedEdge = id;   return ACTION_PICK_EDGE;

0 notes on commit fbb6adf

Please sign in to comment.
Something went wrong with that request. Please try again.