ImageCanvas.cpp
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @file ImageCanvas.cpp 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 <!-------------------------------------------------------------------->**/ 00007 00008 #include "ImageCanvas.h" 00009 #include "RenderThread.h" 00010 #include "Gui.h" 00011 00012 #include <renderers/PointSample.h> 00013 #include <utils/SpectralSampleSet.h> 00014 00015 ImageCanvas::ImageCanvas(Gui *gui, unsigned width, unsigned height) 00016 : Canvas(gui, width, height), 00017 NaiveRenderOutput(), 00018 m_qimage(NULL), m_image(NULL), m_renderCount(NULL) 00019 { 00020 m_qimage = new QImage(m_width, m_height, QImage::Format_RGB32); 00021 m_mainProxy = new MainSyscallProxy(); 00022 00023 _init(); 00024 } 00025 00026 ImageCanvas::ImageCanvas(Gui *gui, const QImage &background) 00027 : Canvas(gui, background.width(), background.height()), 00028 NaiveRenderOutput(), 00029 m_qimage(new QImage(background)), m_image(NULL), m_renderCount(NULL) 00030 { 00031 _init(); 00032 } 00033 00034 ImageCanvas::~ImageCanvas() { 00035 safeDelete(m_qimage); 00036 safeDelete(m_image); 00037 safeDeleteArray(m_renderCount); 00038 } 00039 00040 00041 bool ImageCanvas::save(const char *fileName) { 00042 if (m_qimage == NULL) 00043 return false; 00044 00045 return m_qimage->save(QString(fileName), NULL, -1); 00046 } 00047 00048 bool ImageCanvas::load(const char *fileName) { 00049 QImage *temp = new QImage; 00050 if (!temp->load(QString(fileName))) 00051 return false; 00052 00053 if (temp->format() != QImage::Format_RGB32) { 00054 QImage *old = temp; 00055 00056 temp = new QImage(old->convertToFormat(QImage::Format_RGB32)); 00057 00058 safeDelete(old); 00059 } 00060 00061 setSize(temp->width(), temp->height()); 00062 00063 memcpy(getData(), temp->bits(), temp->numBytes()); 00064 update(); 00065 00066 safeDelete(temp); 00067 return true; 00068 } 00069 00070 00071 void ImageCanvas::setPixel(unsigned x, unsigned y, const Rgba32 &color) { 00072 ASSERT(x >= 0 && x < m_width); 00073 ASSERT(y >= 0 && y < m_height); 00074 ASSERT(m_qimage); 00075 00076 m_qimage->setPixel(x, y, qRgb(color.r, color.g, color.b)); 00077 } 00078 00079 Rgba32 ImageCanvas::getPixel(unsigned x, unsigned y) const { 00080 ASSERT(x >= 0 && x < m_width); 00081 ASSERT(y >= 0 && y < m_height); 00082 ASSERT(m_qimage); 00083 00084 Rgba32 c; 00085 QRgb rgb = m_qimage->pixel(x, y); 00086 00087 c.r = (unsigned char)qRed(rgb); 00088 c.g = (unsigned char)qGreen(rgb); 00089 c.b = (unsigned char)qBlue(rgb); 00090 00091 return c; 00092 } 00093 00094 void ImageCanvas::setData(const Rgba32 *data) { 00095 ASSERT(data); 00096 00097 safeDelete(m_qimage); 00098 safeDelete(m_image); 00099 00100 m_qimage = new QImage((unsigned char*) data, m_width, m_height, QImage::Format_RGB32); 00101 m_image = new RgbaImage(*m_qimage); 00102 00103 update(); 00104 } 00105 00106 void ImageCanvas::setData(const Rgba32 *data, 00107 unsigned newWidth, 00108 unsigned newHeight) 00109 { 00110 if (data == NULL) 00111 return; 00112 00113 m_width = newWidth; 00114 m_height = newHeight; 00115 00116 if ((void*) data != (void*) m_qimage->bits()) { 00117 safeDelete(m_qimage); 00118 safeDelete(m_image); 00119 00120 m_qimage = new QImage((unsigned char*) data, m_width, m_height, QImage::Format_RGB32); 00121 m_image = new RgbaImage(*m_qimage); 00122 } 00123 00124 _resizeImage(false); 00125 } 00126 00127 00128 void ImageCanvas::setWidth(unsigned width) { 00129 if (m_width != width) { 00130 m_width = width; 00131 00132 _resizeImage(); 00133 } 00134 } 00135 00136 void ImageCanvas::setHeight(unsigned height) { 00137 if (m_height != height) { 00138 m_height = height; 00139 00140 _resizeImage(); 00141 } 00142 } 00143 00144 void ImageCanvas::setSize(unsigned width, unsigned height) { 00145 if ((m_width != width || m_height != height) && width > 0 && height > 0) { 00146 m_width = width; 00147 m_height = height; 00148 00149 _resizeImage(); 00150 } 00151 } 00152 00153 00154 bool ImageCanvas::supportsOpenGL() const { 00155 return false; 00156 } 00157 00158 00159 void ImageCanvas::render() { 00160 ASSERT(m_renderer); 00161 00162 safeDeleteArray(m_renderCount); 00163 m_renderCount = new unsigned[m_height]; 00164 memset(m_renderCount, 0, sizeof(unsigned) * m_height); 00165 00166 m_renderer->render(); 00167 } 00168 00169 void ImageCanvas::render(unsigned x0, unsigned y0, 00170 unsigned width, unsigned height) 00171 { 00172 ASSERT(m_renderer); 00173 00174 safeDeleteArray(m_renderCount); 00175 m_renderCount = new unsigned[m_height]; 00176 memset(m_renderCount, 0, sizeof(unsigned) * m_height); 00177 00178 // TODO: handle subrendering 00179 m_renderer->render(); 00180 } 00181 00182 void ImageCanvas::redraw() { 00183 update(); 00184 } 00185 00186 void ImageCanvas::update() { 00187 if (QThread::currentThread() == qApp->thread()) { 00188 QWidget::update(); 00189 } else { 00190 LocalSyscallProxy(this, m_mainProxy).repaint(0, 0, m_width, m_height); 00191 } 00192 } 00193 00194 void ImageCanvas::update(int x, int y, int width, int height) { 00195 if (QThread::currentThread() == qApp->thread()) { 00196 QWidget::update(x, y, width, height); 00197 } else { 00198 LocalSyscallProxy(this, m_mainProxy).repaint(x, y, width, height); 00199 } 00200 } 00201 00202 00203 void ImageCanvas::_addSample(const PointSample &sample) { 00204 NaiveRenderOutput::_addSample(sample); 00205 unsigned x, y; 00206 00207 m_viewport.getBin(sample.position, x, y); 00208 00209 if (NULL == m_renderCount) { 00210 m_renderCount = new unsigned[m_height]; 00211 memset(m_renderCount, 0, sizeof(unsigned) * m_height); 00212 } 00213 00214 // no need to synchronize access to m_renderCount because we're in Qt's 00215 // GUI thread, which is already synchronized via the LocalSyscallProxy 00216 // mechanism (there is only one accessible Qt GUI thread) 00217 if (++m_renderCount[y] % (m_width - 1) == 0) { 00218 if (y < m_height - 1) 00219 update(0, y, m_width, 1); 00220 else 00221 update(0, 0, m_width, m_height); 00222 } 00223 } 00224 00225 00226 void ImageCanvas::mousePressEvent(QMouseEvent *e) { 00227 mousePressed(e); 00228 } 00229 00230 void ImageCanvas::mouseReleaseEvent(QMouseEvent *e) { 00231 mouseReleased(e); 00232 } 00233 00234 void ImageCanvas::mouseMoveEvent(QMouseEvent *e) { 00235 mouseMoved(e); 00236 } 00237 00238 void ImageCanvas::keyPressEvent(QKeyEvent *e) { 00239 keyPressed(e); 00240 } 00241 00242 void ImageCanvas::keyReleaseEvent(QKeyEvent *e) { 00243 keyReleased(e); 00244 } 00245 00246 00247 QSize ImageCanvas::sizeHint() const { 00248 return QSize(getWidth(), getHeight()); 00249 } 00250 00251 QSize ImageCanvas::minimumSize() const { 00252 return sizeHint(); 00253 } 00254 00255 QSize ImageCanvas::maximumSize() const { 00256 return sizeHint(); 00257 } 00258 00259 00260 void ImageCanvas::paintEvent(QPaintEvent *e) { 00261 ASSERT(m_qimage); 00262 00263 if (NULL == m_qimage || m_qimage->isNull()) { 00264 cerr << "ImageCanvas::paintEvent invalid QImage" << endl; 00265 ASSERT(0); 00266 abort(); 00267 } 00268 00269 QPainter painter(this); 00270 /*const QRect clip(0, 0, m_width, m_height); 00271 p.setClipRect(clip); 00272 p.drawImage(clip, *m_qimage, clip);*/ 00273 00274 painter.drawImage(0, 0, *m_qimage); 00275 00276 /* Notify all listeners of the paint event */ 00277 ListenerListIter iter; 00278 painter.setRenderHint(QPainter::Antialiasing); 00279 00280 for(iter = m_interactionListeners.begin(); iter != m_interactionListeners.end(); iter++) { 00281 (*iter)->paint(&painter); 00282 } 00283 } 00284 00285 00286 void ImageCanvas::_init() { 00287 m_image = new RgbaImage(*m_qimage); 00288 NaiveRenderOutput::setImage(m_image); 00289 00290 _setupQWidget(); 00291 } 00292 00293 void ImageCanvas::_setupQWidget() { 00294 // minor optimization: tell Qt that we'll be painting our own background 00295 setAutoFillBackground(false); 00296 setAttribute(Qt::WA_NoSystemBackground); 00297 setFocusPolicy(Qt::StrongFocus); 00298 00299 if (layout() != NULL) 00300 layout()->setSizeConstraint(QLayout::SetFixedSize); 00301 00302 setMouseTracking(true); 00303 setFixedSize(m_width, m_height); 00304 } 00305 00306 void ImageCanvas::_resizeImage(bool modifyImage) { 00307 if (modifyImage) { 00308 safeDelete(m_qimage); 00309 safeDelete(m_image); 00310 00311 m_qimage = new QImage(m_width, m_height, QImage::Format_RGB32); 00312 m_image = new RgbaImage(*m_qimage); 00313 } 00314 00315 setFixedSize(m_width, m_height); 00316 //sizeChanged (m_width, m_height); 00317 00318 if (modifyImage) 00319 update(); 00320 } 00321 00322 void ImageCanvas::_repaintPrivate(unsigned x, unsigned y, 00323 unsigned w, unsigned h) 00324 { 00325 QWidget::repaint(x, y, w, h); 00326 } 00327
Generated on 28 Feb 2009 for Milton by
1.5.6