]> git.cworth.org Git - vogl/blob - src/vogleditor/vogleditor_qframebufferexplorer.cpp
Initial vogl checkin
[vogl] / src / vogleditor / vogleditor_qframebufferexplorer.cpp
1 #include "vogleditor_qframebufferexplorer.h"
2 #include "ui_vogleditor_qframebufferexplorer.h"
3
4 #include "vogleditor_qtextureexplorer.h"
5
6 #include "vogl_gl_object.h"
7 #include "vogl_gl_state_snapshot.h"
8 #include "vogl_fbo_state.h"
9
10 typedef struct
11 {
12     int index;
13     vogl_framebuffer_state* pFBOState;
14     vogl_default_framebuffer_state* pDefaultFBState;
15 } vogl_framebuffer_container;
16
17 Q_DECLARE_METATYPE(vogl_framebuffer_container);
18
19 vogleditor_QFramebufferExplorer::vogleditor_QFramebufferExplorer(QWidget *parent) :
20     QWidget(parent),
21     ui(new Ui::vogleditor_QFramebufferExplorer),
22     m_pDefaultFramebufferState(NULL)
23 {
24     ui->setupUi(this);
25
26     m_colorExplorerLayout = new QVBoxLayout();
27     m_depthExplorerLayout = new QVBoxLayout();
28     m_stencilExplorerLayout = new QVBoxLayout();
29
30     ui->colorBufferGroupBox->setLayout(m_colorExplorerLayout);
31
32     m_depthExplorer = new vogleditor_QTextureExplorer(ui->depthBufferGroupBox);
33     m_depthExplorerLayout->addWidget(m_depthExplorer);
34     ui->depthBufferGroupBox->setLayout(m_depthExplorerLayout);
35
36     m_stencilExplorer = new vogleditor_QTextureExplorer(ui->stencilBufferGroupBox);
37     m_stencilExplorerLayout->addWidget(m_stencilExplorer);
38     ui->stencilBufferGroupBox->setLayout(m_stencilExplorerLayout);
39
40     connect(ui->framebufferObjectListbox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectedFramebufferIndexChanged(int)));
41 }
42
43 vogleditor_QFramebufferExplorer::~vogleditor_QFramebufferExplorer()
44 {
45     delete ui;
46
47     delete m_colorExplorerLayout;
48     delete m_depthExplorerLayout;
49     delete m_stencilExplorerLayout;
50
51     delete m_depthExplorer;
52     m_depthExplorer = NULL;
53
54     delete m_stencilExplorer;
55     m_stencilExplorer = NULL;
56 }
57
58 void vogleditor_QFramebufferExplorer::clear()
59 {
60     ui->framebufferObjectListbox->clear();
61
62     clearViewers();
63 }
64
65 void vogleditor_QFramebufferExplorer::clearViewers()
66 {
67     m_depthExplorer->clear();
68     m_stencilExplorer->clear();
69
70     for (vogleditor_QTextureExplorer** iter = m_viewers.begin(); iter != m_viewers.end(); iter++)
71     {
72         m_colorExplorerLayout->takeAt(0);
73         (*iter)->clear();
74         delete (*iter);
75         *iter = NULL;
76     }
77
78     m_viewers.clear();
79 }
80
81 void vogleditor_QFramebufferExplorer::set_framebuffer_objects(vogl_gl_object_state_ptr_vec objects, vogl_context_snapshot& context, vogl_default_framebuffer_state& defaultFramebufferState)
82 {
83     clear();
84
85     m_context = &context;
86     m_objects = objects;
87     m_pDefaultFramebufferState = &defaultFramebufferState;
88
89     // add default framebuffer
90     vogl_framebuffer_container defaultContainer;
91     defaultContainer.index = 0;
92     defaultContainer.pFBOState = NULL;
93     defaultContainer.pDefaultFBState = m_pDefaultFramebufferState;
94     ui->framebufferObjectListbox->addItem("Framebuffer 0 - (default framebuffer)", QVariant::fromValue(defaultContainer));
95
96     // add framebuffer objects
97     QString valueStr;
98     for (vogl_gl_object_state_ptr_vec::iterator iter = objects.begin(); iter != objects.end(); iter++)
99     {
100         vogl_framebuffer_state* pState = static_cast<vogl_framebuffer_state*>(*iter);
101
102         if (pState->get_attachments().size() > 0)
103         {
104             unsigned int width = 0;
105             unsigned int height = 0;
106             const vogl_framebuffer_attachment* pAttachment = &(pState->get_attachments().begin()->second);
107             if (pAttachment->get_type() == GL_TEXTURE)
108             {
109                 vogl_texture_state* pTexState = this->get_texture_attachment(NULL, pAttachment->get_handle());
110                 if (pTexState != NULL)
111                 {
112                     width = pTexState->get_texture().get_width();
113                     height = pTexState->get_texture().get_height();
114                 }
115             }
116             else if (pAttachment->get_type() == GL_RENDERBUFFER)
117             {
118                 vogl_renderbuffer_state* pRbState = this->get_renderbuffer_attachment(NULL, pAttachment->get_handle());
119                 if (pRbState != NULL)
120                 {
121                     width = pRbState->get_texture().get_texture().get_width();
122                     height = pRbState->get_texture().get_texture().get_height();
123                 }
124             }
125
126             valueStr = valueStr.sprintf("Framebuffer %" PRIu64 " - (%u x %u) %d attachments", pState->get_snapshot_handle(), width, height, pState->get_attachments().size());
127         }
128         else
129         {
130             valueStr = valueStr.sprintf("Framebuffer %" PRIu64 " - %d attachments", pState->get_snapshot_handle(), pState->get_attachments().size());
131         }
132
133         vogl_framebuffer_container defaultContainer;
134         defaultContainer.index = 0;
135         defaultContainer.pFBOState = pState;
136         defaultContainer.pDefaultFBState = NULL;
137
138         ui->framebufferObjectListbox->addItem(valueStr, QVariant::fromValue(defaultContainer));
139     }
140 }
141
142 bool vogleditor_QFramebufferExplorer::set_active_framebuffer(unsigned long long framebufferHandle)
143 {
144     bool bDisplayedFramebuffer = false;
145
146     if (framebufferHandle == 0)
147     {
148         ui->framebufferObjectListbox->setCurrentIndex(0);
149         bDisplayedFramebuffer = true;
150     }
151     else
152     {
153         int index = 1;
154         for (vogl_gl_object_state_ptr_vec::iterator iter = m_objects.begin(); iter != m_objects.end(); iter++)
155         {
156             vogl_framebuffer_state* pState = static_cast<vogl_framebuffer_state*>(*iter);
157             if (pState->get_snapshot_handle() == framebufferHandle)
158             {
159                 ui->framebufferObjectListbox->setCurrentIndex(index);
160                 bDisplayedFramebuffer = true;
161                 break;
162             }
163
164             ++index;
165         }
166     }
167     return bDisplayedFramebuffer;
168 }
169
170 void vogleditor_QFramebufferExplorer::selectedFramebufferIndexChanged(int index)
171 {
172     clearViewers();
173
174     if (index < 0 || index >= ui->framebufferObjectListbox->count())
175     {
176         return;
177     }
178
179     vogl_gl_object_state_ptr_vec colorVec;
180     vogl_gl_object_state_ptr_vec depthVec;
181     vogl_gl_object_state_ptr_vec stencilVec;
182
183 #define ADD_COLOR_BUFFER_VIEWER vogleditor_QTextureExplorer* pViewer = new vogleditor_QTextureExplorer(ui->colorBufferGroupBox); m_colorExplorerLayout->addWidget(pViewer); m_viewers.push_back(pViewer);
184
185     vogl_framebuffer_container container = ui->framebufferObjectListbox->itemData(index).value<vogl_framebuffer_container>();
186     if (index == 0)
187     {
188         vogl_default_framebuffer_state* pDefaultState = container.pDefaultFBState;
189
190         vogl_texture_state& rFrontLeft = pDefaultState->get_texture(cDefFramebufferFrontLeft);
191         vogl_texture_state& rBackLeft = pDefaultState->get_texture(cDefFramebufferBackLeft);
192         vogl_texture_state& rFrontRight = pDefaultState->get_texture(cDefFramebufferFrontRight);
193         vogl_texture_state& rBackRight = pDefaultState->get_texture(cDefFramebufferBackRight);
194         vogl_texture_state& rDepthStencil = pDefaultState->get_texture(cDefFramebufferDepthStencil);
195
196         if (rFrontLeft.is_valid())
197         {
198             colorVec.push_back(&rFrontLeft);
199             ADD_COLOR_BUFFER_VIEWER
200             pViewer->add_texture_object(rFrontLeft, "GL_FRONT_LEFT");
201         }
202         if (rBackLeft.is_valid())
203         {
204             colorVec.push_back(&rBackLeft);
205             ADD_COLOR_BUFFER_VIEWER
206             pViewer->add_texture_object(rBackLeft, "GL_BACK_LEFT");
207         }
208         if (rFrontRight.is_valid())
209         {
210             colorVec.push_back(&rFrontRight);
211             ADD_COLOR_BUFFER_VIEWER
212             pViewer->add_texture_object(rFrontRight, "GL_FRONT_RIGHT");
213         }
214         if (rBackRight.is_valid())
215         {
216             colorVec.push_back(&rBackRight);
217             ADD_COLOR_BUFFER_VIEWER
218             pViewer->add_texture_object(rBackRight, "GL_BACK_RIGHT");
219         }
220
221         if (rDepthStencil.is_valid()) { depthVec.push_back(&rDepthStencil); m_depthExplorer->add_texture_object(rDepthStencil, "GL_DEPTH"); }
222         if (rDepthStencil.is_valid()) { stencilVec.push_back(&rDepthStencil); m_stencilExplorer->add_texture_object(rDepthStencil, "GL_STENCIL"); }
223     }
224     else
225     {
226         vogl_framebuffer_state* pState = container.pFBOState;
227         if (pState != NULL)
228         {
229             vogl_gl_object_state_ptr_vec textureVec;
230             m_context->get_all_objects_of_category(cGLSTTexture, textureVec);
231
232             vogl_gl_object_state_ptr_vec renderbufferVec;
233             m_context->get_all_objects_of_category(cGLSTRenderbuffer, renderbufferVec);
234
235             const vogl_framebuffer_state::GLenum_to_attachment_map& rAttachments = pState->get_attachments();
236             for (vogl_framebuffer_state::GLenum_to_attachment_map::const_iterator iter = rAttachments.begin(); iter != rAttachments.end(); iter++)
237             {
238                 const vogl_framebuffer_attachment* pAttachment = &(iter->second);
239                 if (pAttachment->get_type() == GL_TEXTURE)
240                 {
241                     vogl_texture_state* pTexState = this->get_texture_attachment(&textureVec, pAttachment->get_handle());
242                     if (pTexState != NULL)
243                     {
244                         if (iter->first == GL_DEPTH_ATTACHMENT ||
245                             iter->first == GL_DEPTH)
246                         {
247                             depthVec.push_back(pTexState);
248                         }
249                         else if (iter->first == GL_STENCIL_ATTACHMENT ||
250                                  iter->first == GL_STENCIL)
251                         {
252                             stencilVec.push_back(pTexState);
253                         }
254                         else
255                         {
256                             colorVec.push_back(pTexState);
257
258                             ADD_COLOR_BUFFER_VIEWER
259                         }
260                     }
261                 }
262                 else if (pAttachment->get_type() == GL_RENDERBUFFER)
263                 {
264                     vogl_renderbuffer_state* pRbState = this->get_renderbuffer_attachment(&renderbufferVec, pAttachment->get_handle());
265                     if (pRbState != NULL)
266                     {
267                         if (iter->first == GL_DEPTH_ATTACHMENT ||
268                             iter->first == GL_DEPTH)
269                         {
270                             depthVec.push_back(pRbState);
271                         }
272                         else if (iter->first == GL_STENCIL_ATTACHMENT ||
273                                  iter->first == GL_STENCIL)
274                         {
275                             stencilVec.push_back(pRbState);
276                         }
277                         else
278                         {
279                             colorVec.push_back(pRbState);
280
281                             ADD_COLOR_BUFFER_VIEWER
282                         }
283                     }
284                 }
285                 else
286                 {
287                     VOGL_ASSERT(!"Unhandled framebuffer attachment type");
288                 }
289             }
290         }
291     }
292
293 #undef ADD_COLOR_BUFFER_VIEWER
294
295     if (colorVec.size() == 0)
296     {
297         ui->colorBufferGroupBox->setMinimumHeight(50);
298     }
299     else
300     {
301         uint totalHeight = 0;
302         uint viewerIndex = 0;
303         for (vogleditor_QTextureExplorer** iter = m_viewers.begin(); iter != m_viewers.end(); iter++)
304         {
305             (*iter)->set_zoom_factor(0.2);
306
307             // use index which was passed in as parameter
308             if (index != 0)
309             {
310                 (*iter)->set_texture_objects(colorVec);
311                 (*iter)->set_active_texture(colorVec[viewerIndex]->get_snapshot_handle());
312             }
313
314             // for better visibility, adjust height based on combined preferred heights
315             totalHeight += (*iter)->get_preferred_height();
316             (*iter)->setFixedHeight((*iter)->get_preferred_height());
317             ++viewerIndex;
318
319             connect(*iter, SIGNAL(zoomFactorChanged(double)), this, SLOT(on_zoomFactorChanged(double)));
320         }
321     }
322
323     if (depthVec.size() == 0)
324     {
325         m_depthExplorer->setVisible(false);
326         ui->depthBufferGroupBox->setMinimumHeight(50);
327     }
328     else
329     {
330         m_depthExplorer->setVisible(true);
331         m_depthExplorer->set_zoom_factor(0.2);
332         // use index which was passed in as parameter
333         if (index != 0)
334         {
335             m_depthExplorer->set_texture_objects(depthVec);
336             m_depthExplorer->set_active_texture(depthVec[0]->get_snapshot_handle());
337         }
338         connect(m_depthExplorer, SIGNAL(zoomFactorChanged(double)), this, SLOT(on_zoomFactorChanged(double)));
339         m_depthExplorer->setMinimumHeight(m_depthExplorer->get_preferred_height());
340     }
341
342     if (stencilVec.size() == 0)
343     {
344         m_stencilExplorer->setVisible(false);
345         ui->stencilBufferGroupBox->setMinimumHeight(50);
346     }
347     else
348     {
349         m_stencilExplorer->setVisible(true);
350         m_stencilExplorer->set_zoom_factor(0.2);
351         // use index which was passed in as parameter
352         if (index != 0)
353         {
354             m_stencilExplorer->set_texture_objects(stencilVec);
355             m_stencilExplorer->set_active_texture(stencilVec[0]->get_snapshot_handle());
356         }
357         connect(m_stencilExplorer, SIGNAL(zoomFactorChanged(double)), this, SLOT(on_zoomFactorChanged(double)));
358         m_stencilExplorer->setMinimumHeight(m_stencilExplorer->get_preferred_height());
359     }
360 }
361
362 vogl_texture_state* vogleditor_QFramebufferExplorer::get_texture_attachment(vogl_gl_object_state_ptr_vec* pObjectVec, unsigned int handle)
363 {
364     vogl_gl_object_state_ptr_vec textureVec;
365     if (pObjectVec == NULL)
366     {
367         m_context->get_all_objects_of_category(cGLSTTexture, textureVec);
368         pObjectVec = &textureVec;
369     }
370
371     vogl_texture_state* pTexState = NULL;
372     for (vogl_gl_object_state_ptr_vec::iterator texIter = pObjectVec->begin(); texIter != pObjectVec->end(); texIter++)
373     {
374         if ((*texIter)->get_snapshot_handle() == handle)
375         {
376             pTexState = static_cast<vogl_texture_state*>(*texIter);
377             break;
378         }
379     }
380
381     return pTexState;
382 }
383
384 vogl_renderbuffer_state* vogleditor_QFramebufferExplorer::get_renderbuffer_attachment(vogl_gl_object_state_ptr_vec* pObjectVec, unsigned int handle)
385 {
386     vogl_gl_object_state_ptr_vec renderbufferVec;
387     if (pObjectVec == NULL)
388     {
389         m_context->get_all_objects_of_category(cGLSTRenderbuffer, renderbufferVec);
390         pObjectVec = &renderbufferVec;
391     }
392
393     vogl_renderbuffer_state* pRenderbufferState = NULL;
394     for (vogl_gl_object_state_ptr_vec::iterator texIter = pObjectVec->begin(); texIter != pObjectVec->end(); texIter++)
395     {
396         if ((*texIter)->get_snapshot_handle() == handle)
397         {
398             pRenderbufferState = static_cast<vogl_renderbuffer_state*>(*texIter);
399             break;
400         }
401     }
402
403     return pRenderbufferState;
404 }
405
406 void vogleditor_QFramebufferExplorer::on_zoomFactorChanged(double zoomFactor)
407 {
408     VOGL_NOTE_UNUSED(zoomFactor);
409
410     uint totalHeight = 0;
411     for (vogleditor_QTextureExplorer** iter = m_viewers.begin(); iter != m_viewers.end(); iter++)
412     {
413         // for better visibility, adjust height based on combined preferred heights
414         totalHeight += (*iter)->get_preferred_height();
415         (*iter)->setFixedHeight((*iter)->get_preferred_height());
416     }
417
418     m_depthExplorer->setMinimumHeight(m_depthExplorer->get_preferred_height());
419     m_stencilExplorer->setMinimumHeight(m_stencilExplorer->get_preferred_height());
420 }