1 | /*
|
---|
2 | * ----------------------------------------------------------------------
|
---|
3 | * Render to vertex array
|
---|
4 | *
|
---|
5 | * This class implements "render to vertex array" functionality
|
---|
6 | * using vertex and pixel buffer objects (VBO and PBO).
|
---|
7 | *
|
---|
8 | * Operation:
|
---|
9 | * 1. A buffer object is created
|
---|
10 | * 2. The buffer object is bound to the pixel pack (destination) buffer
|
---|
11 | * 3. glReadPixels is used to read from the frame buffer to the buffer object
|
---|
12 | * 4. The buffer object is bound to the vertex array
|
---|
13 | * 5. Vertex array pointers are set
|
---|
14 | *
|
---|
15 | * Usage:
|
---|
16 | * 1. Create a floating point pbuffer
|
---|
17 | * 2. Create a RenderVertexArray object for each vertex attribute
|
---|
18 | * you want to render to
|
---|
19 | * 3. Render vertex data to pbuffer using a fragment program (could
|
---|
20 | * use multiple draw buffers here)
|
---|
21 | * 4. Call Read() method to read data from pbuffer to vertex array
|
---|
22 | * 5. Call SetPointer() method to set vertex array pointers
|
---|
23 | * 6. Set any other other static vertex array attribute pointers
|
---|
24 | * 7. Render geometry as usual using glDrawArrays or glDrawElements
|
---|
25 | *
|
---|
26 | * ======================================================================
|
---|
27 | * AUTHOR: Wei Qiao <qiaow@purdue.edu>
|
---|
28 | * Purdue Rendering and Perceptualization Lab (PURPL)
|
---|
29 | *
|
---|
30 | * Copyright (c) 2004-2006 Purdue Research Foundation
|
---|
31 | *
|
---|
32 | * See the file "license.terms" for information on usage and
|
---|
33 | * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
---|
34 | * ======================================================================
|
---|
35 | */
|
---|
36 | #include "RenderVertexArray.h"
|
---|
37 | #include <GL/glut.h>
|
---|
38 | #include <stdio.h>
|
---|
39 |
|
---|
40 | using namespace std;
|
---|
41 |
|
---|
42 | RenderVertexArray::RenderVertexArray(int nverts, GLint size, GLenum type) :
|
---|
43 | m_nverts(nverts), m_size(size), m_usage(GL_STREAM_COPY), m_type(type)
|
---|
44 | {
|
---|
45 | switch(m_type) {
|
---|
46 | case GL_HALF_FLOAT_NV:
|
---|
47 | m_bytes_per_component = 2; break;
|
---|
48 | case GL_FLOAT:
|
---|
49 | m_bytes_per_component = sizeof(float); break;
|
---|
50 | default:
|
---|
51 | fprintf(stderr, "Error: unsupported RenderVertexArray type\n");
|
---|
52 | return;
|
---|
53 | }
|
---|
54 |
|
---|
55 | // create the buffer object
|
---|
56 | glGenBuffersARB(1, &m_buffer);
|
---|
57 | glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, m_buffer);
|
---|
58 | glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, m_nverts*m_size*m_bytes_per_component, 0, m_usage); // undefined data
|
---|
59 | glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
|
---|
60 |
|
---|
61 | // set equivalent image format
|
---|
62 | switch(m_size) {
|
---|
63 | case 1:
|
---|
64 | m_format = GL_LUMINANCE; break;
|
---|
65 | case 3:
|
---|
66 | m_format = GL_RGB; break;
|
---|
67 | case 4:
|
---|
68 | m_format = GL_RGBA; break;
|
---|
69 | default:
|
---|
70 | fprintf(stderr, "Error: unsupported RenderVertexArray size\n");
|
---|
71 | return;
|
---|
72 | }
|
---|
73 | }
|
---|
74 |
|
---|
75 | RenderVertexArray::~RenderVertexArray()
|
---|
76 | {
|
---|
77 | glDeleteBuffersARB(1, &m_buffer);
|
---|
78 | }
|
---|
79 |
|
---|
80 | void
|
---|
81 | RenderVertexArray::LoadData(void *data)
|
---|
82 | {
|
---|
83 | // load data to buffer object
|
---|
84 | glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, m_buffer);
|
---|
85 | glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, m_nverts*m_size*m_bytes_per_component, data, m_usage);
|
---|
86 | }
|
---|
87 |
|
---|
88 | void
|
---|
89 | RenderVertexArray::Read(/*GLenum buffer,*/ int w, int h)
|
---|
90 | {
|
---|
91 | // bind buffer object to pixel pack buffer
|
---|
92 | glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, m_buffer);
|
---|
93 | // read from frame buffer to buffer object
|
---|
94 | //glReadBuffer(buffer); //crash
|
---|
95 | glReadPixels(0, 0, w, h, m_format, m_type, 0);
|
---|
96 |
|
---|
97 | glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
|
---|
98 | }
|
---|
99 |
|
---|
100 | void
|
---|
101 | RenderVertexArray::SetPointer(GLuint index)
|
---|
102 | {
|
---|
103 | // bind buffer object to vertex array
|
---|
104 | glBindBufferARB(GL_ARRAY_BUFFER, m_buffer);
|
---|
105 | //glVertexAttribPointerARB(index, m_size, m_type, GL_FALSE, 0, 0); //doesn't work
|
---|
106 | glVertexPointer(m_size, m_type, GL_FALSE, 0);
|
---|
107 |
|
---|
108 | glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
---|
109 | }
|
---|