cgv
Loading...
Searching...
No Matches
gl_vr_display.cxx
1#include "gl_vr_display.h"
2
3#include <GL/glew.h>
4
5namespace vr {
6
8gl_vr_display::gl_vr_display(unsigned _width, unsigned _height, unsigned _nr_multi_samples)
9 : width(_width), height(_height), nr_multi_samples(_nr_multi_samples)
10{
11 for (unsigned i = 0; i < 2; ++i) {
13 multi_tex_id[i] = 0;
14 multi_fbo_id[i] = 0;
15 tex_id[i] = 0;
16 fbo_id[i] = 0;
17 }
18}
19
24
26const std::string& gl_vr_display::get_last_error() const
27{
28 return last_error;
29}
30
32void gl_vr_display::set_size(int new_width, int new_height)
33{
34 width = new_width;
35 height = new_height;
36}
37
40{
41 return width;
42}
45{
46 return height;
47}
48
51{
52 switch (es) {
53 case ES_BOTH :
54 return fbo_id[0] != 0 && fbo_id[1] != 0 && multi_fbo_id[0] != 0 && multi_fbo_id[1] != 0;
55 case ES_LEFT:
56 return fbo_id[0] != 0 && multi_fbo_id[0];
57 case ES_RIGHT:
58 return fbo_id[1] != 0 && multi_fbo_id[1] != 0;
59 }
60 return false;
61}
62
65{
66 for (unsigned i = 0; i < 2; ++i) {
67 if (es == ES_LEFT && i == 1)
68 continue;
69 if (es == ES_RIGHT && i == 0)
70 continue;
71 if (multi_depth_buffer_id[i] != 0) {
72 glDeleteRenderbuffers(1, &multi_depth_buffer_id[i]);
74 }
75 if (multi_tex_id[i] != 0) {
76 glDeleteTextures(1, &multi_tex_id[i]);
77 multi_tex_id[i] = 0;
78 }
79 if (multi_fbo_id[i] != 0) {
80 glDeleteFramebuffers(1, &multi_fbo_id[i]);
81 multi_fbo_id[i] = 0;
82 }
83 if (tex_id[i] != 0) {
84 glDeleteTextures(1, &tex_id[i]);
85 tex_id[i] = 0;
86 }
87 if (fbo_id[i] != 0) {
88 glDeleteFramebuffers(1, &fbo_id[i]);
89 fbo_id[i] = 0;
90 }
91 }
92}
93
96{
97 for (unsigned i = 0; i < 2; ++i) {
98 if (es == ES_LEFT && i == 1)
99 continue;
100 if (es == ES_RIGHT && i == 0)
101 continue;
102
103 glGenFramebuffers(1, &multi_fbo_id[i]);
104 glBindFramebuffer(GL_FRAMEBUFFER, multi_fbo_id[i]);
105
106 glGenRenderbuffers(1, &multi_depth_buffer_id[i]);
107 glBindRenderbuffer(GL_RENDERBUFFER, multi_depth_buffer_id[i]);
108 glRenderbufferStorageMultisample(GL_RENDERBUFFER, nr_multi_samples, GL_DEPTH_COMPONENT, width, height);
109 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, multi_depth_buffer_id[i]);
110
111 glGenTextures(1, &multi_tex_id[i]);
112 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, multi_tex_id[i]);
113 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, nr_multi_samples, GL_RGBA8, width, height, true);
114 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, multi_tex_id[i], 0);
115
116 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
118 glBindFramebuffer(GL_FRAMEBUFFER, 0);
119 last_error = "check status of multi framebuffer failed";
120 return false;
121 }
122
123 glGenFramebuffers(1, &fbo_id[i]);
124 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id[i]);
125
126 glGenTextures(1, &tex_id[i]);
127 glBindTexture(GL_TEXTURE_2D, tex_id[i]);
128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
130 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
131 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id[i], 0);
132
133 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
135 glBindFramebuffer(GL_FRAMEBUFFER, 0);
136 last_error = "check status of framebuffer failed";
137 return false;
138 }
139 }
140 glBindFramebuffer(GL_FRAMEBUFFER, 0);
141 return true;
142}
145{
146 glBindTexture(GL_TEXTURE_2D, tex_id[eye]);
147}
148
151{
152 old_msaa = (int)glIsEnabled(GL_MULTISAMPLE);
153 if (old_msaa == GL_FALSE)
154 glEnable(GL_MULTISAMPLE);
155 // Left Eye
156 glBindFramebuffer(GL_FRAMEBUFFER, multi_fbo_id[eye]);
157 glGetIntegerv(GL_VIEWPORT, vp);
158 glViewport(0, 0, width, height);
159}
160
162bool gl_vr_display::blit_fbo(int eye, int x, int y, int w, int h)
163{
164 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_id[eye]);
165 glBlitFramebuffer(0, 0, width, height, x, y, x+w, y+h,
166 GL_COLOR_BUFFER_BIT, GL_NEAREST);
167 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
168 return true;
169}
170
173{
174 glViewport(vp[0], vp[1], vp[2], vp[3]);
175
176 glBindFramebuffer(GL_FRAMEBUFFER, 0);
177 glDisable(GL_MULTISAMPLE);
178
179 glBindFramebuffer(GL_READ_FRAMEBUFFER, multi_fbo_id[eye]);
180 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id[eye]);
181 glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
182 GL_COLOR_BUFFER_BIT, GL_LINEAR);
183 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
184 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
185
186 if (old_msaa == GL_TRUE)
187 glEnable(GL_MULTISAMPLE);
188}
189
190}
std::string last_error
store last error message
virtual bool blit_fbo(int eye, int x, int y, int w, int h)
initialize render targets and framebuffer objects in current opengl context
gl_vr_display(unsigned _width, unsigned _height, unsigned _nr_multi_samples)
construct
const std::string & get_last_error() const
return last error of vr_kit
virtual void disable_fbo(int eye)
disable the framebuffer object of given eye
int get_width() const
return width in pixel of view
virtual void bind_texture(int eye)
bind texture of given eye to current texture unit
virtual void enable_fbo(int eye)
enable the framebuffer object of given eye (0..left, 1..right)
int get_height() const
return height in pixel of view
unsigned width
pixel dimensions of render targets
virtual void set_size(int new_width, int new_height)
allow to set a different size
virtual ~gl_vr_display()
declare virtual destructor
virtual void destruct_fbos(EyeSelection es=ES_BOTH)
destruct render targets and framebuffer objects in current opengl context
virtual bool init_fbos(EyeSelection es=ES_BOTH)
initialize render targets and framebuffer objects in current opengl context
virtual bool fbos_initialized(EyeSelection es=ES_BOTH) const
check whether fbos have been initialized
unsigned multi_depth_buffer_id[2]
ids of gl render objects
the vr namespace for virtual reality support
EyeSelection
enum to support restriction of eyes to a single eye