void ChannelPage::nicksReady() { QHashIterator<QString, IrcClient::UserMode*> iterator = Window::ircClient->getChannel(getName()).getUserIterator(); while (iterator.hasNext()) { QString key = iterator.next().key(); addUser(key); } }
QList<IQORMModel* > IQORMCore::allModels() { QList<IQORMModel* > result; QHashIterator<QString, QPointer<IQORMModel> > i (IQORMCore::_models); while (i.hasNext()) { i.next(); result << i.value(); } return result; }
QString Level::xml () { QString rv; rv.append(QString("<Level name=\"%1\">").arg(levelName())); QHashIterator<int, LevelObject*> o (this->levelObjects); o.toFront (); while (o.hasNext ()) { o.next (); LevelObject* obj = o.value (); int id = o.key (); rv.append(obj->xml (id)); } rv.append("</Level>"); return rv; }
//========================================= // timerDone //----------------------------------------- void Notify::timerDone (void) { // .../ // every time the timer expires this method is called. // the function will send a signal including the file // descriptor of the touched file and the flag whether this // file was created or deleted // ---- QHashIterator<int, int> it (mNotifyQueue); while (it.hasNext()) { it.next(); int fd = it.key(); int flag = it.value(); sendSignal (fd,flag); } mNotifyQueue.clear(); }
~BackgroundParserPrivate() { suspend(); m_weaver.dequeue(); m_weaver.requestAbort(); m_weaver.finish(); // Release dequeued jobs QHashIterator<KUrl, ParseJob*> it = m_parseJobs; while (it.hasNext()) { it.next(); it.value()->setBackgroundParser(0); delete it.value(); } qDeleteAll(m_delayedParseJobs); }
int ScriptEngine::unsetAllTimers() { int i = 0; QHashIterator <QTimer*, QScriptValue> it (timerEvents); while (it.hasNext()) { it.next(); QTimer *timer = it.key(); timer->stop(); timer->blockSignals(true); timerEvents.remove(timer); timer->deleteLater(); i++; } return i; }
bool ScriptEngine::unsetTimer(int timerId) { QHashIterator <QTimer*, QScriptValue> it (timerEvents); while (it.hasNext()) { it.next(); QTimer *timer = it.key(); if (timer->timerId() == timerId) { timer->stop(); timer->blockSignals(true); timerEvents.remove(timer); timer->deleteLater(); return true; // Timer found. } } warn ("unsetTimer(timerId)", "no timer with that id"); return false; // No timer found. }
// Clear all time statistics void Mainwindow::menuClearStatistics() { QString message; message = i18n("Do you really want to clear the all time " "statistical data?"); if (KMessageBox::Yes == KMessageBox::questionYesNo(this, message, QString(), KStandardGuiItem::clear())) { QHashIterator<int,Player *> it = mLSkatConfig->playerIterator(); while (it.hasNext()) { it.next(); Player *player = it.value(); player->clear(); } } }
QtPropertyData::~QtPropertyData() { QHashIterator<QString, QtPropertyData*> i = QHashIterator<QString, QtPropertyData*>(children); while(i.hasNext()) { i.next(); QtPropertyData *data = i.value(); if(NULL != data) { delete data; } } for (int i = 0; i < optionalWidgets.size(); i++) { if(NULL != optionalWidgets.at(i).widget) { delete optionalWidgets.at(i).widget; } } }
// Start a new game void Mainwindow::startGame() { // Enable game action QLatin1String endName(KStandardGameAction::name(KStandardGameAction::End)); ACTION(endName)->setEnabled(true); // Deal cards to player - Shuffle card deck and reset pile mDeck->shuffle(); // Draw Trump Suite trump = mDeck->randomTrump(); // Loop all players in the game QHashIterator<int,Player *> it = mLSkatConfig->playerIterator(); while (it.hasNext()) { it.next(); Player *player = it.value(); player->setDeck(mDeck); // Deal cards player->deal(16); // Store trump player->setTrump(trump); } // Start display mDisplay->start(); // Start the game engine mEngine->startGame(trump, mStartPlayer); // Start player for next game setStartPlayer(1-mStartPlayer); // statusBar()->clearMessage(); }
bool QtCreatorIntegration::navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames, QString *errorMessage) { typedef QMap<int, Document::Ptr> DocumentMap; const Utils::FileName currentUiFile = FormEditorW::activeEditor()->document()->filePath(); #if 0 return Designer::Internal::navigateToSlot(currentUiFile.toString(), objectName, signalSignature, parameterNames, errorMessage); #endif // TODO: we should pass to findDocumentsIncluding an absolute path to generated .h file from ui. // Currently we are guessing the name of ui_<>.h file and pass the file name only to the findDocumentsIncluding(). // The idea is that the .pro file knows if the .ui files is inside, and the .pro file knows it will // be generating the ui_<>.h file for it, and the .pro file knows what the generated file's name and its absolute path will be. // So we should somehow get that info from project manager (?) const QFileInfo fi = currentUiFile.toFileInfo(); const QString uiFolder = fi.absolutePath(); const QString uicedName = "ui_" + fi.completeBaseName() + ".h"; // Retrieve code model snapshot restricted to project of ui file or the working copy. Snapshot docTable = CppTools::CppModelManager::instance()->snapshot(); Snapshot newDocTable; const Project *uiProject = SessionManager::projectForFile(currentUiFile); if (uiProject) { for (Snapshot::const_iterator i = docTable.begin(), ei = docTable.end(); i != ei; ++i) { const Project *project = SessionManager::projectForFile(i.key()); if (project == uiProject) newDocTable.insert(i.value()); } } else { const CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const Utils::FileName configFileName = Utils::FileName::fromString(CppTools::CppModelManager::configurationFileName()); QHashIterator<Utils::FileName, QPair<QByteArray, unsigned> > it = workingCopy.iterator(); while (it.hasNext()) { it.next(); const Utils::FileName &fileName = it.key(); if (fileName != configFileName) newDocTable.insert(docTable.document(fileName)); } } docTable = newDocTable; // take all docs, find the ones that include the ui_xx.h. // Sort into a map, putting the ones whose path closely matches the ui-folder path // first in case there are project subdirectories that contain identical file names. const QList<Document::Ptr> docList = findDocumentsIncluding(docTable, uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file DocumentMap docMap; for (const Document::Ptr &d : docList) { const QFileInfo docFi(d->fileName()); docMap.insert(qAbs(docFi.absolutePath().compare(uiFolder, Qt::CaseInsensitive)), d); } if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size(); if (docMap.isEmpty()) { *errorMessage = tr("No documents matching \"%1\" could be found.\nRebuilding the project might help.").arg(uicedName); return false; } QDesignerFormWindowInterface *fwi = FormEditorW::activeWidgetHost()->formWindow(); const QString uiClass = uiClassName(fwi->mainContainer()->objectName()); if (Designer::Constants::Internal::debug) qDebug() << "Checking docs for " << uiClass; // Find the class definition (ui class defined as member or base class) // in the file itself or in the directly included files (order 1). QString namespaceName; const Class *cl = 0; Document::Ptr doc; for (const Document::Ptr &d : qAsConst(docMap)) { LookupContext context(d, docTable); const ClassDocumentPtrPair cd = findClassRecursively(context, uiClass, 1u , &namespaceName); if (cd.first) { cl = cd.first; doc = cd.second; break; } } if (!cl) { *errorMessage = msgClassNotFound(uiClass, docList); return false; } Overview o; const QString className = namespaceName + o.prettyName(cl->name()); if (Designer::Constants::Internal::debug) qDebug() << "Found class " << className << doc->fileName(); const QString functionName = "on_" + objectName + '_' + signalSignature; const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames); if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << "Found " << uiClass << doc->fileName() << " checking " << functionName << functionNameWithParameterNames; int line = 0; Document::Ptr sourceDoc; if (Function *fun = findDeclaration(cl, functionName)) { sourceDoc = findDefinition(fun, &line); if (!sourceDoc) { // add function definition to cpp file sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line); } } else { // add function declaration to cl CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const QString fileName = doc->fileName(); getParsedDocument(fileName, workingCopy, docTable); addDeclaration(docTable, fileName, cl, functionNameWithParameterNames); // add function definition to cpp file sourceDoc = addDefinition(docTable, fileName, className, functionNameWithParameterNames, &line); } if (!sourceDoc) { *errorMessage = tr("Unable to add the method definition."); return false; } // jump to function definition, position within code Core::EditorManager::openEditorAt(sourceDoc->fileName(), line + 2, indentation); return true; }
QWidget* XletQueuesConfigure::buildConfigureQueueList(QWidget *parent) { QWidget *root = new QWidget(parent); QGridLayout *layout = new QGridLayout(root); root->setLayout(layout); layout->addWidget(new QLabel(tr("Queue"), root), 0, 0, Qt::AlignLeft); QLabel *label_qos = new QLabel(tr("Qos - X (s)"), root); label_qos->setToolTip(tr( "This is the threshold in seconds to consider that the answer to a " "call was too late to be accounted as an answer of quality.")); layout->addWidget(label_qos, 0, 1, Qt::AlignLeft); QLabel *label_window = new QLabel(tr("Window (s)"), root); label_window->setToolTip(tr( "The window is the period of time used to compute the statistics")); layout->addWidget(label_window, 0, 2, Qt::AlignLeft); QCheckBox *displayQueue; QSpinBox *spinBox; int row; int column; QVariantMap statConfig = b_engine->getConfig("guioptions.queuespanel").toMap(); QString xqueueid; row = 1; QHashIterator<QString, XInfo *> i = \ QHashIterator<QString, XInfo *>(b_engine->iterover("queues")); while (i.hasNext()) { column = 0; i.next(); QueueInfo * queueinfo = (QueueInfo *) i.value(); xqueueid = queueinfo->xid(); displayQueue = new QCheckBox(queueinfo->queueName(), root); displayQueue->setProperty("xqueueid", xqueueid); displayQueue->setProperty("param", "visible"); displayQueue->setChecked(statConfig.value("visible" + xqueueid, true).toBool()); layout->addWidget(displayQueue, row, column++); connect(displayQueue, SIGNAL(stateChanged(int)), this, SLOT(changeQueueStatParam(int))); spinBox = new QSpinBox(root); spinBox->setAlignment(Qt::AlignCenter); spinBox->setMaximum(240); spinBox->setProperty("xqueueid", xqueueid); spinBox->setProperty("param", "xqos"); spinBox->setValue(statConfig.value("xqos" + xqueueid, 60).toInt()); layout->addWidget(spinBox, row, column++); connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(changeQueueStatParam(int))); spinBox = new QSpinBox(root); spinBox->setAlignment(Qt::AlignCenter); spinBox->setMaximum(3600*3); spinBox->setProperty("xqueueid", xqueueid); spinBox->setProperty("param", "window"); spinBox->setValue(statConfig.value("window" + xqueueid, 3600).toInt()); layout->addWidget(spinBox, row, column++); connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(changeQueueStatParam(int))); row++; } return root; }
/** * @brief StatUtil::_calSumValue * 计算将各个科目下的各个币种合计后的余额及其方向 * @param isPre true:期初,false:期末 * @param isfst true:一级科目,false:二级科目 */ void StatUtil::_calSumValue(bool isPre, bool isfst) { QHash<int,Double> *vs,*vms,*sumvs; //未合计前的值表(其中:vs为原币值表,vms为本币值表),合计后的值表 QHash<int,MoneyDirection> *ds,*sumds; //未合计前的方向表,合计后的方向表 if(isPre){ if(isfst){ vs = &preFExa; vms= &preFExaM; ds = &preFDir; sumvs = &sumPreFV; sumds = &sumPreFD; } else{ vs = &preSExa; vms= &preSExaM; ds = &preSDir; sumvs = &sumPreSV; sumds = &sumPreSD; } } else{ if(isfst){ vs = &endFExa; vms= &endFExaM; ds = &endFDir; sumvs = &sumEndFV; sumds = &sumEndFD; } else{ vs = &endSExa; vms= &endSExaM; ds = &endSDir; sumvs = &sumEndSV; sumds = &sumEndSD; } } //基本思路是借方 - 贷方,并根据差值的符号来判断余额方向 QHashIterator<int,Double>* it = new QHashIterator<int,Double>(*vs); int mt,sid; int mmt = masterMt->code(); Double v; while(it->hasNext()){ it->next(); sid = it->key()/10; if(sid == 0) continue; mt = it->key()%10; if(mt == mmt) v = it->value(); else v = vms->value(it->key()); if(ds->value(it->key()) == MDIR_P){ if(sumvs->contains(sid)) continue; else (*sumvs)[sid] = 0; } else if(ds->value(it->key()) == MDIR_J) (*sumvs)[sid] += v; else (*sumvs)[sid] -= v; } bool isIn ; //是否是损益类凭证的收入类科目 bool isFei; //是否是损益类凭证的费用类科目 FirstSubject* fsub; SecondSubject* ssub; it = new QHashIterator<int,Double>(*sumvs); while(it->hasNext()){ it->next(); sid = it->key(); if(isfst){ fsub = smg->getFstSubject(sid); if(!fsub) LOG_ERROR(QString("Null point exception! When request FirstSubject object point from sid=%1").arg(sid)); ssub = NULL; } else{ ssub = smg->getSndSubject(sid); if(!ssub) LOG_ERROR(QString("Null point exception! When request SecondSubject object point from sid=%1").arg(sid)); fsub = ssub->getParent(); } if(it->value() == 0) (*sumds)[sid] = MDIR_P; else if(it->value() > 0){ isIn = (smg->isSySubject(fsub->getId()) && !fsub->getJdDir()); //如果是收入类科目,要将它固定为贷方 if(isIn){ (*sumvs)[sid].changeSign(); (*sumds)[sid] = MDIR_D; } else{ (*sumds)[sid] = MDIR_J; } } else{ isFei = (smg->isSySubject(fsub->getId()) && fsub->getJdDir()); //如果是费用类科目,要将它固定为借方 if(isFei){ (*sumds)[sid] = MDIR_J; //为什么不需要更改金额符号,是因为对于一般的科目是根据符号来判断科目的余额方向 //但对费用类科目,我们认为即使是负数也将其定为借方(因为运算法则是借方-贷方,方向仍为借方) //sumsR[id].changeSign(); } else{ (*sumvs)[sid].changeSign(); (*sumds)[sid] = MDIR_D; } } } }
/** * @brief StatUtil::_calEndExtra * @param isFst true:统计的是一级科目,false:二级科目 */ void StatUtil::_calEndExtra(bool isFst) { //期末余额的计算及其方向的确定: //要遵循的基本原则: //(1)同向计算,即只有在方向相同的情况下,才进行金额的加减计算,否则在计算前要进行调整 //(2)始终用“借方-贷方”后所得差额值的符号,来确定方向 //(3)只有当涉及到外币项目时,才进行本币值的计算 //变量命名约定(p:期初,v:金额,j:借方,d:贷方或方向,c:本期发生,e:期末,M:本币值) QHash<int,Double> *pvs,*pvMs,*cjvs,*cjMvs,*cdvs,*cdMvs,*evs,*evMs; QHash<int, MoneyDirection> *pds,*eds; if(isFst){ pvs = &preFExa; pvMs = &preFExaM; pds = &preFDir; cjvs = &curJF; cjMvs = &curJFM; cdvs = &curDF; cdMvs = &curDFM; evs = &endFExa; evMs = &endFExaM; eds = &endFDir; } else{ pvs = &preSExa; pvMs = &preSExaM; pds = &preSDir; cjvs = &curJS; cjMvs = &curJSM; cdvs = &curDS; cdMvs = &curDSM; evs = &endSExa; evMs = &endSExaM; eds = &endSDir; } // evs->clear(); eds->clear(); evMs->clear(); Double vp,vm; //原币金额、本币金额 MoneyDirection dir; int sid,key,mt; int mmt = masterMt->code(); QHashIterator<int,Double> it(*cjvs); while(it.hasNext()){ it.next(); key = it.key(); sid = key/10; mt = key%10; vp = cjvs->value(key) - cdvs->value(key); if(mt != mmt) vm = cjMvs->value(key) - cdMvs->value(key); if(vp > 0) dir = MDIR_J; else if(vp < 0){ dir = MDIR_D; vp.changeSign(); vm.changeSign(); } else if(vp==0 && vm!=0){ //这发生在结转汇兑损益的情况,原币不变本币变 if(vm > 0) dir = MDIR_J; else{ dir = MDIR_D; vm.changeSign(); } } else dir = MDIR_P; if(dir == MDIR_P){ //本期借贷相抵(平),则余额值和方向同期初 (*evs)[key] = pvs->value(key); (*eds)[key] = pds->value(key); if(mt != mmt){ (*evMs)[key] = pvMs->value(key)+vm; //if(isFst) // evRs[key] = pvRs.value(key); //else // endSExaR = preSExaR; } } else if(pds->value(key) == dir){ //本期发生额借贷方向与期初相同,则直接加到同一方向 (*evs)[key] = pvs->value(key) + vp; (*eds)[key] = pds->value(key); if(mt != mmt){ (*evMs)[key] = pvMs->value(key) + vm; //if(isFst) // endFExaR = preFExaR + vm; //else // endSExaR = preSExaR + vm; } } else{ Double tvp,tvm; bool isInSub; //始终用借方去减贷方,如果值为正,则余额在借方,值为负,则余额在贷方 if(dir == MDIR_J){ tvp = vp - pvs->value(key); //借方(当前发生借贷相抵后) - 贷方(期初余额) if(mt != mmt){ tvm = vm - pvMs->value(key); //if(isFst) // tvm = vm - preFExaR; //else // tvm = vm -preSExaR; } } else{ tvp = pvs->value(key) - vp; //借方(期初余额) - 贷方(当前发生借贷相抵后) if(mt != mmt){ tvm = pvMs->value(key) - vm; //if(isFst) // tvm = preFExaR - vm; //else // tvm = preSExaR - vm; } } if(tvp > 0){ //余额在借方 //如果是收入类科目,要将它固定为贷方 if(smg->isSyClsSubject(sid,isInSub,isFst) && isInSub){ tvp.changeSign(); (*evs)[key] = tvp; (*eds)[key] = MDIR_D; } else{ (*evs)[key] = tvp; (*eds)[key] = MDIR_J; if(mt != mmt){ (*evMs)[key] = tvm; //if(isFst) // endFExaR[key] = tvm; //else // endSExaR[key] = tvm; } } } else if(tvp < 0){ //余额在贷方 //如果是费用类科目,要将它固定为借方 if(smg->isSyClsSubject(sid,isInSub,isFst) && !isInSub){ (*evs)[key] = tvp; (*eds)[key] = MDIR_J; } else{ tvp.changeSign(); tvm.changeSign(); (*evs)[key] = tvp; (*eds)[key] = MDIR_D; if(mt != mmt){ (*evMs)[key] = tvm; //if(isFst) // endFExaR[key] = tvm; //else // endSExaR[key] = tvm; } } } else{ (*evs)[key] = 0; (*eds)[key] = MDIR_P; if(mt != mmt){ (*evMs)[key] = tvm; //if(isFst) // endFExaR[key] = tvm; //因为原币余额为0,并不意味着本币余额也为0 //else // endSExaR[key] = tvm; } } } } //if(!isFst) // qDebug()<<QString("StatUtil::_calEndExtra===> %1").arg(evMs->value(1122).toString()); //将存在期初值但本期未发生的科目余额拷贝到期末余额 QHashIterator<int,Double>* ip = new QHashIterator<int,Double>(*pvs); while(ip->hasNext()){ ip->next(); int key = ip->key(); int mt = key%10; if(!evs->contains(key)){ (*evs)[key] = pvs->value(key); (*eds)[key] = pds->value(key); if(mt != mmt) (*evMs)[key] = pvMs->value(key); } } //查找并剔除那些外币的原币余额为0,但其本币值不为0的值项 ip = new QHashIterator<int,Double>(*evMs); Double v; while(ip->hasNext()){ ip->next(); v = ip->value(); if(v != 0 && evs->value(ip->key()) == 0){ //(*evMs)[ip->key()] = 0; //2015-7-15,以前为何要将其清零?,发现可以保存此值,但期初读取时没有读取到 QString subName; int sid = ip->key()/10; if(isFst) subName = smg->getFstSubject(sid)->getName(); else{ SecondSubject* ssub = smg->getSndSubject(sid); subName = QString("%1-%2").arg(ssub->getParent()->getName()).arg(ssub->getName()); } if(!isFst){ Money* mt = account->getAllMoneys().value(ip->key()%10); QString info = tr("科目“%1”的%2的原币余额为0,但本币余额是:%3,需要在结转汇兑损益凭证中将其清零!") .arg(subName).arg(mt->name()).arg(v.toString2()); QMessageBox::warning(0,tr("余额误差"),info); LOG_WARNING(tr("%1(sid=%2) 外币余额本币值误差:%3").arg(subName).arg(sid).arg(v.toString2())); } } } }
const QList<PlastiQCandidateMethod> PlastiQMetaObject::candidates(const QByteArray &name, int argc, PlastiQMethod::Type type, PlastiQMethod::Access filter, bool ignoreCase) const { #ifdef PQDEBUG PQDBG_LVL_START(__FUNCTION__); PQDBGLPUP(QString("PlastiQMetaObject::d.className = %1").arg(d.className)); PQDBGLPUP(QString("find candidates for `%1`").arg(name.constData())); #endif QList<PlastiQCandidateMethod> candidateList; const PlastiQMetaObject *m = this; int offset = 0; bool maxArgs = argc == -1; QByteArray lowerName = name.toLower(); do { QHashIterator<QByteArray, PlastiQMethod> *i; const QHash<QByteArray, PlastiQMethod> *hash; switch(type) { case PlastiQMethod::Method: i = new QHashIterator<QByteArray, PlastiQMethod>(*(m->d.pq_methods)); hash = m->d.pq_methods; break; case PlastiQMethod::Constructor: i = new QHashIterator<QByteArray, PlastiQMethod>(*(m->d.pq_constructors)); hash = m->d.pq_constructors; break; case PlastiQMethod::Signal: i = new QHashIterator<QByteArray, PlastiQMethod>(*(m->d.pq_signals)); hash = m->d.pq_signals; break; default: PQDBG_LVL_DONE(); return candidateList; } while(i->hasNext()) { i->next(); if(ignoreCase) { if(i->value().name.toLower() != lowerName) continue; } else { if(i->value().name != name) continue; } int idx = i->key().indexOf("("); QString methodSignature = i->key().mid(idx + 1, i->key().size() - idx - 2); QStringList argTypes = methodSignature.split(","); int candidateArgc = methodSignature.length() ? argTypes.size() : 0; if(type == PlastiQMethod::Signal && maxArgs) { if(argc < candidateArgc) { argc = candidateArgc; candidateList.clear(); candidateList.append({ i->value().name, argc, argTypes, i->value().index + offset }); continue; } } else { if(!maxArgs && candidateArgc != argc) { continue; } } if(filter == PlastiQMethod::None || filter == i->value().access) { if(maxArgs) { if(argc < candidateArgc) { PQDBGLPUP(QString("reappend candidate: %1(%2)").arg(name.constData()).arg(methodSignature)); argc = candidateArgc; candidateList.clear(); candidateList.append({ i->value().name, argc, argTypes, i->value().index + offset }); continue; } } else { PQDBGLPUP(QString("append candidate: %1(%2)").arg(name.constData()).arg(methodSignature)); candidateList.append({ i->value().name, argc, argTypes, i->value().index + offset }); } } } if(type == PlastiQMethod::Constructor) { delete i; break; } else { offset += hash->size(); delete i; } } while(m = m->d.superdata); PQDBG_LVL_DONE(); return candidateList; }
void PerspectiveView::glPass(GLResourceContext &ctx) { glEnable(GL_DEPTH_TEST); QMatrix4x4 cameraProjM = _camera->getProjMatrix(width(), height()); QMatrix4x4 cameraViewM = _camera->getViewMatrix(width(), height()); QMatrix4x4 cameraProjViewM = cameraProjM * cameraViewM; QMatrix4x4 objToWorld; Scene* scene = Scene::activeScene(); // render each mesh QHashIterator<QString,Mesh*> meshes = scene->meshes(); while (meshes.hasNext()) { meshes.next(); Mesh* mesh = meshes.value(); // make sure a texture exists for this mesh if (!hasMeshTexture(mesh)) { std::cout << "creating mesh texture" << std::endl; QOpenGLFramebufferObject* transferFbo = ctx.transferFbo(); transferFbo->bind(); GLuint textureId; glGenTextures(1, &textureId); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureId); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glClearColor(.5,.5,.5,1); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,1,0,1,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0, 0, 256, 256); glColor3f(.8,.8,.8); glBegin(GL_QUADS); { glVertex2f(.25,.25); glVertex2f(.75,.25); glVertex2f(.75,.75); glVertex2f(.25,.75); } glEnd(); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 256, 256, 0); transferFbo->release(); //glActiveTexture(GL_TEXTURE0); //QImage img("/tmp/lena.jpg"); //QImage image = QGLWidget::convertToGLFormat(img); //glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0 , image.width(), image.height(), GL_RGB, GL_UNSIGNED_BYTE, image.bits() ); glViewport(0, 0, width(), height()); setMeshTexture(mesh, textureId); } QOpenGLFramebufferObject* paintFbo = ctx.paintFbo(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, meshTexture(mesh)); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, paintFbo->texture()); glActiveTexture(GL_TEXTURE0); QGLShaderProgram* meshShader = ctx.meshShader(); meshShader->bind(); meshShader->setUniformValue("objToWorld", objToWorld); meshShader->setUniformValue("cameraPV", cameraProjViewM); meshShader->setUniformValue("paintFboWidth", PAINT_FBO_WIDTH); meshShader->setUniformValue("brushColor", _brushColor.redF(), _brushColor.greenF(), _brushColor.blueF(), 1); meshShader->setUniformValue("meshTexture", 0); meshShader->setUniformValue("paintTexture", 1); renderMesh(mesh); meshShader->release(); } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glLoadMatrixf(cameraProjM.data()); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(cameraViewM.data()); glBegin(GL_LINES); for (int i = -10; i <= 10; i++) { glVertex3f(-10, 0, i); glVertex3f(10, 0, i); } glEnd(); glDisable(GL_DEPTH_TEST); drawPaintStrokes(ctx); if (_bakePaintLayer) { bakePaintLayer(ctx); } }