1 | #include <stdio.h> |
---|
2 | #include <stdlib.h> |
---|
3 | |
---|
4 | #include "../include/GL/glew.h" |
---|
5 | #ifdef _WIN32 |
---|
6 | #include "../include/GL/wglew.h" |
---|
7 | #endif |
---|
8 | #include "../include/global.h" |
---|
9 | #include "../include/histogram.h" |
---|
10 | #include "../include/metrics.h" |
---|
11 | |
---|
12 | #define WIN_MARGIN 2 |
---|
13 | |
---|
14 | using namespace VMI; |
---|
15 | |
---|
16 | void VMI::printHistogram(int histoGram[][4]) { |
---|
17 | int i; |
---|
18 | |
---|
19 | printf("\n"); |
---|
20 | for (i=0; i<HISTOGRAM_SIZE; i++) { |
---|
21 | printf("H: %d RGBA(%d, %d, %d, %d)\n",i, histoGram[i][0], histoGram[i][1], histoGram[i][2], histoGram[i][3]); |
---|
22 | } |
---|
23 | } |
---|
24 | |
---|
25 | void VMI::plotHistogram(int histoGram[][4]) { |
---|
26 | int i; |
---|
27 | int iLargest = 0; // Largest histogram value |
---|
28 | GLfloat maxHeight = height / 2.0f; |
---|
29 | |
---|
30 | setOrthographicProjection(); |
---|
31 | |
---|
32 | // Find largest value for scaling graph down |
---|
33 | for (i=0; i<HISTOGRAM_SIZE; i++) { |
---|
34 | if(iLargest < histoGram[i][0]) |
---|
35 | iLargest = histoGram[i][0]; |
---|
36 | if(iLargest < histoGram[i][1]) |
---|
37 | iLargest = histoGram[i][1]; |
---|
38 | if(iLargest < histoGram[i][2]) |
---|
39 | iLargest = histoGram[i][2]; |
---|
40 | if(iLargest < histoGram[i][3]) |
---|
41 | iLargest = histoGram[i][3]; |
---|
42 | } |
---|
43 | printf("%d\n", iLargest); |
---|
44 | glBegin(GL_LINE_STRIP); |
---|
45 | glColor3f(1.0f, 0.0f, 0.0f); |
---|
46 | for (i=0; i < HISTOGRAM_SIZE; i++) |
---|
47 | //glVertex2s(i, histoGram[i][0]); |
---|
48 | glVertex2f((GLfloat)i, ((GLfloat)histoGram[i][0] / maxHeight) * maxHeight); |
---|
49 | glEnd(); |
---|
50 | |
---|
51 | glBegin(GL_LINE_STRIP); |
---|
52 | glColor3f(0.0f, 1.0f, 0.0f); |
---|
53 | for (i=0; i < HISTOGRAM_SIZE; i++) |
---|
54 | //glVertex2s(i, histoGram[i][1]); |
---|
55 | glVertex2f((GLfloat)i, ((GLfloat)histoGram[i][0] / maxHeight) * maxHeight); |
---|
56 | glEnd(); |
---|
57 | |
---|
58 | glBegin(GL_LINE_STRIP); |
---|
59 | glColor3f(0.0f, 0.0f, 1.0f); |
---|
60 | for (i=0; i < HISTOGRAM_SIZE; i++) |
---|
61 | //glVertex2s(i, histoGram[i][2]); |
---|
62 | glVertex2f((GLfloat)i, ((GLfloat)histoGram[i][0] / maxHeight) * maxHeight); |
---|
63 | glEnd(); |
---|
64 | glBegin(GL_LINE_STRIP); |
---|
65 | glColor3f(0.5f, 0.5f, 0.5f); // Grey color represents the alpha channel |
---|
66 | for (i=0; i < HISTOGRAM_SIZE; i++) |
---|
67 | //glVertex2s(i, histoGram[i][3]); |
---|
68 | glVertex2f((GLfloat)i, ((GLfloat)histoGram[i][0] / maxHeight) * maxHeight); |
---|
69 | glEnd(); |
---|
70 | |
---|
71 | resetPerspectiveProjection(); |
---|
72 | } |
---|
73 | |
---|
74 | int **VMI::initHistogram(int numTriangles, int numCameras) { |
---|
75 | int i; |
---|
76 | int **histogram; |
---|
77 | |
---|
78 | histogram = (int **)malloc(sizeof(int *) * numCameras); |
---|
79 | |
---|
80 | if (histogram == NULL) { |
---|
81 | fprintf(stderr, "Error allocating memory\n"); |
---|
82 | exit(1); |
---|
83 | } |
---|
84 | |
---|
85 | for (i=0; i<numCameras; i++) |
---|
86 | histogram[i] = (int *)malloc(sizeof(int) * (numTriangles + 1)); // + 1 because the last is the numPixels of the background |
---|
87 | |
---|
88 | // Fill the histogram buffer with 0 |
---|
89 | for (i=0; i<numCameras; i++) |
---|
90 | memset(histogram[i], 0, sizeof(int) * (numTriangles + 1)); |
---|
91 | |
---|
92 | return histogram; |
---|
93 | } |
---|
94 | |
---|
95 | void VMI::deleteHistogram(int **histogram, int numCameras) { |
---|
96 | int i; |
---|
97 | |
---|
98 | for (i=0;i<numCameras;i++) |
---|
99 | if (histogram[i] != NULL) free(histogram[i]); |
---|
100 | |
---|
101 | free(histogram); |
---|
102 | } |
---|
103 | |
---|
104 | void VMI::printFullHistogram(int **histogram, int numCameras, int numTriangles) { |
---|
105 | int i, j; |
---|
106 | |
---|
107 | printf("\n"); |
---|
108 | for (i=0; i<numCameras; i++) { |
---|
109 | printf("c%d [t%d(%d) ", i, 0, histogram[i][0]); |
---|
110 | for (j=1; j<=numTriangles; j++) { |
---|
111 | printf(",t%d(%d) ", j, histogram[i][j]); |
---|
112 | } |
---|
113 | printf("]\n"); |
---|
114 | } |
---|
115 | printf("Total image area: %d\n", width * height); |
---|
116 | } |
---|
117 | |
---|
118 | void VMI::getSubHistogram(int subHistoGram[][4]) { |
---|
119 | //printf("Computing histogram...\n"); |
---|
120 | // Define the histogram |
---|
121 | |
---|
122 | glEnable(GL_HISTOGRAM); |
---|
123 | //glEnable(GL_TEXTURE_2D); |
---|
124 | glHistogram(GL_HISTOGRAM, HISTOGRAM_SIZE, GL_RGBA, GL_TRUE); |
---|
125 | |
---|
126 | // Perform a pixel operation |
---|
127 | glCopyPixels(0, 0, width, height, GL_COLOR); |
---|
128 | |
---|
129 | // Get the histogram |
---|
130 | glGetHistogram(GL_HISTOGRAM, GL_FALSE, GL_RGBA, GL_UNSIGNED_INT, subHistoGram); |
---|
131 | glResetHistogram(GL_HISTOGRAM); |
---|
132 | glDisable(GL_HISTOGRAM); |
---|
133 | //glDisable(GL_TEXTURE_2D); |
---|
134 | |
---|
135 | //printHistogram(subHistoGram); |
---|
136 | //plotHistogram(subHistoGram); |
---|
137 | } |
---|
138 | |
---|
139 | void VMI::copySubHistogram(Color *colors, int *histogram, int begin, int end, int subHistoGram[][4]) { |
---|
140 | int i; |
---|
141 | GLubyte r, g, b, a; |
---|
142 | int h = 0; |
---|
143 | |
---|
144 | for (i=begin; i<end; i++) { |
---|
145 | |
---|
146 | r = colors[i].r; |
---|
147 | g = colors[i].g; |
---|
148 | b = colors[i].b; |
---|
149 | a = colors[i].a; |
---|
150 | |
---|
151 | if (r != 0) |
---|
152 | h = subHistoGram[r][0]; |
---|
153 | |
---|
154 | if (g != 0) |
---|
155 | h = subHistoGram[g][1]; |
---|
156 | |
---|
157 | if (b != 0) |
---|
158 | h = subHistoGram[b][2]; |
---|
159 | |
---|
160 | if (a != 0) |
---|
161 | h = subHistoGram[a][3]; |
---|
162 | |
---|
163 | histogram[i] = h; |
---|
164 | } |
---|
165 | } |
---|
166 | |
---|
167 | void VMI::getSWHistogram(int *histogram, GLubyte *pixels) { |
---|
168 | GLubyte r, g, b, a; |
---|
169 | int i, t, p, numPixels = width * height; |
---|
170 | |
---|
171 | glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
---|
172 | |
---|
173 | for (i=0; i<numPixels; i++) { // pixel i |
---|
174 | p = i << 2; // 4 * i |
---|
175 | r = pixels[p]; |
---|
176 | g = pixels[p + 1]; |
---|
177 | b = pixels[p + 2]; |
---|
178 | a = pixels[p + 3]; |
---|
179 | |
---|
180 | t = r + (g << 8) + (b << 16) + (a << 24); // triangle color |
---|
181 | |
---|
182 | //printf("pixel:%d (%d,%d,%d,%d) t %d\n", i, r, g, b, a, t); |
---|
183 | |
---|
184 | histogram[t]++; |
---|
185 | } |
---|
186 | //getchar(); |
---|
187 | } |
---|
188 | |
---|
189 | void VMI::getBoundingBox(Change *c, GLfloat min[3], GLfloat max[3]) { |
---|
190 | int i, j, t, v; |
---|
191 | GLfloat maxx = 0.0f, minx = 0.0f, |
---|
192 | maxy = 0.0f, miny = 0.0f, |
---|
193 | maxz = 0.0f, minz = 0.0f; |
---|
194 | |
---|
195 | /* get the max/mins */ |
---|
196 | for (i=0; i<c->numMod; i++) { |
---|
197 | t = c->modified[i].id; |
---|
198 | |
---|
199 | for (j=0; j<3; j++) { |
---|
200 | v = mesh->triangles[t].indices[j]; |
---|
201 | // v |
---|
202 | if (maxx < mesh->vertices[v].x) |
---|
203 | maxx = mesh->vertices[v].x; |
---|
204 | if (minx > mesh->vertices[v].x) |
---|
205 | minx = mesh->vertices[v].x; |
---|
206 | |
---|
207 | if (maxy < mesh->vertices[v].y) |
---|
208 | maxy = mesh->vertices[v].y; |
---|
209 | if (miny > mesh->vertices[v].y) |
---|
210 | miny = mesh->vertices[v].y; |
---|
211 | |
---|
212 | if (maxz < mesh->vertices[v].z) |
---|
213 | maxz = mesh->vertices[v].z; |
---|
214 | if (minz > mesh->vertices[v].z) |
---|
215 | minz = mesh->vertices[v].z; |
---|
216 | } |
---|
217 | } |
---|
218 | |
---|
219 | for (i=0; i<c->numDel; i++) { |
---|
220 | t = c->deleted[i].id; |
---|
221 | |
---|
222 | for (j=0; j<3; j++) { |
---|
223 | v = mesh->triangles[t].indices[j]; |
---|
224 | // v |
---|
225 | if (maxx < mesh->vertices[v].x) |
---|
226 | maxx = mesh->vertices[v].x; |
---|
227 | if (minx > mesh->vertices[v].x) |
---|
228 | minx = mesh->vertices[v].x; |
---|
229 | |
---|
230 | if (maxy < mesh->vertices[v].y) |
---|
231 | maxy = mesh->vertices[v].y; |
---|
232 | if (miny > mesh->vertices[v].y) |
---|
233 | miny = mesh->vertices[v].y; |
---|
234 | |
---|
235 | if (maxz < mesh->vertices[v].z) |
---|
236 | maxz = mesh->vertices[v].z; |
---|
237 | if (minz > mesh->vertices[v].z) |
---|
238 | minz = mesh->vertices[v].z; |
---|
239 | } |
---|
240 | } |
---|
241 | |
---|
242 | min[0] = minx; |
---|
243 | min[1] = miny; |
---|
244 | min[2] = minz; |
---|
245 | |
---|
246 | max[0] = maxx; |
---|
247 | max[1] = maxy; |
---|
248 | max[2] = maxz; |
---|
249 | } |
---|
250 | |
---|
251 | void VMI::getWindow(GLfloat min[3], GLfloat max[3], int minw[2], int maxw[2]) { |
---|
252 | GLdouble winx, winy, winz, |
---|
253 | mv[16], pm[16]; |
---|
254 | GLint vp[4], minx, miny, maxx, maxy; |
---|
255 | |
---|
256 | glGetDoublev(GL_MODELVIEW_MATRIX, mv); |
---|
257 | glGetDoublev(GL_PROJECTION_MATRIX, pm); |
---|
258 | glGetIntegerv(GL_VIEWPORT, vp); |
---|
259 | |
---|
260 | /* The eight points of the bounding box */ |
---|
261 | /* Point 1 (min,min,min) */ |
---|
262 | gluProject((GLdouble)min[0], (GLdouble)min[1], (GLdouble)min[2], mv, pm, vp, &winx, &winy, &winz); |
---|
263 | minx = winx; |
---|
264 | maxx = winx; |
---|
265 | miny = winy; |
---|
266 | maxy = winy; |
---|
267 | |
---|
268 | /* Point 2 (max,min,min) */ |
---|
269 | gluProject((GLdouble)max[0], (GLdouble)min[1], (GLdouble)min[2], mv, pm, vp, &winx, &winy, &winz); |
---|
270 | if (winx < minx) minx =winx; |
---|
271 | if (winx > maxx) maxx =winx; |
---|
272 | if (winy < miny) miny =winy; |
---|
273 | if (winy > maxy) maxy =winy; |
---|
274 | |
---|
275 | /* Point 3 (min,max,min) */ |
---|
276 | gluProject((GLdouble)min[0], (GLdouble)max[1], (GLdouble)min[2], mv, pm, vp, &winx, &winy, &winz); |
---|
277 | if (winx < minx) minx =winx; |
---|
278 | if (winx > maxx) maxx =winx; |
---|
279 | if (winy < miny) miny =winy; |
---|
280 | if (winy > maxy) maxy =winy; |
---|
281 | |
---|
282 | /* Point 4 (max,max,min) */ |
---|
283 | gluProject((GLdouble)max[0], (GLdouble)max[1], (GLdouble)min[2], mv, pm, vp, &winx, &winy, &winz); |
---|
284 | if (winx < minx) minx =winx; |
---|
285 | if (winx > maxx) maxx =winx; |
---|
286 | if (winy < miny) miny =winy; |
---|
287 | if (winy > maxy) maxy =winy; |
---|
288 | |
---|
289 | /* Point 5 (min,min,max) */ |
---|
290 | gluProject((GLdouble)min[0], (GLdouble)min[1], (GLdouble)max[2], mv, pm, vp, &winx, &winy, &winz); |
---|
291 | if (winx < minx) minx =winx; |
---|
292 | if (winx > maxx) maxx =winx; |
---|
293 | if (winy < miny) miny =winy; |
---|
294 | if (winy > maxy) maxy =winy; |
---|
295 | |
---|
296 | /* Point 6 (max,min,max) */ |
---|
297 | gluProject((GLdouble)max[0], (GLdouble)min[1], (GLdouble)max[2], mv, pm, vp, &winx, &winy, &winz); |
---|
298 | if (winx < minx) minx =winx; |
---|
299 | if (winx > maxx) maxx =winx; |
---|
300 | if (winy < miny) miny =winy; |
---|
301 | if (winy > maxy) maxy =winy; |
---|
302 | |
---|
303 | /* Point 7 (min,max,max) */ |
---|
304 | gluProject((GLdouble)min[0], (GLdouble)max[1], (GLdouble)max[2], mv, pm, vp, &winx, &winy, &winz); |
---|
305 | if (winx < minx) minx =winx; |
---|
306 | if (winx > maxx) maxx =winx; |
---|
307 | if (winy < miny) miny =winy; |
---|
308 | if (winy > maxy) maxy =winy; |
---|
309 | |
---|
310 | /* Point 8 (max,max,max) */ |
---|
311 | gluProject((GLdouble)max[0], (GLdouble)max[1], (GLdouble)max[2], mv, pm, vp, &winx, &winy, &winz); |
---|
312 | if (winx < minx) minx =winx; |
---|
313 | if (winx > maxx) maxx =winx; |
---|
314 | if (winy < miny) miny =winy; |
---|
315 | if (winy > maxy) maxy =winy; |
---|
316 | |
---|
317 | minw[0] = minx; |
---|
318 | minw[1] = miny; |
---|
319 | |
---|
320 | maxw[0] = maxx; |
---|
321 | maxw[1] = maxy; |
---|
322 | } |
---|
323 | |
---|
324 | void VMI::getSWHistogramWin(int *histogram, GLubyte *pixels, GLfloat min[3], GLfloat max[3], Change *c) { |
---|
325 | GLubyte r, g, b, a; |
---|
326 | int i, t, p, numPixels, |
---|
327 | *histoAux = (int *)calloc(mesh->numTriangles + 1, sizeof(int)); |
---|
328 | GLint minw[2], maxw[2], ox, oy, h, w; |
---|
329 | |
---|
330 | getWindow(min, max, minw, maxw); |
---|
331 | |
---|
332 | w = ABS(maxw[0] - minw[0]); |
---|
333 | h = ABS(maxw[1] - minw[1]); |
---|
334 | //printf("w:%d h:%d\n", w, h); |
---|
335 | |
---|
336 | ox = minw[0]; |
---|
337 | oy = minw[1]; |
---|
338 | |
---|
339 | ox -= WIN_MARGIN; |
---|
340 | if (ox < 0) ox = 0; |
---|
341 | oy -= WIN_MARGIN; |
---|
342 | if (oy < 0) oy = 0; |
---|
343 | |
---|
344 | w += (WIN_MARGIN * 2); |
---|
345 | if (w > width) w = width; |
---|
346 | h += (WIN_MARGIN * 2); |
---|
347 | if (h > height) h = height; |
---|
348 | |
---|
349 | //printf("(%d,%d)\n", ox, oy); |
---|
350 | //printf("w:%d h:%d\n", w, h); |
---|
351 | //getchar(); |
---|
352 | |
---|
353 | numPixels = w * h; |
---|
354 | //printf("NumPixels: %d\n", numPixels); |
---|
355 | |
---|
356 | glReadPixels(ox, oy, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
---|
357 | |
---|
358 | for (i=0; i<numPixels; i++) { // pixel i |
---|
359 | p = i << 2; // 4 * i |
---|
360 | r = pixels[p]; |
---|
361 | g = pixels[p + 1]; |
---|
362 | b = pixels[p + 2]; |
---|
363 | a = pixels[p + 3]; |
---|
364 | |
---|
365 | t = r + (g << 8) + (b << 16) + (a << 24); // triangle color |
---|
366 | //printf("pixel:%d (%d,%d,%d,%d) t %d\n", i, r, g, b, a, t); |
---|
367 | |
---|
368 | histoAux[t]++; |
---|
369 | } |
---|
370 | |
---|
371 | for (i=0; i<c->numMod; i++) { |
---|
372 | t = c->modified[i].id; |
---|
373 | |
---|
374 | histogram[t + 1] = histoAux[t + 1]; |
---|
375 | } |
---|
376 | |
---|
377 | free(histoAux); |
---|
378 | //getchar(); |
---|
379 | } |
---|
380 | |
---|
381 | void VMI::getSWHistoByOcclusionQuery(Mesh *mesh, Color *colors, int *histogram) { |
---|
382 | int i, v1, v2, v3; |
---|
383 | GLint area, totalArea = 0; |
---|
384 | |
---|
385 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
---|
386 | glDepthMask(GL_FALSE); |
---|
387 | |
---|
388 | for (i=0; i<mesh->numTriangles; i++) { // For every triangle |
---|
389 | if (mesh->triangles[i].enable == TRUE) { |
---|
390 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, queries[i]); |
---|
391 | |
---|
392 | /* Render triangle i */ |
---|
393 | glBegin(GL_TRIANGLES); |
---|
394 | v1= mesh->triangles[i].indices[0]; |
---|
395 | v2= mesh->triangles[i].indices[1]; |
---|
396 | v3= mesh->triangles[i].indices[2]; |
---|
397 | |
---|
398 | glColor4ub(colors[i].r, colors[i].g, colors[i].b, colors[i].a); |
---|
399 | |
---|
400 | glVertex3f(mesh->vertices[v1].x, mesh->vertices[v1].y, mesh->vertices[v1].z); |
---|
401 | glVertex3f(mesh->vertices[v2].x, mesh->vertices[v2].y, mesh->vertices[v2].z); |
---|
402 | glVertex3f(mesh->vertices[v3].x, mesh->vertices[v3].y, mesh->vertices[v3].z); |
---|
403 | glEnd(); |
---|
404 | |
---|
405 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); |
---|
406 | } |
---|
407 | } |
---|
408 | glFlush(); |
---|
409 | |
---|
410 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
---|
411 | glDepthMask(GL_TRUE); |
---|
412 | |
---|
413 | for (i=0; i<mesh->numTriangles; i++) { // For every triangle |
---|
414 | if (mesh->triangles[i].enable == TRUE) { |
---|
415 | glGetQueryObjectivARB(queries[i], GL_QUERY_RESULT_ARB, &area); |
---|
416 | |
---|
417 | if (area < 0) { |
---|
418 | printf(" t:%d a:%d\n", i, histogram[i + 1]); |
---|
419 | histogram[i + 1] = 0; |
---|
420 | } else { |
---|
421 | histogram[i + 1] = area; |
---|
422 | |
---|
423 | totalArea += area; |
---|
424 | } |
---|
425 | } |
---|
426 | } |
---|
427 | |
---|
428 | /* Compute the background area */ |
---|
429 | histogram[0] = (width * height) - totalArea; |
---|
430 | |
---|
431 | //printf("background area: %d\n", histogram[0]); |
---|
432 | } |
---|
433 | |
---|
434 | void VMI::resetSWHistogram(int *histogram, int numTriangles) { |
---|
435 | |
---|
436 | // Fill the histogram buffer with 0 |
---|
437 | memset(histogram, 0, sizeof(int) * (numTriangles + 1)); |
---|
438 | } |
---|