Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [qt] вывод текста в OpenGL


Автор: gordmiand 10.3.2010, 11:49
Каким образом (какой исп-ся метод?) можно вывести определенный текст в заданное место OpenGL-виджета? 
В классе QGLWidget есть метод renderText:
В хидере класса объявляю данный метод:
Код

  void renderText ( int x, int y, const QString & str, const QFont & font = QFont(), int listBase = 2000 );


В cpp-шнике (в методе paintGL()):
Код

QFont shrift("Times", 10, QFont::Bold);
renderText (50, 50, "Привет", shrift,  2000 );

пишет, что undefined reference to `класс::renderText(int, int, QString const&, QFont const&, int)… так как же правильно использовать данный метод вывода текста в виджет opengl-я?

Автор: kemiisto 10.3.2010, 12:01
Цитата(gordmiand @  10.3.2010,  12:49 Найти цитируемый пост)
В хидере класса объявляю данный метод:

На кой ляд Вы чего-то там объявляете? Если Вы наследуетесь от QGLWidget то все методы предка Вам доступны в наследнике. А Вы метод  перекрываете новым объявлением, но реализации не предоставляете.

Цитата(gordmiand @  10.3.2010,  12:49 Найти цитируемый пост)
так как же правильно использовать данный метод вывода текста в виджет opengl-я? 

Сначала надо язык выучить, а потом программы писать. smile 

Автор: gordmiand 10.3.2010, 15:58
согласен - с объявлением я погорячился....теперь другая проблема:
если код
Код

    glColor3f(1,1,1);
    QFont shrift("Times", 12, QFont::Bold);
    renderText (150, 30, "HELLO", shrift,  2000 );

запускаю непосредственно из paintGL, то текст выводится (все верно), а если переношу сей код в функцию (fig_mod1) одного из классов (Mode1 - приходится делать его наследником от QGLWidget), запускаемую из того же paintGL, то вообще ничего не выводится (даже рисунок другого класса Mode2), хотя и нет ошибок – см. прилагаемую программу… ну что тут не так? А вообще вывод надписи и построения графических элементов надо запихнуть в отдельный класс Figures и вызывать эти методы в функциях классов Mode1 и Mode2… 

Автор: kemiisto 10.3.2010, 17:46
Боже!

Фуф... Я даже не знаю, с чего и начать.

gordmiand, Вы не с Delphi, случайно, переходите? Сдаётся мне, что именно так.

Что Вам известно про ООП, кроме того как расшифровывается эта аббревиатура? Правильный ответ - ничего. Я молчу, про то, что Вы не знаете С++...

Как обычно это делается. Субклассим QGLWidget:
Код

class GLWidget : public QGLWidget
{
  Q_OBJECT
  ...
  protected:
    void paintGL();
  ...
}


В методе paintGL() пишем код отрисовки.


Цитата(gordmiand @  10.3.2010,  16:58 Найти цитируемый пост)
А вообще вывод надписи и построения графических элементов надо запихнуть в отдельный класс Figures и вызывать эти методы в функциях классов Mode1 и Mode2…

Это можно сделать относительно просто. Посмотрите, например, Hello GL Example. Класс QtLogo. 

Я сейчас как раз одну приладу пишу и тоже такой подход использую. Исходники можно увидеть http://code.google.com/p/qdalton/source/browse/#hg/Sources/Render.

НО! Если Вы хотите выводить надписи с помощью renderText(), Вы должны вызвать этот метод для объекта класса QGLViewer, в котором и хотите увидеть надпись. Можно это сделать прямо в методе paintGL() этого объекта, можно куда-то передать указатель/ссылку на этот объект и там где-то через указатель/ссылку вызвать этот метод.

А Вы городите непонятно что...

Автор: gordmiand 10.3.2010, 20:45
"Субклассим QGLWidget" - и что? у меня тоже есть класс GL_wnd-потомок QGLWidget, в котором я переопределяю метод paintGL()...Вы толком скажите - почему не выводится не только текст, но и фигуры, описанные в классах Mode1 и Mode2?
По поводу renderText - подскажите тогда самый  простой способ вывода текста на gl-виджет типа QGLWidget...
и указанная ссылка на Ваши исходники - какая-то непонятная... где и что именно там выбирать?

Автор: kemiisto 10.3.2010, 23:39
Цитата(gordmiand @  10.3.2010,  21:45 Найти цитируемый пост)
у меня тоже есть класс GL_wnd-потомок QGLWidget, в котором я переопределяю метод paintGL()

Да. Есть. smile И в нём отлично работает метод renderText(), как и обещано. 

Но! Mode1 тоже на кой-то ляд унаследован от QGLWidget. И при вызове Mode1::fig_mod1() внутри GL_wnd::paintGL() происходит что-то жуткое. smile Ты закоментируй вызов и увидишь, что m2->fig_mod2() отработает вполне пристойно...

Ужасный код. Просто smile Ты ничерта не понимаешь. На кой тебе фреймы? На кой... А, делай как "знаешь"! smile 

Автор: gordmiand 11.3.2010, 00:06
у меня вообще чего-то мой же проект Proj9_03.rar  не запускается: 
"mingw32-make: No rule to make target `../Qt/2010.01/qt/mkspecs/win32-g++/qmake.conf', needed by `makefile'. Stop." наверное файл какой из проекта нечаянно удалил...да это не суть...
главное:
1. А как же мне класс Mode1  не наследовать от QGLWidget, если в методе fig_mod1() используются opengl-функции?
2.  почему при вызове Mode1::fig_mod1() внутри GL_wnd::paintGL() должно происходить что-то жуткое, а не вывод надписи HELLO и красного квадрата?
3. подскажите пож-та лучшую организацию (код) взаимодействия таких классов с учетом того, что:
класс GL_wnd является "базовым" потомком gl-виджета QGLWidget, в методе paintGL которого вызываются различные методы классов Mode1 и Mode2, фигуры в которых строятся методами из класса Figures...
4. фреймы используются в качестве виджетов-контейнеров, в которые грузятся различные формы (Form2 и Form3)...

Автор: kemiisto 11.3.2010, 00:13
gordmiand, скажите, что хотите получить в итоге. Как должно выглядеть и работать приложение?

Автор: gordmiand 11.3.2010, 00:52
 Приложение следующее (в принципе то же самое что я написал чуть выше):
- на главную MainWindow-форму (в ее пресловутые фреймы) грузятся различные формы Form2 и Form3.
- есть класс GL_wnd - он является "базовым" (и единственным?) потомком gl-виджета QGLWidget. 
-  по кнопке Режим1 (с формы Form3) в методе paintGL класса GL_wnd должны выводиться (вызываться) только  OpenGL-фигуры, описанные в классе Mode1 (см. мой метод fig_mod1()), по клику кнопки Режим2 - фигуры, описанные в классе Mode2 (см. мой метод fig_mod2()), а по кнопке Режим3 - выводится только Label с формы Form2.
Этот мой gl-виджет (указатель на экземпляр класса GL_wnd) создается и выводится (show()) в классе Form2 - см. методы show_Label и show_GLscena...
В свою очередь фигуры в методах классов Mode1 и Mode2 строятся с использованием методов из класса Figures (см. мой закомментированный указатель на экземпляр fig1 класса Figures в fig_mod1())...

 




Автор: kemiisto 11.3.2010, 00:55
gordmiand, Вам дали в Университете задание? Так? Вот его мне и перескажите!

Не надо мне набирать про фреймы и т.д. и т.п. На кой они нужны. Без них справимся.

http://forum.vingrad.ru/forum/topic-293991.html не ваш(а) одногруппник(ца)? smile 

Автор: gordmiand 11.3.2010, 01:10
ну да, в инсте...а я Вам задание в принципе и описал в предыдущем сообщении... 
а про "одногруппницу" не уверен...

Автор: kemiisto 11.3.2010, 01:12
gordmiand, если надо использовать фреймы, то я умываю руки. Я с ними не работал и не собираюсь...

Автор: gordmiand 11.3.2010, 01:16
да совершенно не обязательно их использовать...просто я через них делал... 
главное соблюсти указанную выше иерархию классов+ разобраться с выводом текста...

Автор: kemiisto 11.3.2010, 02:18
gordmiand, завтра с утра занят буду. 

Пока разберись с "каркасом" приложения.

Во-первых, не будем использовать *.ui. Это overhead для учебных примеров.
Во-вторых, у нас "хитрый"
Код
class GLWidget : public QGLWidget

Обрати внимание на private секцию
Код

private:
  enum State
  {
    State1,
    State2,
    State3
  };

  State state;

Переменную state мы используем в методе GLWidget::paintGL()
Код

  switch (state)
  {
  case State1:
    glColor3f(1.0f, 0.0f, 0.0f);
    renderText(20, 20, "State1");
    break;
  case State2:
    glColor3f(0.0f, 1.0f, 0.0f);
    renderText(20, 20, "State2");
    break;
  case State3:
    glColor3f(0.0f, 0.0f, 1.0f);
    renderText(20, 20, "State3");
    break;
  }

В зависимости от текущего состояния мы будем отрисовывать разные сценки. Пока тут только "заглушки" в виде renderText(). 

Смена состояний осуществляется через сигналы-слоты. Смотри конструктор класса Window:
Код

  connect(button1, SIGNAL(clicked()),
          glWidget, SLOT(setState1()));
  connect(button2, SIGNAL(clicked()),
          glWidget, SLOT(setState2()));
  connect(button3, SIGNAL(clicked()),
          glWidget, SLOT(setState3()));


Прежде чем мы пойдём дальше, скажи, ты понимаешь уже написанный код?

Автор: gordmiand 11.3.2010, 06:32
спасибо за уже оказанную помощь...cегодня днем все осознаю - тогда и отпишу....

но как же без ui-форм? что значит " Это overhead для учебных примеров"? тут специально и утилита для их создания есть (qt designer) - по-моему очень удобно - накидал на форму виджетов, задав тем самым добрую половину их свойств (местоположение, надпись на виджете и т.п.), а программного кода и так хватит писать....
и, хоть это и заглушки пока, напоминаю - выводить текст (renderText) напрямую в paintGL не надо (метод вывода текста - определяется в классе Figures, исп-ся в Mode1 и Mode2)...
но так в принципе все понятно (только уточните про неиспользование ui-форм)...
можно двигаться помаленьку дальше....жду Вашего ответа...спасибо!

Автор: gordmiand 11.3.2010, 11:37
kemiisto: В Вашем примере мне все понятно, но у меня более длинная цепочка классов…
Подскажите пож-та (пока без использования switch-a в paintGL) как дотянуться из метода fig_mod1 класса Mode1 до методов класса Figures???...в paintGL ничего не выводится (см. приложенную к этому сообщению прогу…) а то я совсем заплутал в этих классах – кто кого должен наследовать и т.п…спокойно подскажите пож-та …буду в очередной раз благодарен…

Автор: kemiisto 11.3.2010, 13:16
Цитата(gordmiand @  11.3.2010,  07:32 Найти цитируемый пост)
но как же без ui-форм?

Так показано же.

Цитата(gordmiand @  11.3.2010,  07:32 Найти цитируемый пост)
что значит " Это overhead для учебных примеров"?

Ну, лишние знания, типа.

Цитата(gordmiand @  11.3.2010,  07:32 Найти цитируемый пост)
тут специально и утилита для их создания есть (qt designer) - по-моему очень удобно - накидал на форму виджетов, задав тем самым добрую половину их свойств (местоположение, надпись на виджете и т.п.), а программного кода и так хватит писать....

Это же не Delphi с его Pixel Hunting'ом. Layout'ы удобно и в коде создавать.

Цитата(gordmiand @  11.3.2010,  07:32 Найти цитируемый пост)
и, хоть это и заглушки пока, напоминаю - выводить текст (renderText) напрямую в paintGL не надо (метод вывода текста - определяется в классе Figures, исп-ся в Mode1 и Mode2)...

Понял, понял.

Итак, давай тут разберёмся. Три кнопки. Каждая отвечает за разную сценку в OpenGL-виджете? 
Что такое Mode1 и Mode2?
Где Figures?

Если так уж хочеццо *.ui - сделаем.

Автор: gordmiand 11.3.2010, 16:39
Совершенно верно - каждая кнопка (№ 1 и № 2) отвечает за вывод разной сценки в OpenGL-виджет...третья кнопка - за закрытие (hide) этого opengl-виджета и вывод вместо него другого виджета (например Label).. эти сценки (то, что на них рисуется) и определяются как раз в классах Mode1 и Mode2, в которых фигуры для этих сценок строятся с использованием методов класса Figures...у меня в проекте  Proj11_03.rar  (см. выше) же все это есть - вопрос почему в paintGL ничего не выводится? посмотрите пож-та.... 

Автор: gordmiand 11.3.2010, 20:39
kemiisto : очень жду Вашего ответа почему не  работает (и конечно как это поправить?) вывод в paintGL фигуры+надписи из метода класса Mode1  (см. прогу Proj11_03.rar выше)

Автор: gordmiand 11.3.2010, 23:31
kemiisto: очень жаль, что Вы не смогли мне помочь...  smile 

Автор: gordmiand 12.3.2010, 06:27
подскажите кто знает - почему не выводится графика при вызове в paintGL метода fig_mode1 класса Mode1? (см. мою прогу Proj11_03.rar несколькими сообщениями выше)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)