Russian Qt Forum
Апрель 27, 2024, 18:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 7   Вниз
  Печать  
Автор Тема: Примеры из SuperBible под Qt 5.3  (Прочитано 68178 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Август 15, 2014, 16:33 »

Действительно задумался зафиксировать примерчики, которые я пробую переписывать под Qt из книги.

Примеры взяты с сайта http://www.openglsuperbible.com/. Он же и посвящен книге OpenGL SuperBible: Comprehensive Tutorial and Reference (6th Edition).

Для запуска примеров я использую последний Qt, на данный момент это 5.3.1. Минимально необходимый, на сколько я знаю, должен быть 5.1.
Также необходимо иметь установленные свежие драйвера для видеокарты.

Готовые проекты во вложении.

Первый пост:
Привет, друзья!
Я наконец-таки сегодня смог победить первый пример из суперкниги.
Меня интересует ваше мнение, на сколько правильно я выполнил связку OpenGL и Qt.
Местоположение точки в окне моей программы несколько отличается от того, что я запускал из примера. Но я думаю, что это будет раскрыто в следующих главах.
В моей программе нужно сильно растянуть окно, чтобы точка стала видна.

Код моего класса:
Код
C++ (Qt)
#include "singlepoint.h"
#include <QGLShader>
#include <QGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QPainter>
#include <QDebug>
 
SinglePoint::SinglePoint(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Single Point");
}
 
void SinglePoint::initializeGL()
{
   glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
   const char * vs_source =
       "#version 420 core                             \n"
       "                                              \n"
       "void main(void)                               \n"
       "{                                             \n"
       "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);   \n"
       "}                                             \n";
 
   const char * fs_source =
       "#version 420 core                             \n"
       "                                              \n"
       "out vec4 color;                               \n"
       "                                              \n"
       "void main(void)                               \n"
       "{                                             \n"
       "    color = vec4(0.0, 0.8, 1.0, 1.0);         \n"
       "}                                             \n";
   QGLShader* fs = new QGLShader(QGLShader::Fragment);
   fs->compileSourceCode(fs_source);
 
   QGLShader* vs = new QGLShader(QGLShader::Vertex);
   vs->compileSourceCode(vs_source);
 
   program = new QGLShaderProgram(this);
   program->addShader(vs);
   program->addShader(fs);
 
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->bind();
}
 
void SinglePoint::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT);
   program->bind();
   glPointSize(40.0f);
   glDrawArrays(GL_POINTS, 0, 1);
   program->release();
}
 
Код примера:
Код
C++ (Qt)
/*
* Copyright © 2012-2013 Graham Sellers
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

 
#include <sb6.h>
 
class singlepoint_app : public sb6::application
{
   void init()
   {
       static const char title[] = "OpenGL SuperBible - Single Point";
 
       sb6::application::init();
 
       memcpy(info.title, title, sizeof(title));
   }
 
   virtual void startup()
   {
       static const char * vs_source[] =
       {
           "#version 420 core                             \n"
           "                                              \n"
           "void main(void)                               \n"
           "{                                             \n"
           "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);   \n"
           "}                                             \n"
       };
 
       static const char * fs_source[] =
       {
           "#version 420 core                             \n"
           "                                              \n"
           "out vec4 color;                               \n"
           "                                              \n"
           "void main(void)                               \n"
           "{                                             \n"
           "    color = vec4(0.0, 0.8, 1.0, 1.0);         \n"
           "}                                             \n"
       };
 
       program = glCreateProgram();
       GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
       glShaderSource(fs, 1, fs_source, NULL);
       glCompileShader(fs);
 
       GLuint vs = glCreateShader(GL_VERTEX_SHADER);
       glShaderSource(vs, 1, vs_source, NULL);
       glCompileShader(vs);
 
       glAttachShader(program, vs);
       glAttachShader(program, fs);
 
       glLinkProgram(program);
 
       glGenVertexArrays(1, &vao);
       glBindVertexArray(vao);
   }
 
   virtual void render(double currentTime)
   {
       static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
       glClearBufferfv(GL_COLOR, 0, red);
 
       glUseProgram(program);
 
       glPointSize(40.0f);
 
       glDrawArrays(GL_POINTS, 0, 1);
   }
 
   virtual void shutdown()
   {
       glDeleteVertexArrays(1, &vao);
       glDeleteProgram(program);
   }
 
private:
   GLuint          program;
   GLuint          vao;
};
 
DECLARE_MAIN(singlepoint_app)
 
« Последнее редактирование: Август 18, 2014, 09:25 от __Heaven__ » Записан
8Observer8
Гость
« Ответ #1 : Август 15, 2014, 16:47 »

Вы видели пример "opengl/cube"? Мне кажется, что лучше шейдеры поместить в файлы "fshader.glsl" и "vshader.glsl" как в примере "cube". Сможете так сделать? Это очень важно, так как с примерами из самой SDK все в первую очередь знакомятся. И Qt'шникам легче будет читать SuperBible. Я тоже буду постепенно разбираться и добавлять свои переписанные примеры Улыбающийся

Тему лучше потом переименовать во что-то типа "Примеры SuperBible под 5.3". Так её можно будет развивать Улыбающийся Ну или завести потом новую Улыбающийся

Хотя с другой стороны пример близок к оригиналу по оформлению... Может две версии писать... Надо подумать. Но всё же я почти уверен, что надо максимально использовать идеи из примеров Qt

P.S Лично я не могу пока сказать "насколько правильно". Но всё же постараюсь позже высказать своё мнение Улыбающийся


--- Updata 8/20/2014 ---

Содержание темы

Примеры __Heaven__:
- Проект, который включает в себя примеры: "SimpleClear", "SimpleClear2", "Single Point", "Single Triangle"
- Moving Triangle
- Tessellated Triangle
- Tessellated Geometry Shader Triangle

Примеры в стиле CAD-приложений:
- Single Point Editor
- Single Triangle Editor
« Последнее редактирование: Август 20, 2014, 18:16 от 8Observer8 » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Август 15, 2014, 16:56 »

Да, пример с кубом видел. Не хотел себе голову лишним забивать, так как насчет работы с ресурсами опыта мало (хотя там все легко, предполагаю). Да и хотелось сохранить идентичность с книжным примером.
А так, согласен. Мухи отдельно, котлеты отдельно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Август 15, 2014, 16:58 »

Привет, друзья!
Здравствуй, дружок  Улыбающийся

В моей программе нужно сильно растянуть окно, чтобы точка стала видна.
Я не увидел установки вью (glOrtho или gluPerspective), может кто-то это делает автоматом/пулеметом, но мне об этом ничего не известно.

А шейдить будем или это в след примере(ах)?
Записан
8Observer8
Гость
« Ответ #4 : Август 15, 2014, 17:31 »

Да и хотелось сохранить идентичность с книжным примером.
В этом есть резон! Тогда вы пишите максимально приближенно к книге, а я буду - к Qt примерам. Теперь с меня SinglePoint Улыбающийся
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Август 15, 2014, 18:32 »

Игорь, функции, которые вы написали, являются устаревшими, как и glTranslate и glRotate. Балом правят матрицы. Но это я так понял.

Шейдить собираюсь. Насчет примеров пока не знаю. Но если будут, могу выложить. Вижу, тема не только мне интересна.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 15, 2014, 18:48 »

Игорь, функции, которые вы написали, являются устаревшими, как и glTranslate и glRotate. Балом правят матрицы. Но это я так понял.
Набрал в гугле  "glOrtho obsolete" - ничего не получил. Укажите источник где сказано про устарелость. И как тогда "по-новому/современному" задавать параметры камеры? (а они всегда должны быть определены). То же самое про матрицы - как же ими теперь управлять если glTranslate/glRotate устарели?

Возможно есть смысл сформулировать hardware границу где начинается "все новое на шейдерах". Напр на скромной карте (OpenGL 1.5 или 2.0) рендер с шейдером у меня был медленнее на порядок.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Август 15, 2014, 22:59 »

Набрал в гугле  "glOrtho obsolete" - ничего не получил. Укажите источник где сказано про устарелость.
Правильнее было бы "glOrtho deprecated", имхо.
http://stackoverflow.com/questions/6573398/list-of-deprecated-opengl-functionalities
http://stackoverflow.com/questions/8453310/orthographic-projection-in-modern-opengl
И как тогда "по-новому/современному" задавать параметры камеры? (а они всегда должны быть определены). То же самое про матрицы - как же ими теперь управлять если glTranslate/glRotate устарели?
Возможно есть смысл сформулировать hardware границу где начинается "все новое на шейдерах". Напр на скромной карте (OpenGL 1.5 или 2.0) рендер с шейдером у меня был медленнее на порядок.
Я темой плохо владею и не особо хотел бы спорить на этой почве, но существует класс QMatrix4x4.
В нем есть методы rotate, scale, ortho, translate, perspective.
Все это примочки, по идеи программист может вручную задавать числа матрицы. Это дело и передаётся в opengl (не спрашивайте как, пока не готов ответить).
В суперкниге 3изд в главе 4, вроде, были прямые операции с матрицами. Они в реальности при умном подходе в разы быстрее любимых нами операций трансляции и поворота. В книге говорится, что это особо ощутимо при большом количестве объектов на сцене. Очень советую прочитать эту главу про матричные операции, если еще не читали
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #8 : Август 15, 2014, 23:19 »

Кстати, добавление glViewport исправило ситуацию с положением точки. Она теперь в центре окна.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #9 : Август 16, 2014, 00:17 »

В примере чего-то не хватает. У меня точка вырисовывается белым цветом, а не голубым. А под ubuntu вообще красный экран и всё.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Август 16, 2014, 12:30 »

Ага, вот
Цитировать
In general, you do not compute matrices in shaders. You compute them on the CPU and upload them as uniforms to the shaders. So your vertex shader would neither know nor care if it is for an orthographic projection or a perspective one. It just transforms by whatever projection matrix it is given.
Т.е. теперь это перенесли в вертексный шейдер. Ну хозяин-барин, переживем

Я темой плохо владею и не особо хотел бы спорить на этой почве, но существует класс QMatrix4x4.
В нем есть методы rotate, scale, ortho, translate, perspective.
Все это примочки, по идеи программист может вручную задавать числа матрицы. Это дело и передаётся в opengl (не спрашивайте как, пока не готов ответить).
Сегодня посмотрел, это есть а примере hellogl_es2

В суперкниге 3изд в главе 4, вроде, были прямые операции с матрицами. Они в реальности при умном подходе в разы быстрее любимых нами операций трансляции и поворота. В книге говорится, что это особо ощутимо при большом количестве объектов на сцене. Очень советую прочитать эту главу про матричные операции, если еще не читали
Прямо не знаю что и ответить Улыбающийся Давайте лучше расскажу как я это понимаю. Матричное преобразование применяется 1 раз к каждому вертексу, поэтому его доля (во времени рендера) ничтожна. Не существует каких-то мифических быстрых/медленных матриц, там все одинаково уже сотни лет. Перспективное преобразование не матричное (и не "аффинное"), оно применяется отдельно, после матричного, его параметры просто хранят в  4-м столбце который не используется. Все это - для любого рендера (не только OpenGL)
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #11 : Август 16, 2014, 12:58 »

Я именно hellogles и разбирал, чтобы написать это.

Игорь, видимо вы меня не правильно поняли. Представьте, что у нас текущая система координат в ноле и повернута по х на 45 градусов. Чтобы сдвинуть ее вверх на 1 необходимо повернуть ее по х на -45 или запросить единичную матрицу, сдвинуть вверх на 1, повернуть на 45 градусов по х.

Что мы имеем: 3 преобразования с матрицами с использованием именно процессора.
Использование нынешнего opengl для данного примера предлагает следующую операцию: в 13 элемент матрицы записать 1. Все! Операция с 1 членом, а не с целой матрицей и в одно действие. А если таких преобразований на сцене 100500?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Август 16, 2014, 13:58 »

Представьте, что у нас текущая система координат в ноле и повернута по х на 45 градусов. Чтобы сдвинуть ее вверх на 1 необходимо повернуть ее по х на -45 или запросить единичную матрицу, сдвинуть вверх на 1, повернуть на 45 градусов по х.

Что мы имеем: 3 преобразования с матрицами с использованием именно процессора.
Использование нынешнего opengl для данного примера предлагает следующую операцию: в 13 элемент матрицы записать 1. Все! Операция с 1 членом, а не с целой матрицей и в одно действие. А если таких преобразований на сцене 100500?
Этот пример работы с матрицей "вообще", он имеет к OpenGL такое же отношение как ко всему остальному. Как я создам матрицу - мое дело, могу и без всяких glRotate если (как в этом примере) выходит короче. Но в любом случае ее надо отдать в OpenGL. Возможно Вы имели ввиду что установка переменной в шейдере быстрее чем вызов glXXX. Даже если это так (в чем я не уверен) - никакой оптимизации это не даст. Установка матрицы выполняется перед рендером каждого объекта (точнее перед засылкой его на карту). И там еще много чего надо делать - одна установка материала чего стоит. А если мы уже в шейдере - зачем нам менять матрицу? (да и вряд ли нам там позволят это сделать).

Ладно, просто "сейчас надо делать так (через шейдер)" - ну надо так надо, я к этому спокойно отношусь. Что там у Вас дальше по плану - а то что-то долго с точкой возимся  Улыбающийся 
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #13 : Август 16, 2014, 14:11 »

Ну да, матрица передается в gl в виде вектора из 16 значений. На сколько я понимаю, матрица проектирования оперируется (наверное перемножается) с матрицей модели. Получаем результирующую матрицу. Далее эта матрица передается opengl. Она, в свою очередь перемножает эту матрицу на каждую координату из шейдера.
Да, мне потребовалась немало времени, чтобы сделать эту точку. Далее буду смотреть, что там предлагается в книге - будет еще повод для обсуждений Улыбающийся
Записан
8Observer8
Гость
« Ответ #14 : Август 16, 2014, 14:45 »

Да, мне потребовалась немало времени, чтобы сделать эту точку.
Опишите, пожалуйста, в чём была проблема?
В примере чего-то не хватает. У меня точка вырисовывается белым цветом, а не голубым. А под ubuntu вообще красный экран и всё.

Тема закончится, когда будет в общем доступе текущий код примера без недостатков Улыбающийся
Записан
Страниц: [1] 2 3 ... 7   Вверх
  Печать  
 
Перейти в:  


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