]> git.cworth.org Git - vogl/blob - src/vogleditor/vogleditor_qtextureexplorer.cpp
UI: Improved support for shared contexts and viewing shared state objects
[vogl] / src / vogleditor / vogleditor_qtextureexplorer.cpp
1 #include "vogleditor_qtextureexplorer.h"
2 #include "ui_vogleditor_qtextureexplorer.h"
3
4 #include "vogl_gl_object.h"
5 #include "vogl_gl_state_snapshot.h"
6 #include "vogl_texture_state.h"
7 #include "vogl_renderbuffer_state.h"
8 #include <QColorDialog>
9
10 Q_DECLARE_METATYPE(vogl_gl_object_state*);
11
12 vogleditor_QTextureExplorer::vogleditor_QTextureExplorer(QWidget *parent) :
13     QWidget(parent),
14     ui(new Ui::vogleditor_QTextureExplorer)
15 {
16     ui->setupUi(this);
17
18     ui->textureScrollArea->setWidget(&m_textureViewer);
19
20     ui->channelSelectionBox->addItem("RGBA", VOGL_CSO_RGBA);
21     ui->channelSelectionBox->addItem("RGB", VOGL_CSO_RGB);
22     ui->channelSelectionBox->addItem("R", VOGL_CSO_R);
23     ui->channelSelectionBox->addItem("G", VOGL_CSO_G);
24     ui->channelSelectionBox->addItem("B", VOGL_CSO_B);
25     ui->channelSelectionBox->addItem("A", VOGL_CSO_A);
26
27     ui->channelSelectionBox->addItem("1 - RGBA", VOGL_CSO_ONE_MINUS_RGBA);
28     ui->channelSelectionBox->addItem("1 - RGB", VOGL_CSO_ONE_MINUS_RGB);
29     ui->channelSelectionBox->addItem("1 - R", VOGL_CSO_ONE_MINUS_R);
30     ui->channelSelectionBox->addItem("1 - G", VOGL_CSO_ONE_MINUS_G);
31     ui->channelSelectionBox->addItem("1 - B", VOGL_CSO_ONE_MINUS_B);
32     ui->channelSelectionBox->addItem("1 - A", VOGL_CSO_ONE_MINUS_A);
33
34     ui->channelSelectionBox->addItem("1 / RGBA", VOGL_CSO_ONE_OVER_RGBA);
35     ui->channelSelectionBox->addItem("1 / RGB", VOGL_CSO_ONE_OVER_RGB);
36     ui->channelSelectionBox->addItem("1 / R", VOGL_CSO_ONE_OVER_R);
37     ui->channelSelectionBox->addItem("1 / G", VOGL_CSO_ONE_OVER_G);
38     ui->channelSelectionBox->addItem("1 / B", VOGL_CSO_ONE_OVER_B);
39     ui->channelSelectionBox->addItem("1 / A", VOGL_CSO_ONE_OVER_A);
40
41     connect(ui->textureObjectListbox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectedTextureIndexChanged(int)));
42     connect(ui->channelSelectionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(channelSelectionChanged(int)));
43     connect(ui->alphaBlendColorButton, SIGNAL(clicked()), this, SLOT(alphaBlendButtonClicked()));
44
45     // set default channel so that it doesn't alpha blend
46     ui->channelSelectionBox->setCurrentIndex(VOGL_CSO_RGB);
47
48     ui->zoomSpinBox->setValue(m_textureViewer.getZoomFactor());
49 }
50
51 vogleditor_QTextureExplorer::~vogleditor_QTextureExplorer()
52 {
53     clear();
54     delete ui;
55 }
56
57 void vogleditor_QTextureExplorer::clear()
58 {
59     m_objects.clear();
60
61     ui->textureObjectListbox->clear();
62
63     m_textureViewer.clear();
64     m_textureViewer.repaint();
65 }
66
67 void vogleditor_QTextureExplorer::set_zoom_factor(double zoomFactor)
68 {
69     ui->zoomSpinBox->setValue(zoomFactor);
70 }
71
72 unsigned int vogleditor_QTextureExplorer::get_preferred_height() const
73 {
74     // texture viewer height, plus extra space for the explorer UI
75     return m_textureViewer.get_preferred_height() + ui->textureObjectListbox->height() * 2 + 50;
76 }
77
78 uint vogleditor_QTextureExplorer::set_texture_objects(vogl::vector<vogl_context_snapshot*> sharingContexts)
79 {
80     clear();
81
82     uint textureCount = 0;
83
84     for (uint c = 0; c < sharingContexts.size(); c++)
85     {
86         vogl_gl_object_state_ptr_vec textureObjects;
87         sharingContexts[c]->get_all_objects_of_category(cGLSTTexture, textureObjects);
88
89         textureCount += add_texture_objects(textureObjects);
90     }
91
92     return textureCount;
93 }
94
95 uint vogleditor_QTextureExplorer::set_renderbuffer_objects(vogl::vector<vogl_context_snapshot*> sharingContexts)
96 {
97     clear();
98
99     uint textureCount = 0;
100
101     for (uint c = 0; c < sharingContexts.size(); c++)
102     {
103         vogl_gl_object_state_ptr_vec renderbufferObjects;
104         sharingContexts[c]->get_all_objects_of_category(cGLSTRenderbuffer, renderbufferObjects);
105
106         textureCount += add_texture_objects(renderbufferObjects);
107     }
108
109     return textureCount;
110 }
111
112 uint vogleditor_QTextureExplorer::set_texture_objects(vogl_gl_object_state_ptr_vec textureObjects)
113 {
114     clear();
115
116     return add_texture_objects(textureObjects);
117 }
118
119 uint vogleditor_QTextureExplorer::add_texture_objects(vogl_gl_object_state_ptr_vec textureObjects)
120 {
121     uint textureCount = 0;
122
123     for (vogl_gl_object_state_ptr_vec::iterator iter = textureObjects.begin(); iter != textureObjects.end(); iter++)
124     {
125         ++textureCount;
126         m_objects.push_back(*iter);
127
128         if ((*iter)->get_type() == cGLSTTexture)
129         {
130             vogl_texture_state* pTexState = static_cast<vogl_texture_state*>(*iter);
131
132             QString valueStr;
133             valueStr = valueStr.sprintf("Texture %" PRIu64 " - %s (%u samples) (%u x %u x %u) %s", pTexState->get_snapshot_handle(), g_gl_enums.find_name(pTexState->get_target()), pTexState->get_num_samples(), pTexState->get_texture().get_width(), pTexState->get_texture().get_height(), pTexState->get_texture().get_depth(), g_gl_enums.find_name(pTexState->get_texture().get_ogl_internal_fmt()));
134
135             ui->textureObjectListbox->addItem(valueStr, QVariant::fromValue(*iter));
136         }
137         else if ((*iter)->get_type() == cGLSTRenderbuffer)
138         {
139             vogl_renderbuffer_state* pRbState = static_cast<vogl_renderbuffer_state*>(*iter);
140
141             QString valueStr;
142             valueStr = valueStr.sprintf("Renderbuffer %" PRIu64 " - %s (%u samples) (%u x %u) %s", pRbState->get_snapshot_handle(), "GL_RENDERBUFFER", pRbState->get_texture().get_num_samples(), pRbState->get_desc().get_int_or_default(GL_RENDERBUFFER_WIDTH), pRbState->get_desc().get_int_or_default(GL_RENDERBUFFER_HEIGHT), g_gl_enums.find_name(pRbState->get_desc().get_int_or_default(GL_RENDERBUFFER_INTERNAL_FORMAT)));
143
144             ui->textureObjectListbox->addItem(valueStr, QVariant::fromValue(*iter));
145         }
146         else
147         {
148             VOGL_ASSERT(!"Unhandled object type in TextureExplorer");
149         }
150     }
151
152     return textureCount;
153 }
154
155 uint vogleditor_QTextureExplorer::add_texture_object(vogl_texture_state& textureState, vogl::dynamic_string bufferType)
156 {
157     m_objects.push_back(&textureState);
158
159     QString valueStr;
160     valueStr = valueStr.sprintf("%s (%u x %u) %s", bufferType.c_str(), textureState.get_texture().get_width(), textureState.get_texture().get_height(), g_gl_enums.find_name(textureState.get_texture().get_ogl_internal_fmt()));
161
162     ui->textureObjectListbox->addItem(valueStr, QVariant::fromValue((vogl_gl_object_state*)&textureState));
163     return 1;
164 }
165
166 bool vogleditor_QTextureExplorer::set_active_texture(unsigned long long textureHandle)
167 {
168     bool bDisplayedTexture = false;
169     int index = 0;
170     for (vogl_gl_object_state_ptr_vec::iterator iter = m_objects.begin(); iter != m_objects.end(); iter++)
171     {
172         vogl_texture_state* pTexState = static_cast<vogl_texture_state*>(*iter);
173         if (pTexState->get_snapshot_handle() == textureHandle)
174         {
175             ui->textureObjectListbox->setCurrentIndex(index);
176             bDisplayedTexture = true;
177             break;
178         }
179
180         ++index;
181     }
182     return bDisplayedTexture;
183 }
184
185 void vogleditor_QTextureExplorer::selectedTextureIndexChanged(int index)
186 {
187     int count = ui->textureObjectListbox->count();
188     if (index >= 0 && index < count)
189     {
190         vogl_gl_object_state* pObjState = ui->textureObjectListbox->itemData(index).value<vogl_gl_object_state*>();
191         if (pObjState == NULL)
192         {
193             VOGL_ASSERT(!"NULL object type in TextureExplorer");
194             return;
195         }
196
197         vogl_texture_state* pTexState = NULL;
198
199         if (pObjState->get_type() == cGLSTTexture)
200         {
201             pTexState = static_cast<vogl_texture_state*>(pObjState);
202         }
203         else if (pObjState->get_type() == cGLSTRenderbuffer)
204         {
205             vogl_renderbuffer_state* pRbState = static_cast<vogl_renderbuffer_state*>(pObjState);
206             if (pRbState != NULL)
207             {
208                 pTexState = &(pRbState->get_texture());
209             }
210         }
211         else
212         {
213             VOGL_ASSERT(!"Unhandled object type in TextureExplorer");
214         }
215
216         if (pTexState != NULL)
217         {
218             uint maxSample = pTexState->get_num_samples();
219             if (maxSample <= 1)
220             {
221                 ui->sampleSpinBox->setEnabled(false);
222                 ui->sampleSpinBox->setMaximum(0);
223
224                 // simulate that the value has changed to select the first (only) sample
225                 on_sampleSpinBox_valueChanged(0);
226             }
227             else
228             {
229                 ui->sampleSpinBox->setEnabled(true);
230
231                 int sample = ui->sampleSpinBox->value();
232                 ui->sampleSpinBox->setMaximum(maxSample - 1);
233
234                 // if the value is still at the same sample after setting the max, then the
235                 // valueChanged signal will not be emitted, so we'll need to simulate that
236                 // in order to update and display the new texture.
237                 if (ui->sampleSpinBox->value() == (int)sample)
238                 {
239                     on_sampleSpinBox_valueChanged(sample);
240                 }
241             }
242         }
243     }
244 }
245
246 void vogleditor_QTextureExplorer::channelSelectionChanged(int index)
247 {
248     ChannelSelectionOption channelSelection = (ChannelSelectionOption)ui->channelSelectionBox->itemData(index).toInt();
249     m_textureViewer.setChannelSelectionOption(channelSelection);
250     bool bAlphaBlending = (channelSelection == VOGL_CSO_RGBA ||
251                            channelSelection == VOGL_CSO_ONE_MINUS_RGBA ||
252                            channelSelection == VOGL_CSO_ONE_OVER_RGBA );
253
254     ui->alphaBlendColorButton->setEnabled(bAlphaBlending);
255 }
256
257 void vogleditor_QTextureExplorer::alphaBlendButtonClicked()
258 {
259     QColor newColor = QColorDialog::getColor(m_textureViewer.getBackgroundColor(), this, "Select an alpha blend color");
260     m_textureViewer.setBackgroundColor(QBrush(newColor));
261 }
262
263 void vogleditor_QTextureExplorer::on_zoomSpinBox_valueChanged(double zoomFactor)
264 {
265     m_textureViewer.setZoomFactor(zoomFactor);
266     emit zoomFactorChanged(zoomFactor);
267 }
268
269 void vogleditor_QTextureExplorer::on_pushButton_toggled(bool checked)
270 {
271     m_textureViewer.setInverted(checked);
272 }
273
274 void vogleditor_QTextureExplorer::on_sampleSpinBox_valueChanged(int sample)
275 {
276     vogl_gl_object_state* pObjState = ui->textureObjectListbox->itemData(ui->textureObjectListbox->currentIndex()).value<vogl_gl_object_state*>();
277     if (pObjState == NULL)
278     {
279         VOGL_ASSERT(!"NULL object type in TextureExplorer");
280         return;
281     }
282
283     vogl_texture_state* pTexState = NULL;
284
285     if (pObjState->get_type() == cGLSTTexture)
286     {
287         pTexState = static_cast<vogl_texture_state*>(pObjState);
288     }
289     else if (pObjState->get_type() == cGLSTRenderbuffer)
290     {
291         vogl_renderbuffer_state* pRbState = static_cast<vogl_renderbuffer_state*>(pObjState);
292         if (pRbState != NULL)
293         {
294             pTexState = &(pRbState->get_texture());
295         }
296     }
297     else
298     {
299         VOGL_ASSERT(!"Unhandled object type in TextureExplorer");
300     }
301
302     if (pTexState != NULL)
303     {
304         const vogl::ktx_texture* pKTXTexture = &(pTexState->get_texture(sample));
305
306         uint baseLevel = pTexState->get_params().get_value<uint>(GL_TEXTURE_BASE_LEVEL);
307         uint maxLevel = pTexState->get_params().get_value<uint>(GL_TEXTURE_MAX_LEVEL);
308         m_textureViewer.setTexture(pKTXTexture, baseLevel, maxLevel);
309         m_textureViewer.repaint();
310     }
311 }