void GLWidgetRenderer2::drawFrame() { DPTR_D(GLWidgetRenderer2); QRect roi = realROI(); //d.glv.render(QRectF(-1, 1, 2, -2), roi, d.matrix); // QRectF() means the whole viewport d.glv.render(QRectF(), roi, d.matrix); }
void OpenGLRendererBase::drawFrame() { DPTR_D(OpenGLRendererBase); QRect roi = realROI(); //d.glv.render(QRectF(-1, 1, 2, -2), roi, d.matrix); // QRectF() means the whole viewport d.glv.render(QRectF(), roi, d.matrix); }
void GraphicsItemRenderer::drawFrame() { DPTR_D(GraphicsItemRenderer); if (!d.painter) return; if (d.checkGL()) { d.glv.render(boundingRect(), realROI(), d.matrix*sceneTransform()); return; } QPainterRenderer::drawFrame(); }
void OpenGLRendererBase::drawFrame() { DPTR_D(OpenGLRendererBase); QRect roi = realROI(); //d.glv.render(QRectF(-1, 1, 2, -2), roi, d.matrix); // QRectF() means the whole viewport if (d.frame_changed) { d.glv.setCurrentFrame(d.video_frame); d.frame_changed = false; } d.glv.render(QRectF(), roi, d.matrix); }
void GraphicsItemRenderer::drawFrame() { DPTR_D(GraphicsItemRenderer); if (!d.painter) return; if (d.checkGL()) { d.glv.render(boundingRect(), realROI(), d.matrix*sceneTransform()); return; } //fill background color only when the displayed frame rect not equas to renderer's if (d.image.isNull()) { //TODO: when setInSize()? d.image = QImage(rendererSize(), QImage::Format_RGB32); d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint) } const QRect roi = realROI(); //assume that the image data is already scaled to out_size(NOT renderer size!) if (roi.size() == d.out_rect.size()) { d.painter->drawImage(d.out_rect.topLeft(), d.image, roi); } else { d.painter->drawImage(d.out_rect, d.image, roi); } }
void XVRenderer::drawFrame() { DPTR_D(XVRenderer); QRect roi = realROI(); if (!d.use_shm) XvPutImage(d.display, d.xv_port, winId(), d.gc, d.xv_image , roi.x(), roi.y(), roi.width(), roi.height() , d.out_rect.x(), d.out_rect.y(), d.out_rect.width(), d.out_rect.height()); else XvShmPutImage(d.display, d.xv_port, winId(), d.gc, d.xv_image , roi.x(), roi.y(), roi.width(), roi.height() , d.out_rect.x(), d.out_rect.y(), d.out_rect.width(), d.out_rect.height() , false /*true: send event*/); }
bool QQuickItemRenderer::receiveFrame(const VideoFrame &frame) { DPTR_D(QQuickItemRenderer); d.video_frame = frame; if (!isOpenGL()) { d.image = QImage((uchar*)frame.constBits(), frame.width(), frame.height(), frame.bytesPerLine(), frame.imageFormat()); QRect r = realROI(); if (r != QRect(0, 0, frame.width(), frame.height())) d.image = d.image.copy(r); } d.frame_changed = true; // update(); // why update slow? because of calling in a different thread? //QMetaObject::invokeMethod(this, "update"); // slower than directly postEvent QCoreApplication::postEvent(this, new QEvent(QEvent::User)); return true; }
void Direct2DRenderer::drawFrame() { DPTR_D(Direct2DRenderer); D2D1_RECT_F out_rect = { (FLOAT)d.out_rect.left(), (FLOAT)d.out_rect.top(), (FLOAT)d.out_rect.right(), (FLOAT)d.out_rect.bottom() }; QRect roi = realROI(); D2D1_RECT_F roi_d2d = { (FLOAT)roi.left(), (FLOAT)roi.top(), (FLOAT)roi.right(), (FLOAT)roi.bottom() }; //d.render_target->SetTransform d.render_target->DrawBitmap(d.bitmap , &out_rect , 1 //opacity , d.interpolation , &roi_d2d); }
void GLWidgetRenderer::drawFrame() { DPTR_D(GLWidgetRenderer); QRect roi = realROI(); d.upload(roi); // shader program may not ready before upload if (d.hasGLSL) { #if NO_QGL_SHADER glUseProgram(d.program); //for glUniform #else d.shader_program->bind(); #endif //NO_QGL_SHADER } glDisable(GL_DEPTH_TEST); const int nb_planes = d.video_frame.planeCount(); //number of texture id // all texture ids should be binded when renderering even for packed plane! for (int i = 0; i < nb_planes; ++i) { glActiveTexture(GL_TEXTURE0 + i); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, d.textures[i]); //we've bind 0 after upload() // use glUniform1i to swap planes. swap uv: i => (3-i)%3 // TODO: in shader, use uniform sample2D u_Texture[], and use glUniform1iv(u_Texture, 3, {...}) #if NO_QGL_SHADER glUniform1i(d.u_Texture[i], i); #else d.shader_program->setUniformValue(d.u_Texture[i], (GLint)i); #endif } if (nb_planes < d.u_Texture.size()) { for (int i = nb_planes; i < d.u_Texture.size(); ++i) { #if NO_QGL_SHADER glUniform1i(d.u_Texture[i], nb_planes - 1); #else d.shader_program->setUniformValue(d.u_Texture[i], (GLint)(nb_planes - 1)); #endif } } //TODO: compute kTexCoords only if roi changed #if ROI_TEXCOORDS /*! tex coords: ROI/frameRect()*effective_tex_width_ratio */ const GLfloat kTexCoords[] = { (GLfloat)roi.x()*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(), (GLfloat)(roi.x() + roi.width())*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(), (GLfloat)(roi.x() + roi.width())*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(), (GLfloat)roi.x()*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(), }; /// glVertexAttribPointer(d.a_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords); /// glEnableVertexAttribArray(d.a_TexCoords); #else const GLfloat kTexCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1, }; #endif //ROI_TEXCOORDS #ifndef QT_OPENGL_ES_2 //GL_XXX may not defined in ES2. so macro is required if (!d.hasGLSL) { //qpainter will reset gl state, so need glMatrixMode and clear color(in drawBackground()) //TODO: study what state will be reset glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event? glVertexPointer(2, GL_FLOAT, 0, kVertices); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, kTexCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); } #endif //QT_OPENGL_ES_2 if (d.hasGLSL) { d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event? //qpainter need. TODO: VBO? #if NO_QGL_SHADER glVertexAttribPointer(d.a_Position, 2, GL_FLOAT, GL_FALSE, 0, kVertices); glEnableVertexAttribArray(d.a_Position); glVertexAttribPointer(d.a_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords); glEnableVertexAttribArray(d.a_TexCoords); #else d.shader_program->setAttributeArray(d.a_Position, GL_FLOAT, kVertices, 2); d.shader_program->enableAttributeArray(d.a_Position); d.shader_program->setAttributeArray(d.a_TexCoords, GL_FLOAT, kTexCoords, 2); d.shader_program->enableAttributeArray(d.a_TexCoords); #endif /* * in Qt4 QMatrix4x4 stores qreal (double), while GLfloat may be float * QShaderProgram deal with this case. But compares sizeof(QMatrix4x4) and (GLfloat)*16 * which seems not correct because QMatrix4x4 has a flag var */ GLfloat *mat = (GLfloat*)d.colorTransform.matrixRef().data(); GLfloat glm[16]; #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) if (sizeof(qreal) != sizeof(GLfloat)) { #else if (sizeof(float) != sizeof(GLfloat)) { #endif d.colorTransform.matrixData(glm); mat = glm; } //QMatrix4x4 stores value in Column-major order to match OpenGL. so transpose is not required in glUniformMatrix4fv #if NO_QGL_SHADER glUniformMatrix4fv(d.u_colorMatrix, 1, GL_FALSE, mat); #else d.shader_program->setUniformValue(d.u_colorMatrix, d.colorTransform.matrixRef()); #endif glDrawArrays(GL_TRIANGLE_FAN, 0, 4); #if NO_QGL_SHADER glUseProgram(0); glDisableVertexAttribArray(d.a_TexCoords); glDisableVertexAttribArray(d.a_Position); #else d.shader_program->release(); d.shader_program->disableAttributeArray(d.a_TexCoords); d.shader_program->disableAttributeArray(d.a_Position); #endif } for (int i = 0; i < d.textures.size(); ++i) { //glActiveTexture: gl functions apply on texture i glActiveTexture(GL_TEXTURE0 + i); glDisable(GL_TEXTURE_2D); } } void GLWidgetRenderer::initializeGL() { DPTR_D(GLWidgetRenderer); makeCurrent(); //const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); d.hasGLSL = QGLShaderProgram::hasOpenGLShaderPrograms(); qDebug("OpenGL version: %d.%d hasGLSL: %d", format().majorVersion(), format().minorVersion(), d.hasGLSL); #if QTAV_HAVE(QGLFUNCTIONS) initializeGLFunctions(); d.initializeGLFunctions(); #endif //QTAV_HAVE(QGLFUNCTIONS) qtavResolveActiveTexture(); glEnable(GL_TEXTURE_2D); if (!d.hasGLSL) { #ifndef QT_OPENGL_ES_2 glShadeModel(GL_SMOOTH); //setupQuality? glClearDepth(1.0f); #endif //QT_OPENGL_ES_2 } else { d.initWithContext(context()); } glClearColor(0.0, 0.0, 0.0, 0.0); d.setupQuality(); }
void GLWidgetRenderer::drawFrame() { DPTR_D(GLWidgetRenderer); #ifdef QT_OPENGL_ES_2 #define FMT_INTERNAL GL_BGRA //why BGRA? #define FMT GL_BGRA glUseProgram(d.program); //qpainter need glActiveTexture(GL_TEXTURE0); //TODO: can remove?? glUniform1i(d.tex_location, 0); #else //QT_OPENGL_ES_2 #define FMT_INTERNAL GL_RGBA //why? why 3 works? #define FMT GL_BGRA #endif //QT_OPENGL_ES_2 glBindTexture(GL_TEXTURE_2D, d.texture); d.setupQuality(); QRect roi = realROI(); //uploading part of image eats less gpu memory, but may be more cpu(gles) //FIXME: more cpu usage then qpainter. FBO, VBO? #define ROI_TEXCOORDS 1 if (ROI_TEXCOORDS || roi.size() == d.video_frame.size()) { glTexImage2D(GL_TEXTURE_2D , 0 //level , FMT_INTERNAL //internal format. 4? why GL_RGBA? GL_RGB? , d.video_frame.width(), d.video_frame.height() , 0 //border, ES not support , FMT //format, must the same as internal format? , GL_UNSIGNED_BYTE , d.video_frame.bits()); } else { #ifdef GL_UNPACK_ROW_LENGTH // http://stackoverflow.com/questions/205522/opengl-subtexturing glPixelStorei(GL_UNPACK_ROW_LENGTH, d.video_frame.width()); //glPixelStorei or compute pointer glPixelStorei(GL_UNPACK_SKIP_PIXELS, roi.x()); glPixelStorei(GL_UNPACK_SKIP_ROWS, roi.y()); glTexImage2D(GL_TEXTURE_2D, 0, FMT_INTERNAL, roi.width(), roi.height(), 0, FMT, GL_UNSIGNED_BYTE, d.video_frame.bits()); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); #else // GL ES //define it? or any efficient way? glTexImage2D(GL_TEXTURE_2D, 0, FMT_INTERNAL, roi.width(), roi.height(), 0, FMT, GL_UNSIGNED_BYTE, NULL); // how to use only 1 call? //glTexSubImage2D(GL_TEXTURE_2D, 0, roi.x(), roi.y(), roi.width(), roi.height(), FMT, GL_UNSIGNED_BYTE, d.data.constData()); for(int y = 0; y < roi.height(); y++) { char *row = (char*)d.video_frame.bits() + ((y + roi.y())*d.video_frame.width() + roi.x()) * 4; glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, roi.width(), 1, FMT, GL_UNSIGNED_BYTE, row); } #endif //GL_UNPACK_ROW_LENGTH } //TODO: compute kTexCoords only if roi changed #if ROI_TEXCOORDS const GLfloat kTexCoords[] = { (GLfloat)roi.x()/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(), (GLfloat)(roi.x() + roi.width())/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(), (GLfloat)(roi.x() + roi.width())/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(), (GLfloat)roi.x()/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(), }; /// glVertexAttribPointer(d.tex_coords_location, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords); /// glEnableVertexAttribArray(d.tex_coords_location); #else const GLfloat kTexCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1, }; #endif //ROI_TEXCOORDS #ifndef QT_OPENGL_ES_2 //qpainter will reset gl state, so need glMatrixMode and clear color(in drawBackground()) //TODO: study what state will be reset glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event? glVertexPointer(2, GL_FLOAT, 0, kVertices); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, kTexCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); #else //QT_OPENGL_ES_2 d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event? //qpainter need. TODO: VBO? glVertexAttribPointer(d.position_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); glEnableVertexAttribArray(d.position_location); glVertexAttribPointer(d.tex_coords_location, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords); glEnableVertexAttribArray(d.tex_coords_location); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableVertexAttribArray(d.tex_coords_location); glDisableVertexAttribArray(d.position_location); #endif //QT_OPENGL_ES_2 }