Russian Qt Forum
Июль 13, 2020, 01:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1] 2 3 ... 719
1  Qt / Общие вопросы / Re: Сравнение с QVariant : Июль 12, 2020, 09:09
template<class T>
bool SameValue( const QVariant & v, const T & value )
{
   return v.canConvert<T>(value) && (v.value<T>() == value);
}
canСonvert наоборот, не нужно, требуется  float(0) != int(0)

Код:
 return (v.type() == qMetaTypeId<T>()) && (v.value<T>() == value);
Да, оно, глянул в отладчике - именно так заряжается type в setValue. Спасибо

Правда возникают мелкие непрятности - не могу свитчеваться
Код
C++ (Qt)
switch (v.type()) {
...
 
case (QVariant::Type) QMetaType::QMatrix4x4:   // Ok, такой имеется
SetUniformMatr4(name, v.value<QMatrix4x4>());
break;
 
case (QVariant::Type) QMetaType::QMatrix3x3:   // error: а Чебурашки нет :-(
SetUniformMatr3(name, v.value<QMatrix3x3>());
  break;
 
default:
Q_ASSERT(0);
break;
}
 
Ну наверно это непобедимо т.к. metaType регистрируется в runtime. Или с новыми стандартами все-таки "можна"?  Улыбающийся
2  Qt / Общие вопросы / Сравнение с QVariant : Июль 11, 2020, 08:13
Добрый день

Нарисовал так
Код
C++ (Qt)
template<class T>
bool SameValue( const QVariant & v, const T & value )
{
 QVariant v2;
 v2.setValue(value);
 return (v.type() == v2.type()) && (v.value<T>() == value);
}
 
Как-то коряво. Требуется сравнить без возможного convert. Как это лучше сделать?

Спасибо
3  Qt / OpenGL / Компоновка шейдеров : Июль 07, 2020, 13:36
Добрый день

Жил-был набор шейдеров (пары вертексеый + фрагментный). Некоторые фиксированы (т.е. грузятся один раз из файла/ресурсов на старте), но большинство создается "на лету", т.е. генерируются исходники и новый шейдер компилится. Собсно каждый хотя бы "копнувший" OpenGL создает такую/подобную байду, практически шейдерная архитектура OpenGL к этому вынуждает.

И вот потребовалось перейти на core profile 3.3. Долго я упирался, пытался отсидеться с compatibility profile - ведь, казалось бы, более новые фичи доступны через extensions. Ни фига, переползать пришлось. Как и следовало ожидать, посыпалось немало. Одна из первых проблем - не работает GL_QUADS, т.е. просто так, задав эту константу в glDrawElements, рисовать квадранглы я уже не могу.

В связи с этим в мутной среде железячников бытует мнение
Цитировать
Должны быть только треугольники
Все-таки как счастливы люди которые могут себе позволить такое решение вопроса! Для меня, однако, все по-другому
Цитировать
- Папа, тебе урезали  зарплату, значит ты будешь меньше пить?
- Нет, сынок, это ты будешь меньше кушать
Погуглив я выяснил что теперь (начиная с 3.3) для рисования квадранглов нужен геометрический шейдер, неск строк, конвертирует GL_LINES_ADJACENCY в GL_TRIANGLES_STRIP

Да, но как "увязать" этот новый шейдер с оравой уже имеющихся? Просто так добавить его везде я не могу, т.к. кроме квадранглов есть и др примитивы. Универсального геметического (для любых примитивов) увы, не существует. И при использовании геометрического я должен менять и фрагментный, теперь сидящий на выходе геометрического.

Собсно тема/вопрос чисто "архитектурный", технические детали OpenGL лишь "фон" и насколько хорошо Вы их знаете - несущественно, достаточно понимать о чем речь. Поэтому прошу не стесняться и высказываться.

Спасибо
4  Программирование / С/C++ / Re: Default constructor : Июль 06, 2020, 06:48
Совсем автоматом нельзя, надо скобочки руками писать (Member initialization.):
Понял, спасибо. Заметим что по приведенной ссылке конкретно приведенного Вами примера нет (как-то не очень хорошо документируют)
5  Программирование / С/C++ / Re: Default constructor : Июль 05, 2020, 13:53
Чтобы default сработал, надо присвоить значения в объявлении
Я это всю жизнь и деаю
Код
C++ (Qt)
struct CDrawInst {
 CDrawInst( void ) : m_material(0), m_count(0)
 {
 }
 
// data
 CMaterial * m_material;
 int m_count;
...
};
Вопрос был можно ли как-то занулять "автоматом", как делают template для указателей, int и др
6  Программирование / С/C++ / Default constructor : Июль 05, 2020, 12:09
Добрый день

Справочник открывал, но на сей раз там так много и мутно... лучше спрошу у знающих людей

Есть масса простых структур, напр
Код
C++ (Qt)
struct CDrawInst {
// data
 CMaterial * m_material;
 int m_count;
...
};
 
Единственное что мне нужно в конструкторе - прописать все такие POD члены нулями, и все. CDrawInst() = default это делает? Или это уже и так делается с новыми стандартами? Или по старинке расписывать? Это конечно нетрудно, но надо же как-то у культуре приобщаться Улыбающийся

Спасибо
7  Программирование / Общий / Re: Интрузивный список : Июль 02, 2020, 13:47
Ну, как всегда, все эти разговоры о "проектировании" и "архитектуре" свелись к банальному "какой готовый класс хапнуть" Улыбающийся

По поводу интрузивности: я ее не рекомендую, и сам бы так писать не стал. Но, имея такую дичь работающую, я не только не могу ее "раскритиковать", но даже привести хоть сколько-нибудь весомого аргумента "против". Шаблонные (в смысле избитые) решения с контейнерами явно хуже по всем статьям.

Что касается хеша/ускорения, я пришел у выводу что делать его постоянным (и куда-то поселять) не нужно, лучше латать конкретные bottlrneck'и. Получилось примерно так
Код
C++ (Qt)
Curve * GetNodeCurve( Node * node, int curveID )
{
auto * hash = CScopedCurveHash::instance();
if (hash) {
  Curve * curve = hash->GetCurve(node, curveID);  // есть в хеше ?
  if (curve) return curve;
  if (hash->HasNode(node)) return 0;  // см ниже
}
Curve * curve = GetFirstCurve(node);    
while (curve) {
  if (GetCurveID(curve) == curveID) break;
  curve = GetNextCurve(curve);
}
if (hash)
  hash->AddCurve(node, curveID, curve);
return curve;
}
 
Использование
Код
C++ (Qt)
void LoadCurves( Stream & strem, Node * node )
{
CScopedCurveHash scoped;
scoped.AddNode(node);  // добавить все имеющиеся (на данный момент)
 ... // грузим
}
По поводу HasNode и AddNode. Если поиск по паре (Node, ID) вернул 0 что это значит? (такой вообще нет или такую еще не искали?). Ну и в ф-циях Extract/Insert хеш также корректируется.

Смысл в том что в рамках какого-то фрагмента (напр LoadCurves) я могу быть уверен что юзаются лишь "хорошие" ф-ции и хеш остается достоверным, но в общем случае - нет.

Это "костыль" или нет? Лично я думаю что нет. Во всяком случае постоянное существование потенциально большого хеша проблематично. Напр объекты с большим числом curves требуют доступа по ID лишь на загрузке
8  Программирование / Общий / Re: Интрузивный список : Июнь 30, 2020, 18:13
При том, что имплементация того что вам нужно 1в1 LRU cache. LRU Cache умеет:
1. быстро искать по ключу.
2. хранит порядок элементов.
3. автоматом удаляет "старые" элементы при вставке новых.

Вам нужно 1 и 2 и не нужно 3. 3 отключается выкручиванием лимита элементов в бесконечность. 1 и 2 есть "из коробки".
Так он меняет порядок хранимых, при каждом обращении искомый становится "головой" списка

Код:
template<typename K, typename V> struct OrderedMap
{
    using List = std::list<std::pair<K, V>>;
    using iterator = List::iterator;
    std::unordered_map<K, iterator> map;
    List data;
};
Домашнее задание - не дублировать ключ два раза.
А зачем в списке хранить пару? Просто "V" (сама курва или указатель на нее). Однако привязка к контейнеру все равно есть, т.е. имея курву я должен как-то достучаться до владельца (здесь OrderedMap), и выходит этого владельца я должен иметь. Напр отлинковал (take) какие-то Curves - ну и как эту "пачку" хранить? Др словами придется все делать "от владельца" - так ли уж это выгодно?
9  Программирование / Общий / Re: Интрузивный список : Июнь 30, 2020, 17:13
Вам нужен "обычный" вытесняющий кэш (last recently used cache, LRU cache) (только с лимитом элементов выкрученным в бесконечность), реализуется через std::list+std::unordered_map (или кутешные аналоги).
Причем тут LRU кэш Непонимающий Порядок следования в UI определяется заданными правилами и/или юзером, LRU здесь не поможет

(щаз у вас правда возникнет требование вставлять в середину списка, про которое вы "забыли" упомянуть, но о5 же никакой проблемы сделать его нет, просто внешний итератор должен итерироваться по списку а не по мапе)
Не понял в чем меня хотят уличить? Улыбающийся Да, вставка/удаление обычно работают для середины списка, ну этого никто и не скрывал

..но вот эти ваши "заменить голову" уже намекают на некий бойлерплейт).
Ну да, так получается, если в Node хранить голову списка, то приходится считаться с тем что некоторые вставки/удаления могут ее изменить

В общем это всё не от хорошей жизни,
Да, это выглядит очень старомодно, архаично, наивно, примитивно и.т.п. (как хотите), хотя впрочем неизвестно какое впечатление будет производить "современный" код через четверть века. Но пока я в упор не вижу на что "современное" это поменять. Напр упоминался std::list. Тогда как, имея курву, вычеркнуть ее оттуда? Придется видимо где-то хранить (злополучный) итератор, наверно в том же хеше. На множ вставках/удалениях это заметно медленнее/затратнее чем интрузивный монстр. Ну бог с ним, это не рендер, такая скорость тоже устроит. Но выгоды-то где? Не вижу ни одной. И что делать с приведенными выше Extract/Insert ? Они вероятно будут как-то (неприятно) завязаны на контейнеры/владение. Или как ?
10  Программирование / Общий / Re: Интрузивный список : Июнь 30, 2020, 08:53
Добавьте индексацию этих Curve ::std::unordered_map< int, Curve*> curve_for_id;
Если node владеет curve, то можно ещё попробовать std::set<Curve>.
Ну какой конкретно контейнер юзать - непринципиально, мне лично больше нравится QHash. Предложенные варианты вполне возможны. Но мне не нравится что утверждается (или навязывается) отношение владения. Node владеет Curve? Да, сейчас он просто хранит голову списка (Curve кстати тоже наследник Node). Но возможны курвы которыми на данный момент никто не владеет, напр при чтении из файлв/клипборды. Или вот юзер переставил что-то в UI, нужно переупорядочить список. Сначала делается типа "take"
Код
C++ (Qt)
Curve * ExtractCurvesFromList( Curve * theCurveList, // голова списка
                                              Сurve * theCurve,    // голова извлекаемых Curve
                                              bool withChildren = true );
Возвращается новая голова списка (меняется если theCirveList == theCurve). Потом делается
Код
C++ (Qt)
Curve * InsertCurvesInList( Curve * theCurveList,  // голова списка
                                            Сurve * theCurve,    // голова вставляемых Curve
                                            Curve * theCurveBefore = 0 ); // куда вставлять (null = в конец)
При этом совершенно необязательно что theCurveList - тот самый что хранится в Node владельце.

Пусть интрузивность кака (std никогда ее не юзает), но она привлекает "самодостаточностью", напр код выше не требует никаких контейнеров. Может это плохо, тогда люди просто их не имели, вот и писали так? Не знаю, но я не вижу "достаточных оснований" сносить этот старый код, и неясно на что его менять

В самом деле, если хранить курвы в ассоциативном контейнере то как обеспечить ф-ционал take? Копировать конечно низзя. Придется делать контейнер указателей. И упорядоченность тоже надо поддерживать (в UI должны появляться в заданном порядке (обычно порядок создания), а не по ID). Нормальным стандартным решением будет std::list + QHash для поиска пошустрее. Ну я не вижу чем std::list так уж лучше, а пришивать рукав QHash все равно придется.

При вставке и удалении Curve корректируйте индексацию.
Это совсем непросто в достаточно большом проекте, сначала нужно как-то регламентировать вставки/удаления (сейчас поля next и prev просто public, и я сам их менял не раз (грязыми) руками)

Есть такая мысль: никто не заставляет хешировать все тотально и постоянно. Наоборот, bottleneck'ов немного (пока 2) и они хорошо видны. Один из них - чтение большого числа curves из файла. Сначала Node владелец создается с небольшим числом curves (ну там position, rotation и.т.п). Читается курва за курвой из потока. Сначала ID, такая уже есть у владельца? Да - читать в имеющуюся, нет - создать новую. Ну и вот эта проверка на 100K притормаживает. Может какой-нибудь "scoped" хеш ?
11  Программирование / Общий / Интрузивный список : Июнь 29, 2020, 07:10
Добрый день

Есть код "без всяких классов" написанный в незапамятные времена

Код
C++ (Qt)
Curve * GetNodeCurve( Node * node, int curveID )
{
Curve * curve = GetFirstCurve(node);    
while (curve) {
  if (GetCurveID(curve) == curveID)
   return curve;
  curve = GetNextCurve(curve);
}
return 0;
}
Ну ясно вставки/удаления выполняются быстро, можно лихо перебрасывать данные из одного Node в другой. "Расплата" - нет прямого доступа."По задаче" это вполне оправдано, во всяком случае было. Node имел ну сотку-другую curves максимум, а обычно десяток-другой, да и необходимость прямого доступа возникала относительно редко.

Но вот появилась новая фича которая для некоторых Node струячит поток этих curves, напр 100K и больше. Конечно код выше стал неприятно притормаживать. Отсюда вопросы

1) Как ускорить?

2) Стоит ли держаться за старый код/списки или все-таки принципиально правильно снести его нафиг и сделать "нормально"? (тогда как?).

Спасибо
12  Qt / OpenGL / Re: Стакан воды : Июнь 16, 2020, 06:34
Наверное не совсем то, что надо, но это стакан, правда без воды  Улыбающийся

https://www.shadertoy.com/view/4s2GDV
Да, видел там интересные, но увы, они все hard-coded, т.е. модель/специфика стакана вбита в код. Меня бы устроило напр так но видимо придется "закатать губу" Плачущий
13  Qt / OpenGL / Re: Стакан воды : Июнь 15, 2020, 07:02
Как работает карта/текстура "окружения". Считается что любая точка (что мы сейчас шейдим) стоит в центре бесконечно большой сферы/куба на котором наша текстура. Позиция объекта игнорируется, используется только вектор напр-я, он вычисляется в зависимости от использования (view, reflect, refract). Эта работает хорошо в роли sky/background, но для близлежащих объектов нет. Ведь как-то "облететь окружение" или "зайти за него" нельзя,  мы можем только находиться внутри него. Напр на картинках выше злополучная трубочка поведет себя очень странно и быстро исчезнет если облетать стакан камерой слева или справа.

В случае преломления (refract) мы не получим даже корректного sky. Ведь объект имеет по меньшей мере еще одну заднюю стенку которая тоже преломляет и которую тоже надо учитывать. А так получается что мы смотрим на небо сквозь бесконечную толщу стекла.

В общем, всю эту затею с textureCube следует признать "попыткой с негодными средствами". Какой-то разумной альтернативы не видно, а главное - не видно приличных рез-тов, хотя бы картинок, про анимацию уж молчу, дальше набросков типа выше дело не идет.

Вот тебе, бабушка, и "технология". Заставили учить встроенный язык, осваивать не маленькое API и его обертки (в том же Qt). Понимаю, если хотим задействовать технологию - ей придется овладеть, надо так надо. Но елы-палы, почему для совершенно стандартной, банальной, повседневной и.т.п. задачи данная технология никаких средств не предоставляет Непонимающий Плачущий
14  Qt / Вопросы новичков / Re: Как проверить, пуста ли EditLine? : Июнь 14, 2020, 08:21
P.S.: поясню, в файле lineed.h происходит создание класса LineEd, наследуемого от QLineEdit. Это необходимо для того, чтобы переопределить метод mousePressEvent(), для работы с событиями мыши, а именно "клика" по полю QLineEdit. "My Text" - это текст, который будет удаляться из поля LineEd при клике по полю мышкой (другой текст удаляться не будет).
Либо как посоветовал kambala метод setPlaceholderText(const QString &), минимум кода будет...
Да, это решение выглядит лучшим. Дело даже не минимуме кода, наследование в данном случае не оправдано, слишком мал добавленный ф-ционал чтобы быть классом. Если бы штатной возможности setPlaceholderText не было - лучше было добавить ее фильтром

Думаю подробно объяснил. А, вообще, по-моему, это геморрой так программировать, не зная азы C++, но за настойчивость и терпение респект  Улыбающийся
Меньше за него переживайте  Улыбающийся
15  Qt / Вопросы новичков / Re: Открытие/загрузка файла. : Июнь 12, 2020, 13:24
И какие функции там использовать, их довольно много.
Может еще и мамину сисю дать? Не пытайтесь "на шару", читайте букварь
Страниц: [1] 2 3 ... 719

Страница сгенерирована за 0.23 секунд. Запросов: 23.