Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: __Heaven__ от Август 15, 2014, 16:33



Название: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 15, 2014, 16:33
Действительно задумался зафиксировать примерчики, которые я пробую переписывать под Qt из книги.

Примеры взяты с сайта http://www.openglsuperbible.com/ (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)
 


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 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" (http://www.prog.org.ru/index.php?topic=27475.msg199283#msg199283)
- Moving Triangle (http://www.prog.org.ru/index.php?topic=27475.msg199394#msg199394)
- Tessellated Triangle (http://www.prog.org.ru/index.php?topic=27475.msg199469#msg199469)
- Tessellated Geometry Shader Triangle (http://www.prog.org.ru/index.php?topic=27475.msg199497#msg199497)

Примеры в стиле CAD-приложений:
- Single Point Editor (https://github.com/8Observer8/SinglePointEditor)
- Single Triangle Editor (https://github.com/8Observer8/SingleTriangleEditor)


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 15, 2014, 16:56
Да, пример с кубом видел. Не хотел себе голову лишним забивать, так как насчет работы с ресурсами опыта мало (хотя там все легко, предполагаю). Да и хотелось сохранить идентичность с книжным примером.
А так, согласен. Мухи отдельно, котлеты отдельно.


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: Igors от Август 15, 2014, 16:58
Привет, друзья!
Здравствуй, дружок  :)

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

А шейдить будем или это в след примере(ах)?


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 15, 2014, 17:31
Да и хотелось сохранить идентичность с книжным примером.
В этом есть резон! Тогда вы пишите максимально приближенно к книге, а я буду - к Qt примерам. Теперь с меня SinglePoint :)


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 15, 2014, 18:32
Игорь, функции, которые вы написали, являются устаревшими, как и glTranslate и glRotate. Балом правят матрицы. Но это я так понял.

Шейдить собираюсь. Насчет примеров пока не знаю. Но если будут, могу выложить. Вижу, тема не только мне интересна.


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: Igors от Август 15, 2014, 18:48
Игорь, функции, которые вы написали, являются устаревшими, как и glTranslate и glRotate. Балом правят матрицы. Но это я так понял.
Набрал в гугле  "glOrtho obsolete" - ничего не получил. Укажите источник где сказано про устарелость. И как тогда "по-новому/современному" задавать параметры камеры? (а они всегда должны быть определены). То же самое про матрицы - как же ими теперь управлять если glTranslate/glRotate устарели?

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


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 15, 2014, 22:59
Набрал в гугле  "glOrtho obsolete" - ничего не получил. Укажите источник где сказано про устарелость.
Правильнее было бы "glOrtho deprecated", имхо.
http://stackoverflow.com/questions/6573398/list-of-deprecated-opengl-functionalities (http://stackoverflow.com/questions/6573398/list-of-deprecated-opengl-functionalities)
http://stackoverflow.com/questions/8453310/orthographic-projection-in-modern-opengl (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, вроде, были прямые операции с матрицами. Они в реальности при умном подходе в разы быстрее любимых нами операций трансляции и поворота. В книге говорится, что это особо ощутимо при большом количестве объектов на сцене. Очень советую прочитать эту главу про матричные операции, если еще не читали


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 15, 2014, 23:19
Кстати, добавление glViewport исправило ситуацию с положением точки. Она теперь в центре окна.


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 16, 2014, 00:17
В примере чего-то не хватает. У меня точка вырисовывается белым цветом, а не голубым. А под ubuntu вообще красный экран и всё.


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: Igors от Август 16, 2014, 12:30
http://stackoverflow.com/questions/6573398/list-of-deprecated-opengl-functionalities (http://stackoverflow.com/questions/6573398/list-of-deprecated-opengl-functionalities)
http://stackoverflow.com/questions/8453310/orthographic-projection-in-modern-opengl (http://stackoverflow.com/questions/8453310/orthographic-projection-in-modern-opengl)
Ага, вот
Цитировать
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)


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 16, 2014, 12:58
Я именно hellogles и разбирал, чтобы написать это.

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

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


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: Igors от Август 16, 2014, 13:58
Представьте, что у нас текущая система координат в ноле и повернута по х на 45 градусов. Чтобы сдвинуть ее вверх на 1 необходимо повернуть ее по х на -45 или запросить единичную матрицу, сдвинуть вверх на 1, повернуть на 45 градусов по х.

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

Ладно, просто "сейчас надо делать так (через шейдер)" - ну надо так надо, я к этому спокойно отношусь. Что там у Вас дальше по плану - а то что-то долго с точкой возимся  :) 


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 16, 2014, 14:11
Ну да, матрица передается в gl в виде вектора из 16 значений. На сколько я понимаю, матрица проектирования оперируется (наверное перемножается) с матрицей модели. Получаем результирующую матрицу. Далее эта матрица передается opengl. Она, в свою очередь перемножает эту матрицу на каждую координату из шейдера.
Да, мне потребовалась немало времени, чтобы сделать эту точку. Далее буду смотреть, что там предлагается в книге - будет еще повод для обсуждений :)


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 16, 2014, 14:45
Да, мне потребовалась немало времени, чтобы сделать эту точку.
Опишите, пожалуйста, в чём была проблема?
В примере чего-то не хватает. У меня точка вырисовывается белым цветом, а не голубым. А под ubuntu вообще красный экран и всё.

Тема закончится, когда будет в общем доступе текущий код примера без недостатков :)


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 16, 2014, 15:24
Основную сложность создало незнание классов Qt и что такое vao, у меня пока не отложилось.


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 17, 2014, 22:38
Под убунту удалось запустить. Дело было в том, что у меня по каким-то причинам не поддерживается новая версия opengl. Пришлось использовать строчку
Код:
"#version 130                             \n"
Точка отрисовалась голубой.


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 06:16
Под убунту удалось запустить. Дело было в том, что у меня по каким-то причинам не поддерживается новая версия opengl. Пришлось использовать строчку
Код:
"#version 130                             \n"
Точка отрисовалась голубой.

Врядли следующая информация будет для вас полезна. Но а вдруг! :) Дело в том, что я не мог запустить примеры на своём ноутбуке Asus X53S. Примеры изначально идут для Visual Studio. Для себя на память написал такую инструкцию:

Инструкция по запуску примеров из SuperBible 6-ого издания в среде Visual C++ 2010 Express Edition и на ноутбуке Asus X53S

Инструментарий:
- Ноутбук Asus X53S
- Видеокарта GeForce GT 540M CUBE 1GB
- ОС Win7
- IDE Visual C++ 2010 Express Edition

Инструкция:
- скачиваем и устанавливаем драйвера: http://www.nvidia.ru/download/driverResults.aspx/77333/ru
- скачиваем примеры: http://www.openglsuperbible.com/
- открываем "sb6.sln" в Visual C++ 2010
- кликаем правой кнопкой по какому-нибудь примеру -> выбираем "Properties"
- выбираем "Linker" -> "General" -> меняем значение поля "Enable Incremental Linking" = "No (/INCREMENTAL:NO)" -> нажимаем OK
- кликаем правой кнопкой по примеру -> выбираем "Build"
- переходим в папку, где лежит exe-файл примера
- кликаем правой кнопкой по exe-файлу и выбираем: "Run with graphics processor" -> "Change default graphics processor"
- в открывшимся окне выбираем exe-файл примера и "High-performance NVIDIA processor"


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 06:23
Если вы работаете на ноутбуке, то обратите внимание на то, что у него может быть две видеокарты. Одна мощная, а вторая слабая. Вторая используется поумолчанию (для экономии энергии)

Чтобы узнать версии OpenGL и GLSL, запустите у себя такую программу:
Код
C++ (Qt)
#include <QGLFormat>
#include <QGLWidget>
#include <QString>
#include <iostream>
#include <QApplication>
 
int main( int argc, char *argv[] )
{
   QApplication app( argc, argv );
 
   QGLFormat format;
   format.setVersion( 4, 3 );
   QGLFormat::setDefaultFormat( format );
 
   QGLWidget w;
   w.makeCurrent();
 
   QString vendor( QLatin1String( reinterpret_cast<const char*>( glGetString( GL_VENDOR ) ) ) );
   std::cout << "Vendor: " << vendor.toStdString() << std::endl;
 
   QString renderer( QLatin1String( reinterpret_cast<const char*>( glGetString( GL_RENDERER ) ) ) );
   std::cout << "Renderer: " << renderer.toStdString() << std::endl;
 
   QString versionOfGL( QLatin1String( reinterpret_cast<const char*>( glGetString( GL_VERSION ) ) ) );
   std::cout << "Version: " << versionOfGL.toStdString() << std::endl;
 
   QString versionGLSL( QLatin1String( reinterpret_cast<const char*>( glGetString( GL_SHADING_LANGUAGE_VERSION ) ) ) );
   std::cout << "GLSL: "<< versionGLSL.toStdString() << std::endl;
 
   return app.exec();
}
 


Название: Re: SinglePoint пример из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 07:18
Уверен, что эта информация кому-нибудь здесь пригодится. Нашёл такую книжку: http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=pd_bxgy_b_img_y

Нашёл через eMule: http://www.emule-project.net/home/perl/general.cgi?l=1&rm=download

Открыл eMule и в поиске набрал: OpenGL Programming Guide

Среди найденный, одна нашлась именно восьмого издания с названием файла: Addison-Wesley Professional OpenGL Programming Guide, The Official Guide to Learning OpenGL version 4.3 8th (2013).[sharethefiles.com].pdf

Исходники примеров: http://www.opengl-redbook.com/


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 09:06
Готов треугольник.

Код
C++ (Qt)
#include "singletri.h"
#include <QGLShader>
#include <QGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QPainter>
 
SingleTri::SingleTri(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Single Triangle");
}
 
void SingleTri::initializeGL()
{
   glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
   const char * vs_source =
           "#version 420 core                                                 \n"
           "                                                                  \n"
           "void main(void)                                                   \n"
           "{                                                                 \n"
           "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
           "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
           "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
           "                                                                  \n"
           "    gl_Position = vertices[gl_VertexID];                          \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();
   program->bind();
}
 
void SingleTri::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT);
   glDrawArrays(GL_TRIANGLES, 0, 3);
}
 
void SingleTri::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 

Чтобы узнать версии под убунту, достаточно ввести glxinfo | grep version

Я обнаружил, что под виндой у меня на нетбуке вырисовывается белая точка, а на рабочей станции все ок - голубая.
Помнится, была игра "Бей орков!", которую я хотел запустить на не самой хорошей видеокарте - итогом был чёрный экран со звуками. Я хочу этим сказать, что, скорее всего, версия, которую мы указываем первой строкой, непосредственно связана с железом/драйверами.
Под убунту мне удалось запустить точку, указав версию 130 (без core). Это же действие помогло покрасить белую точку на нетбуке под виндой (даже разрешили мне добавить core).

На нетбуке у меня имеется только одна видеокарта - интегрированная, соответственно, маломощная.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 09:26
Изменил первый пост и выложил примеры в нем из второй главы.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 18, 2014, 09:33
Код
C++ (Qt)
   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";
 
А почему это отображается? Ну есть переменная color, разве это какое-то predefined имя? Раньше надо было заполнить gl_FragColor. И с камерой неясно - это изометрия или перспектива?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 09:50
Игорь, это работа так называемого конвейера.
В первом приближении для отрисовки точки нам необходимо реализовать gl программу, состоящую из двух шейдеров: вершинный (в данном примере позиция) и фрагментный (цвет).
Мне кажется, что это изометрия. Думаю, что скоро смогу с уверенностью ответить на этот вопрос.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 09:51
Да, color это некий predifined


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 09:52
__Heaven__, спасибо, что продолжаете эту очень полезную тему! Хотелось бы, чтобы вашего энтузиазма хватило для всех примеров :)

Предлагаю в самом первом сообщении темы написать содержание для удобства:

Содержание
- SinglePoint (http://www.prog.org.ru/index.php?topic=27475.msg199283#msg199283)
- SingleTri (http://www.prog.org.ru/index.php?topic=27475.msg199382#msg199382)
- Moving Triangle (http://www.prog.org.ru/index.php?topic=27475.msg199394#msg199394)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 10:16
Скажу сразу, что энтузиазма на всё не хватит.
Моя цель - работа с конечно-элементной сеткой (возможно под ES).
Но, постараюсь раскрыть тему в плане связки Qt и OpenGL 4.x.
Всякие штуки как тесселяция меня пока что не интересуют, но, быть может мне когда-нибудь придется писать свой сеточный генератор и это будет необходимо для отображения поверхностей при диком увеличении. Но это только мечты.
Насчёт оглавления ещё подумаю.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 18, 2014, 10:35
Игорь, это работа так называемого конвейера.
В первом приближении для отрисовки точки нам необходимо реализовать gl программу, состоящую из двух шейдеров: вершинный (в данном примере позиция) и фрагментный (цвет).
А по-другому никогда и не было, без вертексного шейдера нельзя (даже если там ничего делать не хотел)

Да, color это некий predifined
Ну как-то это не вяжется - покажите где это написано. Может просто "последнее возвращаемое значение"? Что будет если color заменить напр на "myColor"?

Моя цель - работа с конечно-элементной сеткой (возможно под ES).
Расскажите подробнее (если хотите), может чего и посоветую

По поводу подхода - мне лично он не очень. Почему бы не взять работающий пример, вот hellogl_es2 (именно es2) и туда уже встраивать содержательную часть супер-библии? Возможно Вы хотите научиться создавать OpenGL приложение "с нуля" - в этом есть смысл, но это не очень практично.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 11:41
Да, немного обманул. Извиняюсь.
Цитировать
Next, it declares color as an output variable using the out keyword. In fragment shaders, the value of output variables will be sent to the window or screen.

По поводу моей задачи:
Как уже описывал в одной из проблем (http://www.prog.org.ru/index.php?topic=27401) (там имеется вложенный проект), имеется отливка в форме (см. литейное производство).
И отливка и форма представляют из себя набор двумерных элементов, т.н. freefaces, которые получаются путём обработки моделей, состоящих из элементов tetra4.
Отливку мне необходимо отображать одним цветом (красным), форму - другим (синим). Помимо этого на элементы нужно нанести сетку без z-fighting.
Захотел я это всё запустить на Андроид и огорчился, когда узнал, что ES не понимает, что такое glMatrix, glOrtho и т.д.

Насчёт hellogl_es2.
Я его часто перечитываю и извлекаю нужное мне. Я хочу, чтобы в программе было всё необходимое и ничего лишнего. А также разбивать проекты по главам.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 11:58
Анимируем треугольник с использованием глобальных переменных в шейдере
Код
C++ (Qt)
#include "movingtri.h"
#include <QGLShader>
#include <QGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QPainter>
#include <QTime>
#include <math.h>
#include <QVector4D>
 
MovingTri::MovingTri(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Moving Triangle");
   time = new QTime;
   time->start();
   startTimer(33);
}
 
MovingTri::~MovingTri()
{
   delete time;
}
 
void MovingTri::initializeGL()
{
   const char * vs_source =
       "#version 410 core                                                 \n"
       "                                                                  \n"
       "layout (location = 0) in vec4 offset;                             \n"
       "                                                                  \n"
       "void main(void)                                                   \n"
       "{                                                                 \n"
       "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
       "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
       "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
       "                                                                  \n"
       "    // Add 'offset' to our hard-coded vertex position             \n"
       "    gl_Position = vertices[gl_VertexID] + offset;                 \n"
       "}                                                                 \n";
   const char * fs_source =
       "#version 410 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);
   program->link();
 
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->bind();
   program->bind();
}
 
void MovingTri::paintGL()
{
   GLfloat currentTime = time->elapsed() / 1000.0f;
 
   glClearColor(sinf(currentTime) * 0.5f + 0.5f,
                cosf(currentTime) * 0.5f + 0.5f,
                0.0f, 1.0f);
   glClear(GL_COLOR_BUFFER_BIT);
 
 
   QVector4D attrib
   (
       sinf(currentTime) * 0.5f,
       cosf(currentTime) * 0.6f,
       0.0f,
       0.0f
   );
 
   program->setAttributeValue(0, attrib);
 
   glDrawArrays(GL_TRIANGLES, 0, 3);
}
 
void MovingTri::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 
void MovingTri::timerEvent(QTimerEvent *)
{
   updateGL();
}
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 13:20
А следующий пример идёт с использованием тесселяции.
А в QGLShader отсутствует такой тип...


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 13:44
Мне кажется, что надо бы в будущем проверять версию OGL driver'а и сообщать пользователю.

Запустил программу, а вместо треугольника зелёное окно и текст ошибки:
Цитировать
Starting C:\Users\Ivan\Dropbox\Qt\SuperBible_6th\downloaded\build-chapter02-Desktop_Qt_5_3_1_MinGW_32bit-Debug\debug\chapter02.exe...
QGLShader::compile(Fragment): ERROR: 0:1: '' :  Version number not supported by OGL driver
ERROR: 0:1: '' : syntax error: #version

QGLShader::compile(Vertex): ERROR: 0:1: '' :  Version number not supported by OGL driver
ERROR: 0:1: '' : syntax error: #version

getProcAddress: Unable to resolve 'glProgramParameteri'
getProcAddress: Unable to resolve 'glProgramParameteriEXT'
QGLShader::compile(Fragment): ERROR: 0:1: '' :  Version number not supported by OGL driver
ERROR: 0:1: '' : syntax error: #version

QGLShader::compile(Vertex): ERROR: 0:1: '' :  Version number not supported by OGL driver
ERROR: 0:1: '' : syntax error: #version
ERROR: 2:4: 'const 4-component vector of float' : cannot declare arrays of this qualifier
ERROR: 2:4: 'const' :  non-matching types (using implicit conversion) for const initializer  
ERROR: 2:8: 'assign' :  cannot convert from 'float' to 'Position 4-component vector of float'

getProcAddress: Unable to resolve 'glProgramParameteri'
getProcAddress: Unable to resolve 'glProgramParameteriEXT'

P.S. Я знаю, что забыл для "chapter02.exe" выставить вторую карту ноутбука.
P.S.S. Конечно ваше дело, но пихать в один проект разные примеры - не очень хорошо. Когда у меня появилось 4 окна, я чуть не обделался! Хотя... tastes differ


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 14:35
Идея в том, что разбиение примеров идёт по классам. Вы можете закомментировать .show() и получать по одному примеру на запуск


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 15:28
У вас gl_VertexID не объявлен, а всё нормально работает. Поясните, пожалуйста, как вы этот момент понимаете?

Код
C++ (Qt)
   const char * vs_source =
           "#version 420 core                                                 \n"
           "                                                                  \n"
           "void main(void)                                                   \n"
           "{                                                                 \n"
           "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
           "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
           "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
           "                                                                  \n"
           "    gl_Position = vertices[gl_VertexID];                          \n"
           "}                                                                 \n";
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 18, 2014, 16:15
У вас gl_VertexID не объявлен, а всё нормально работает. Поясните, пожалуйста, как вы этот момент понимаете?
Представьте, что glDrawArrays(GL_TRIANGLES, 0, 3) это тоже самое, что и
Код
C++ (Qt)
glBegin(GL_TRIANGLES);
   for (int gl_VertexID = 0; gl_VertexID < 3; gl_VertexID++)
       ....
glEnd();


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 18, 2014, 16:27
Видимо, внутренняя глобальная переменная. А проблемы с анализатором Qt. Всё работает. Просто подчёркивается красным:

(http://i7.pixs.ru/storage/6/1/1/281png_3473226_13465611.png)

P.S. На это можно забить


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 19, 2014, 16:22
Выяснилась одна весёлая вещь про QGLShader и QGLShaderProgram.
Цитировать
This class is obsolete
По этой причине я не нашел как внедрить тесселяцию.
chapter02 был написан именно на них, кстати, примеры из Qt тоже.
Теперь модно использовать QOpenGLShader и QOpenGLShaderProgramm.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 19, 2014, 16:42
Я имею туманное представление о тесселяции. Нашёл такое определение:
Цитировать
Тесселяция в КГА (КГА - компьютерная графика и анимация) - аппроксимация гладкой поверхности множеством элементарных треугольников или многоугольников в процессе создания представления объекта в виде проволочного каркаса

Как мне сейчас представляется, есть два способа построения каркаса объектов:
1) Редакторы типа Blender
2) Генерация внутри программы

Как увязать вместе такие вещи, как: каркас объекта из Blender'а, тесселяцию и эти классы QGLShader и QGLShaderProgram?

Если можно, буквально, пару слов, чтобы не отнимать у вас время.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 19, 2014, 17:09
Способов построения много, если совсем кратко

- стандартные поверхности (напр revolver - фигура вращения, lofter, extruder, sweeper и.т.д)
- SDS редакторы (ну типа "у зайца уши вытягивать", вроде скульпторов)
- NURBS редакторы (рулить семейством кривых)

Тесселяция ко всему этому отношения не имеет - это просто из одного треугольника (полигона) делается несколько. Простая разбивка, триангуляция. Иногда полезно, но, строго говоря, результат некорректный, что бывает очень ощутимо


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 19, 2014, 17:14
Способов построения много, если совсем кратко
Спасибо! Есть что гуглить :)

А какая связь классов QGLShader и QGLShaderProgram с тесселяцией?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 19, 2014, 18:04
вы лучше видео по тесселяции посмотрите. их много в сети, там где ландшафты рассматривают.
Запустите пример из sb6, tessellatedtri. Там тоже видна концепция


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 19, 2014, 18:15
Спасибо! Посмотрю :)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 10:25
Тесселяция
Код
C++ (Qt)
#include "tessellatedtri.h"
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
 
TessellatedTri::TessellatedTri(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Tessellated Triangle");
}
 
void TessellatedTri::initializeGL()
{
   glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
   const char * vs_source =
       "#version 420 core                                                 \n"
       "                                                                  \n"
       "void main(void)                                                   \n"
       "{                                                                 \n"
       "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
       "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
       "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
       "                                                                  \n"
       "    gl_Position = vertices[gl_VertexID];                          \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";
 
   const char * tcs_source =
       "#version 420 core                                                                 \n"
       "                                                                                  \n"
       "layout (vertices = 3) out;                                                        \n"
       "                                                                                  \n"
       "void main(void)                                                                   \n"
       "{                                                                                 \n"
       "    if (gl_InvocationID == 0)                                                     \n"
       "    {                                                                             \n"
       "        gl_TessLevelInner[0] = 5.0;                                               \n"
       "        gl_TessLevelOuter[0] = 5.0;                                               \n"
       "        gl_TessLevelOuter[1] = 5.0;                                               \n"
       "        gl_TessLevelOuter[2] = 5.0;                                               \n"
       "    }                                                                             \n"
       "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;     \n"
       "}                                                                                 \n";
 
   const char * tes_source =
       "#version 420 core                                                                 \n"
       "                                                                                  \n"
       "layout (triangles, equal_spacing, cw) in;                                         \n"
       "                                                                                  \n"
       "void main(void)                                                                   \n"
       "{                                                                                 \n"
       "    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +                       \n"
       "                  (gl_TessCoord.y * gl_in[1].gl_Position) +                       \n"
       "                  (gl_TessCoord.z * gl_in[2].gl_Position);                        \n"
       "}                                                                                 \n";
 
 
   QOpenGLShader* fs = new QOpenGLShader(QOpenGLShader::Fragment, this);
   fs->compileSourceCode(fs_source);
 
   QOpenGLShader* vs = new QOpenGLShader(QOpenGLShader::Vertex, this);
   vs->compileSourceCode(vs_source);
 
   QOpenGLShader* tcs = new QOpenGLShader(QOpenGLShader::TessellationControl, this);
   tcs->compileSourceCode(tcs_source);
 
   QOpenGLShader* tes = new QOpenGLShader(QOpenGLShader::TessellationEvaluation, this);
   tes->compileSourceCode(tes_source);
 
   program = new QOpenGLShaderProgram(this);
   program->addShader(vs);
   program->addShader(tcs);
   program->addShader(tes);
   program->addShader(fs);
   program->link();
 
   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->bind();
   program->bind();
}
 
void TessellatedTri::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT);
   glDrawArrays(GL_PATCHES, 0, 3);
}
 
void TessellatedTri::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 20, 2014, 12:41
Тесселяция
А что будет с "атрибутами" (в первую очередь с нормалями и UV) для созданных вертексов? Они интерполируются автоматычно или как?

(ну вот, опять "пока не готов ответить"  :))


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 13:28
Я с атрибутами пока не знаком. Нормали только в старом издании краем глаза затронул тему...
Вы сложные вопросы спрашиваете для данного этапа изучения.
Мне кажется, что все нормали будут перпендикулярны плоскостям вновь созданных примитивов, т.н. патчи, которым они принадлежат. Но это только предположение.

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

Кстати, заметил интересную вещь. При компиляции шейдера Qt неявно подставляет в исходники какие-то дефайны. Также при создании объекта в QtCreator на вкладке GLSL можно выбрать вершинный шейдер и фрагментный шейдер. Почему нет остальных....


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 20, 2014, 13:30
__Heaven__, в вас отличный стиль оформления примеров! Я просто добавляю ваши новые классы к вашему проекту (всё, как вы задумали). Огромное спасибо за проделанную работу :)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 20, 2014, 13:45
Пока что игры с отражениями и т.п. рассматривать не собираюсь, так как так как в КЭ моделях это не особо нужно
Нормали - это вовсе не "что-то экзотическое", а необходимые данные. Напр источники света без нормалей не имеют смысла. Хотя может быть в "КЭ моделях" и освещать ничего не надо, нарисовал люмой - и все дела :)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 13:54
Пока что игры с отражениями и т.п. рассматривать не собираюсь, так как так как в КЭ моделях это не особо нужно
Нормали - это вовсе не "что-то экзотическое", а необходимые данные. Напр источники света без нормалей не имеют смысла. Хотя может быть в "КЭ моделях" и освещать ничего не надо, нарисовал люмой - и все дела :)
Я же правильно понимаю, что при обычном рисовании треугольников через glBegin мы получаем нормали перпендикулярно поверхности примитива?
Если правильно, то получается, зачем мне менять нормали поверхностей тетраэдра, из которых состоит модель. А точнее даже треугольников, из которых состоит оболочка этой модели.
Пока что я рассматриваю OpenGL как инструмент простейшего отображения в пространстве, а не инструмент для получения красивых картинок игрового качества. Для КЭ можно вообще не использовать освещение если вы отобразите сетку поверх модели.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 13:58
Я бы даже сказал, что для отображения результатов КЭ, намного лучше отключить использование освещения!


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 14:12
__Heaven__, в вас отличный стиль оформления примеров! Я просто добавляю ваши новые классы к вашему проекту (всё, как вы задумали). Огромное спасибо за проделанную работу :)
Ну да, в том и идея. Меня раздражает иметь несколько открытых проектов. Мне легче закомментировать класс в main.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 20, 2014, 14:23
Я так понял, что это компиляция шейдеров:
Код
C++ (Qt)
   QGLShader* fs = new QGLShader(QGLShader::Fragment);
   fs->compileSourceCode(fs_source);
 
   QGLShader* vs = new QGLShader(QGLShader::Vertex);
   vs->compileSourceCode(vs_source);
 

Это добавление:
Код
C++ (Qt)
   program->addShader(vs);
   program->addShader(fs);
 

Это линковка:
Код
C++ (Qt)
program->link();
 

А это связывание:
Код
C++ (Qt)
program->bind();
 

Только я не понял, почему в некоторых примерах отсутствует линковка? Причём там, где она есть, её можно убрать, закомментировав строку: program->link(); И всё равно работает.

Вопрос совершенно несрочный. Можно пока отложить.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 20, 2014, 14:31
И без vao работает. Что это такое и зачем это надо?

Код
C++ (Qt)
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->bind();
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 20, 2014, 14:40
Я же правильно понимаю, что при обычном рисовании треугольников через glBegin мы получаем нормали перпендикулярно поверхности примитива?
Насколько я знаю, "вообще никаких нормалей не получаем", при любом рисовании, OpenGL их сам не создает. Даже если установлен flat shading (нормаль = нормали к треугольнику), все равно их надо обеспечить. А без освещения получается заливка одним цветом - и вся любовь.

Другой атрибут UV - не менее важен. Напр здесь (http://codeflow.org/entries/2010/nov/07/opengl-4-tessellation/) говорится что используются текстуры (без них смотреть будет не на что). Тогда неясно откуда он взял UV

Ладно, будет время - сам копну, скоро надо будет делать работу с "разбиением на лету"


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 20, 2014, 14:52
И без vao работает. Что это такое и зачем это надо?
vao и vbo - это штучки для засылки данных на видеокарту, чтобы они там сидели. Заслав раз можно просто их юзать снова и снова, что существенно быстрее. Иначе при каждом рисовании происходит перегонка данных CPU -> GPU


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 15:25
Если программа не слинкована перед привязкой, то это происходит автоматом.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 15:37
Оригинальные примеры без vao не работают. Предполагаю, что эта вещь тоже как-то автоматом создаётся.
Правильно ли я понимаю, что vao это тоже, что и glList?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 20, 2014, 15:53
Правильно ли я понимаю, что vao это тоже, что и glList?
Нет, gList это как бы "метафайл" который запоминает все gl вызовы и потом их можно повторить одним glCallList. Это старая техника.

Вообще спецификацию никто не отменял http://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object (http://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 20, 2014, 16:03
Прикручиваем геометрический шейдер
Код
C++ (Qt)
#include "tessellatedgstri.h"
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
 
TessellatedGsTri::TessellatedGsTri(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Tessellated Geometry Shader Triangle");
}
 
void TessellatedGsTri::initializeGL()
{
   glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
   const char * vs_source =
       "#version 420 core                                                 \n"
       "                                                                  \n"
       "void main(void)                                                   \n"
       "{                                                                 \n"
       "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
       "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
       "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
       "                                                                  \n"
       "    gl_Position = vertices[gl_VertexID];                          \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";
 
   const char * tcs_source =
       "#version 420 core                                                                 \n"
       "                                                                                  \n"
       "layout (vertices = 3) out;                                                        \n"
       "                                                                                  \n"
       "void main(void)                                                                   \n"
       "{                                                                                 \n"
       "    if (gl_InvocationID == 0)                                                     \n"
       "    {                                                                             \n"
       "        gl_TessLevelInner[0] = 5.0;                                               \n"
       "        gl_TessLevelOuter[0] = 5.0;                                               \n"
       "        gl_TessLevelOuter[1] = 5.0;                                               \n"
       "        gl_TessLevelOuter[2] = 5.0;                                               \n"
       "    }                                                                             \n"
       "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;     \n"
       "}                                                                                 \n";
 
   const char * tes_source =
       "#version 420 core                                                                 \n"
       "                                                                                  \n"
       "layout (triangles, equal_spacing, cw) in;                                         \n"
       "                                                                                  \n"
       "void main(void)                                                                   \n"
       "{                                                                                 \n"
       "    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +                       \n"
       "                  (gl_TessCoord.y * gl_in[1].gl_Position) +                       \n"
       "                  (gl_TessCoord.z * gl_in[2].gl_Position);                        \n"
       "}                                                                                 \n";
 
   static const char * gs_source =
           "#version 420 core                                                                  \n"
           "                                                                                   \n"
           "layout (triangles) in;                                                             \n"
           "layout (points, max_vertices = 3) out;                                             \n"
           "                                                                                   \n"
           "void main(void)                                                                    \n"
           "{                                                                                  \n"
           "    int i;                                                                         \n"
           "                                                                                   \n"
           "    for (i = 0; i < gl_in.length(); i++)                                           \n"
           "    {                                                                              \n"
           "        gl_Position = gl_in[i].gl_Position;                                        \n"
           "        EmitVertex();                                                              \n"
           "    }                                                                              \n"
           "}                                                                                  \n";
 
   QOpenGLShader* fs = new QOpenGLShader(QOpenGLShader::Fragment, this);
   fs->compileSourceCode(fs_source);
 
   QOpenGLShader* vs = new QOpenGLShader(QOpenGLShader::Vertex, this);
   vs->compileSourceCode(vs_source);
 
   QOpenGLShader* tcs = new QOpenGLShader(QOpenGLShader::TessellationControl, this);
   tcs->compileSourceCode(tcs_source);
 
   QOpenGLShader* tes = new QOpenGLShader(QOpenGLShader::TessellationEvaluation, this);
   tes->compileSourceCode(tes_source);
 
   QOpenGLShader* gs = new QOpenGLShader(QOpenGLShader::Geometry, this);
   gs->compileSourceCode(gs_source);
 
   program = new QOpenGLShaderProgram(this);
   program->addShader(vs);
   program->addShader(tcs);
   program->addShader(tes);
   program->addShader(gs);
   program->addShader(fs);
   program->link();
 
   glPointSize(5.0f);
 
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->bind();
   program->bind();
}
 
void TessellatedGsTri::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT);
   glDrawArrays(GL_PATCHES, 0, 3);
}
 
void TessellatedGsTri::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 20, 2014, 18:17
__Heaven__, переписываю за вами примеры. Моя навигация здесь: http://www.prog.org.ru/index.php?topic=27475.msg199288#msg199288

Делаю с стиле CAD-приложений:
(http://i.pixs.ru/storage/3/5/5/284png_8183716_13495355.png)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 21, 2014, 06:54
По-моему, это единственная книга на русском по GLSL: http://www.ozon.ru/context/detail/id/2619774/

Вот здесь можно скачать книгу и диск к книге: http://www.twirpx.com/file/1134216/

Из содержания:
(http://i7.pixs.ru/storage/6/9/5/285png_4617399_13501695.png)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 21, 2014, 07:10
Люблю книжки от Питерского БХВ. Почитаю, спасибо.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 21, 2014, 07:31
А что будет с "атрибутами" (в первую очередь с нормалями и UV) для созданных вертексов? Они интерполируются автоматычно или как?
Посмотрел, подход "сам создаешь вертекс - вот и остальное все сам создавай", а в конце-концов переменные (хранящие нормали и UV) используются во фрагментном шейдере.

Что хотелось бы видеть: реальную модель (пусть очень маленькую, хоть кубик) и отследить как проходят исходные данные через pipeline. Сейчас уязвимое место - 3 координаты высосанные из пальца(?), а что делать в общем (нормальном) случае - хз. Если нужна модель (в виде массивов в cpp) - я найду


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 21, 2014, 09:28
Я буквально только вчера в википедии узнал, что есть UV.
Боюсь, что не смогу ответить на этот вопрос. По крайней мере, пока.
Вы собираетесь работать с текстурой?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 21, 2014, 09:51
Я буквально только вчера в википедии узнал, что есть UV.
Поверьте, точно есть  :) :)

Вы собираетесь работать с текстурой?
Ну хорошо хоть не сказали "для КЭ моделей текстура не нужна!". А серьезно - любой 3D объект как минимум имеет:

- вертексы и полигоны (могут иметь цвет для каждого)
- вертексные нормали (не путать с "нормали к граням")
- UV координаты (редко но может быть неск наборов)
- материал (набор параметров + часто текстуры)

Это практический стандарт, и как бы Вы ни крутились - рано или поздно жизнь заставит все это иметь (обычно рано). Поэтому избегать этого не нужно, да и зачем, смысла нет.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 21, 2014, 10:07
Поверьте, точно есть  :) :)
Я имел в виду, "что это есть такое"
Ну хорошо хоть не сказали "для КЭ моделей текстура не нужна!".
До сих пор не пригодилась. Мне для отображения объема достаточно использовать один цвет.
Возможно, при выводе данных понадобится.
Спорить на эту тему не стану, у меня опыта маловато в этой области.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 21, 2014, 10:08
По-моему, это единственная книга на русском по GLSL: http://www.ozon.ru/context/detail/id/2619774/
Книжечка старой оказалась.
Автор пишет, что существует 2 вида шейдеров: вершинный и фрагментный, возможно в будущем добавятся ещё какие-нибудь


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 21, 2014, 14:32
Посмотрел в документации Qt. Кроме вершинного и фрагментного появилось ещё 4. И всего в нашем распоряжении:
Код
C++ (Qt)
QOpenGLShader::Vertex
QOpenGLShader::Fragment
QOpenGLShader::Geometry
QOpenGLShader::TessellationControl
QOpenGLShader::TessellationEvaluation
QOpenGLShader::Compute
 

Надеюсь, они описаны в SuperBible. Я пока в этой книге не научился ориентироваться.

В книгу Борескова тоже заглядываю. Может там за GLSL как-то схватиться можно будет.



Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 22, 2014, 11:11
Раскрашиваем фрагмент в зависимости от позиции:
Код
C++ (Qt)
#include "fragcolorfrompos.h"
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QPainter>
 
FragColorFromPos::FragColorFromPos(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Fragment color from position");
   startTimer(1000);
   interpolate = false;
}
 
void FragColorFromPos::initializeGL()
{
   glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
   const char * vs_source =
       "#version 420 core                                                          \n"
       "                                                                           \n"
       "void main(void)                                                            \n"
       "{                                                                          \n"
       "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),           \n"
       "                                   vec4(-0.25, -0.25, 0.5, 1.0),           \n"
       "                                   vec4( 0.25,  0.25, 0.5, 1.0));          \n"
       "                                                                           \n"
       "    gl_Position = vertices[gl_VertexID];                                   \n"
       "}                                                                          \n";
 
   const char * fs_source =
           "#version 420 core                                                          \n"
           "                                                                           \n"
           "out vec4 color;                                                            \n"
           "                                                                           \n"
           "void main(void)                                                            \n"
           "{                                                                          \n"
           "    color = vec4(sin(gl_FragCoord.x * 0.25) * 0.5 + 0.5,                   \n"
           "                 cos(gl_FragCoord.y * 0.25) * 0.5 + 0.5,                   \n"
           "                 sin(gl_FragCoord.x * 0.15) * cos(gl_FragCoord.y * 0.1),   \n"
           "                 1.0);                                                     \n"
           "}                                                                          \n";
   QOpenGLShader* fs = new QOpenGLShader(QOpenGLShader::Fragment);
   fs->compileSourceCode(fs_source);
 
   QOpenGLShader* vs = new QOpenGLShader(QOpenGLShader::Vertex);
   vs->compileSourceCode(vs_source);
 
   nonInterpolateProgram = new QOpenGLShaderProgram(this);
   nonInterpolateProgram->addShader(vs);
   nonInterpolateProgram->addShader(fs);
   nonInterpolateProgram->link();
 
 
   const char * vsInterpolate_source =
       "#version 420 core                                                          \n"
       "                                                                           \n"
       "out vec4 vs_color; \n"
       "void main(void)                                                            \n"
       "{                                                                          \n"
       "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),           \n"
       "                                   vec4(-0.25, -0.25, 0.5, 1.0),           \n"
       "                                   vec4( 0.25,  0.25, 0.5, 1.0));          \n"
       "    const vec4 colors[] = vec4[](vec4(1.0, 0.0, 0.0, 1.0),                 \n"
       "                                 vec4(0.0, 1.0, 0.0, 1.0),                 \n"
       "                                 vec4(0.0, 0.0, 1.0, 1.0));                \n"
       "                                                                           \n"
       "    gl_Position = vertices[gl_VertexID];                                   \n"
       "    vs_color = colors[gl_VertexID];                                        \n"
       "}                                                                          \n";
 
   const char * fsInterpolate_source =
       "#version 420 core                                                          \n"
       "                                                                           \n"
       "in vec4 vs_color;                                                          \n"
       "out vec4 color;                                                            \n"
       "                                                                           \n"
       "void main(void)                                                            \n"
       "{                                                                          \n"
       "    color = vs_color;                                                      \n"
       "}                                                                          \n";
   fs->compileSourceCode(fsInterpolate_source);
 
   vs->compileSourceCode(vsInterpolate_source);
 
 
   interpolateProgram = new QOpenGLShaderProgram(this);
   interpolateProgram->addShader(vs);
   interpolateProgram->addShader(fs);
 
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->bind();
   nonInterpolateProgram->bind();
}
 
void FragColorFromPos::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT);
   glDrawArrays(GL_TRIANGLES, 0, 3);
}
 
void FragColorFromPos::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 
void FragColorFromPos::timerEvent(QTimerEvent *)
{
   interpolate = !interpolate;
   if (interpolate)
       interpolateProgram->bind();
   else
       nonInterpolateProgram->bind();
   updateGL();
}
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 22, 2014, 11:22
Только что заметил, что имена шейдеров я перепутал (interpolate), но суть остается той же.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 22, 2014, 11:52
Красиво! Но меня GLSL вгоняет в тоску. Вообще не понимаю. Например:
1) Что это означает: "out vec4 vs_color;" Как я понял, это массив, элементы, которого это тоже массив из 4 элементов. Каждый элемент означает цвет: red, green, glue, и коэффициент альфа. И теперь этот массив цветов вершин доступен другим шейдерам с помощью ключевого слова "out". И теперь шейдер фрагментов получает его на вход "in vec4 vs_color;", инициализирует переменную "color = vs_color;" и эту переменную делает доступной для других шейдеров: "out vec4 color;" Вопрос: зачем её делают открытой, то есть выходной (out) если она без типа, а значит она служебная (глобальная), как gl_Position
2) Вот эта строчка непонятна: "gl_Position = vertices[gl_VertexID];" Получается, что справа мы получаем элемент массива. Что этот элемент из себя представляет (предполагаю, что элемент массива - это вектор координат одной из вершин)? Что такое gl_VertexID я так и не понял. Слева вообще непонятная переменная gl_Position. Где она объявлена? Что ей присваивается на самом деле?
3) Почему для координат используется 4 числа?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 22, 2014, 12:17
Я пробую изучать котроль версий, так что если кто-то желает... https://github.com/dsbabkov/sb6.git (https://github.com/dsbabkov/sb6.git)

Красиво! Но меня GLSL вгоняет в тоску. Вообще не понимаю. Например:
1) Что это означает: "out vec4 vs_color;" Как я понял, это массив, элементы, которого это тоже массив из 4 элементов. Каждый элемент означает цвет: red, green, glue, и коэффициент альфа. И теперь этот массив цветов вершин доступен другим шейдерам с помощью ключевого слова "out". И теперь шейдер фрагментов получает его на вход "in vec4 vs_color;", инициализирует переменную "color = vs_color;" и эту переменную делает доступной для других шейдеров: "out vec4 color;" Вопрос: зачем её делают открытой, то есть выходной (out) если она без типа, а значит она служебная (глобальная), как gl_Position
2) Вот эта строчка непонятна: "gl_Position = vertices[gl_VertexID];" Получается, что справа мы получаем элемент массива. Что этот элемент из себя представляет (предполагаю, что элемент массива - это вектор координат одной из вершин)? Что такое gl_VertexID я так и не понял. Слева вообще непонятная переменная gl_Position. Где она объявлена? Что ей присваивается на самом деле?
3) Почему для координат используется 4 числа?
1) vec4 это float[4]. out это вывод из вершинного шейдера во фрагментный, из фрагментного на экран (в данном примере).
Код:
out vec4 color
Переменная color не без типа и она не служебная.
2) gl_Position - служебная переменная. Её тип vec4. vertices - массив vec4
Код:
const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0)
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25,  0.25, 0.5, 1.0));
В данном случае размер массива 3 (точки). Для каждой точки определены координаты x, y, z и w.
gl_VertexID - некая служебная переменная, подвергаемая инкременту. Начало и конец задаётся с помощью
Код
C++ (Qt)
glDrawArrays(GL_TRIANGLES, 0, 3);
В данном случае от 0 инкрементируя 3 раза, то есть от 0 до 2.
3) http://stackoverflow.com/questions/2422750/in-opengl-vertex-shaders-what-is-w-and-why-do-i-divide-by-it (http://stackoverflow.com/questions/2422750/in-opengl-vertex-shaders-what-is-w-and-why-do-i-divide-by-it)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 22, 2014, 12:29
меня GLSL вгоняет в тоску. Вообще не понимаю
Не хватайтесь вы за GLSL.
Хорошие картинки для desktop можно рисовать и с устаревшими OpenGL функциями.
Рекомендую к прочтению первых четырёх-пяти глав 3его издания, что на русском языке.
Так хотя бы появится какое-то базовое представление.
Мне очень помогло. Сейчас я не знаю, как бы без этих знаний воспринимал данные примерчики.
В 6 издании, я заметил, материал как-то менее разжеван по сравнению с 3.

Далее, чувствую, пойдут умножения матриц на вектора - там точно будет тёмный лес.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 22, 2014, 13:09
Спасибо, за подробный ответ! Буду по мере сил пытаться вникать в ваши примеры и изучу первые пять глав из 3-ого издания.

1) Каковы функции шейдеров? Из книжки я, как пользователь, ничего не понял. Если я хочу сделать квартиру (для начала, без мебели) по которой я могу ходить и смотреть планировку, каковы будут функции каждого из шейдеров?
2) Можно сказать, что управление камерой можно возложить на какой-то из шейдеров?

P.S. Вот статья попалась, вроде неплохая: http://habrahabr.ru/post/206156/ (посмотрел статью, ничего непонятно, оставлю на будущее)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 22, 2014, 13:46
1) Каковы функции шейдеров? Из книжки я, как пользователь, ничего не понял. Если я хочу сделать квартиру (для начала, без мебели) по которой я могу ходить и смотреть планировку, каковы будут функции каждого из шейдеров?
2) Можно сказать, что управление камерой можно возложить на какой-то из шейдеров?

1) Функции шейдеров следуют из их названий. Вершинный заведует вершинами, фрагментный - фрагментами. Если вы хотите нарисовать коробку, предположим из прямоугольных фрагментов, то вам необходимо в вершинном шейдере задать вершины каждого прямоугольника, то есть по 4 вершины на каждый фрагмент. В коробке 6 сторон (прямоугольных фрагментов), значит коробка состоит из 6*4=24 вершин. То есть в каждом её углу имеется 3 вершины с одинаковыми координатами. Вершинный шейдер назначает координаты вершин. Далее фрагментный шейдер рисует между группами по 4 вершины так называемый GL_QUAD определённого цвета. (тут могу ошибаться)
2) как таковой камеры, наверное, в OpenGL не существует. Можно передать в вершинный шейдер матрицу преобразований, которая будет умножаться на координаты вершин в результате чего будет получена желаемая трансляция, поворот и увеличение. Грубо говоря, вы вращаете мир вокруг своего экрана.

Начните с 3 издания. Там всё это очень доступно описано.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 22, 2014, 14:05
__Heaven__, большое спасибо!


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 22, 2014, 17:03
1) Каковы функции шейдеров? Из книжки я, как пользователь, ничего не понял. Если я хочу сделать квартиру (для начала, без мебели) по которой я могу ходить и смотреть планировку, каковы будут функции каждого из шейдеров?
Для этого никакие шейдера не нужны, делаете модель и рисуете ее прозаичным glDrawElements. Располагаете в каждой комнате по лампочке. Клеите обои (текстурой). Остальное сводится к рулению камерой. Если нужно "не проходить сквозь стены" - такой пример есть в Bullet.

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

2) как таковой камеры, наверное, в OpenGL не существует.
Камера есть всегда, без нее нет рендера. Разница лишь в способе ее задания, но все ее параметры должны быть определены и не меняться в течение всего рендера.

Далее, чувствую, пойдут умножения матриц на вектора - там точно будет тёмный лес.
Ну и чего/кого там бояться?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 22, 2014, 17:13
Igors, спасибо большое за подробный ответ!


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 22, 2014, 17:21
Камера есть всегда, без нее нет рендера. Разница лишь в способе ее задания, но все ее параметры должны быть определены и не меняться в течение всего рендера.

Да, насчёт камеры я не так изъяснился.
Хочу сказать, что эта камера статична. Всякие функции типа lookAt просто модифицируют матрицу преобразований. Она же в свою очередь проворачивает вершины вокруг камеры. Создаётся иллюзия, что камера подвижна.

Ну и чего/кого там бояться?
Ну, по-первой сознание как-то отрицает материал. А в 3 издании к этому плавно все ведется.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Август 24, 2014, 12:04
Один человек посоветовал изучить:
GLSL: https://code.google.com/p/gl33lessons/wiki/Lesson02
Камера: https://code.google.com/p/gl33lessons/wiki/Lesson04

P.S. Лично я в свободное время пока изучаю "классический" OpenGL по третьему изданию СуперБиблии


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 27, 2014, 09:52
Совсем я запутался с vao и vbo...
Кто-нибудь пользовался QOpenGLContext, QSurface?
Не понимаю, на сколько необходимо использовать QOpenGLContext.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 27, 2014, 10:50
Не понимаю, на сколько необходимо использовать QOpenGLContext.
По-моему никакой необходимости в этом нет, можно спокойно действовать на уровне QGLContext


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 27, 2014, 13:06
Я никогда не использовал *Context.
Читаю справку - вижу ... Не буду говорить что.
В чём прелесть использования этого контекста. Также непонятно, как он прикручивается к моему QGLWidget.

Неясно с использованием VAO и VBO.
Правильно ли я интерпретирую, что VAO необходим для передачи данных из ОЗУ в GPU для каждого кадра, а VBO для единовременного наполнения массива в памяти видеокарты и неоднократного использования?

В следующем примере я вижу следующий код:
Код
C++ (Qt)
       glGenVertexArrays(1, &vao);
       glBindVertexArray(vao);
   .....
       glGenBuffers(1, &buffer);
       glBindBuffer(GL_ARRAY_BUFFER, buffer);
       glBufferData(GL_ARRAY_BUFFER,
                    sizeof(vertex_positions),
                    vertex_positions,
                    GL_STATIC_DRAW);
       glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
       glEnableVertexAttribArray(0);
 

Пытаюсь перевести таким образом:
Код
C++ (Qt)
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->create();
   vao->bind();
 
   QOpenGLBuffer* buffer = new QOpenGLBuffer;
   buffer->create();
   buffer->bind();
   buffer->setUsagePattern(QOpenGLBuffer::StaticDraw);
   buffer->allocate(vertex_positions, sizeof(vertex_positions));
 
   program->setAttributeBuffer(0, GL_FLOAT, 0, 3);
   program->enableAttributeArray(0);
 
Что может быть не так?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 27, 2014, 16:58
Наконец-то разобрался с летающими кубиками.

Код
C++ (Qt)
#include "spinnycube.h"
#include <QOpenGLShader>
#include <QOpenGLBuffer>
#include <QMatrix4x4>
#include <QDebug>
#include <QTime>
#include <math.h>
 
SpinnyCube::SpinnyCube(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Spinny Cube");
 
   proj_matrix = new QMatrix4x4;
   program = new QOpenGLShaderProgram;
   time = new QTime;
   many = false;
   time->start();
   startTimer(16);
}
SpinnyCube::~SpinnyCube()
{
   delete proj_matrix;
   delete time;
}
 
void SpinnyCube::initializeGL()
{
   glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
   glClearDepth(1.0f);
 
   const char * vs_source =
   {
       "#version 410 core                                                  \n"
       "                                                                   \n"
       "in vec4 position;                                                  \n"
       "                                                                   \n"
       "out VS_OUT                                                         \n"
       "{                                                                  \n"
       "    vec4 color;                                                    \n"
       "} vs_out;                                                          \n"
       "                                                                   \n"
       "uniform mat4 mv_matrix;                                            \n"
       "uniform mat4 proj_matrix;                                          \n"
       "                                                                   \n"
       "void main(void)                                                    \n"
       "{                                                                  \n"
       "    gl_Position = proj_matrix * mv_matrix * position;              \n"
       "    vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);      \n"
       "}                                                                  \n"
   };
 
   const char * fs_source =
   {
       "#version 410 core                                                  \n"
       "                                                                   \n"
       "out vec4 color;                                                    \n"
       "                                                                   \n"
       "in VS_OUT                                                          \n"
       "{                                                                  \n"
       "    vec4 color;                                                    \n"
       "} fs_in;                                                           \n"
       "                                                                   \n"
       "void main(void)                                                    \n"
       "{                                                                  \n"
       "    color = fs_in.color;                                           \n"
       "}                                                                  \n"
   };
 
   program->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_source);
   program->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_source);
   program->link();
 
   mv_location = program->uniformLocation("mv_matrix");
   proj_location = program->uniformLocation("proj_matrix");
 
//    QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
//    vao->bind();
 
   static const GLfloat vertex_positions[] =
   {
       -0.25f,  0.25f, -0.25f,
       -0.25f, -0.25f, -0.25f,
        0.25f, -0.25f, -0.25f,
 
        0.25f, -0.25f, -0.25f,
        0.25f,  0.25f, -0.25f,
       -0.25f,  0.25f, -0.25f,
 
        0.25f, -0.25f, -0.25f,
        0.25f, -0.25f,  0.25f,
        0.25f,  0.25f, -0.25f,
 
        0.25f, -0.25f,  0.25f,
        0.25f,  0.25f,  0.25f,
        0.25f,  0.25f, -0.25f,
 
        0.25f, -0.25f,  0.25f,
       -0.25f, -0.25f,  0.25f,
        0.25f,  0.25f,  0.25f,
 
       -0.25f, -0.25f,  0.25f,
       -0.25f,  0.25f,  0.25f,
        0.25f,  0.25f,  0.25f,
 
       -0.25f, -0.25f,  0.25f,
       -0.25f, -0.25f, -0.25f,
       -0.25f,  0.25f,  0.25f,
 
       -0.25f, -0.25f, -0.25f,
       -0.25f,  0.25f, -0.25f,
       -0.25f,  0.25f,  0.25f,
 
       -0.25f, -0.25f,  0.25f,
        0.25f, -0.25f,  0.25f,
        0.25f, -0.25f, -0.25f,
 
        0.25f, -0.25f, -0.25f,
       -0.25f, -0.25f, -0.25f,
       -0.25f, -0.25f,  0.25f,
 
       -0.25f,  0.25f, -0.25f,
        0.25f,  0.25f, -0.25f,
        0.25f,  0.25f,  0.25f,
 
        0.25f,  0.25f,  0.25f,
       -0.25f,  0.25f,  0.25f,
       -0.25f,  0.25f, -0.25f
   };
 
   QOpenGLBuffer* buffer = new QOpenGLBuffer;
   buffer->create();
   buffer->bind();
   buffer->allocate(vertex_positions, sizeof(vertex_positions));
   buffer->setUsagePattern(QOpenGLBuffer::StaticDraw);
 
   program->setAttributeArray(0, GL_FLOAT, NULL, 3);
   program->enableAttributeArray(0);
 
   glEnable(GL_CULL_FACE);
   glFrontFace(GL_CW);
 
   glEnable(GL_DEPTH_TEST);
   glDepthFunc(GL_LEQUAL);
 
}
 
 
void SpinnyCube::paintGL()
{
   float currentTime = time->elapsed() / 1000.0f;
 
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
   program->bind();
   program->setUniformValue(proj_location, *proj_matrix);
 
   if (many)
   {
       int i;
       for (i = 0; i < 24; i++)
       {
           float f = i + currentTime * 0.3f;
           QMatrix4x4 mv_matrix;
           mv_matrix.translate(0.0f, 0.0f, -6.0f);
           mv_matrix.rotate(currentTime * 45.0f, 0.0f, 1.0f, 0.0f);
           mv_matrix.rotate(currentTime * 21.0f, 1.0f, 0.0f, 0.0f);
           mv_matrix.translate(sinf(2.1f * f) * 2.0f,
                               cosf(1.7f * f) * 2.0f,
                               sinf(1.3f * f) * cosf(1.5f * f) * 2.0f);
           program->setUniformValue(mv_location, mv_matrix);
           glDrawArrays(GL_TRIANGLES, 0, 36);
       }
   }
   else
   {
       float f = currentTime * 0.3f;
       QMatrix4x4 mv_matrix;
       mv_matrix.translate(0.0f, 0.0f, -4.0f);
       mv_matrix.translate(sinf(2.1f * f) * 0.5f,
                           cosf(1.7f * f) * 0.5f,
                           sinf(1.3f * f) * cosf(1.5f * f) * 2.0f);
       mv_matrix.rotate(currentTime * 45.0f, 0.0f, 1.0f, 0.0f);
       mv_matrix.rotate(currentTime * 81.0f, 1.0f, 0.0f, 0.0f);
       program->setUniformValue(mv_location, mv_matrix);
       glDrawArrays(GL_TRIANGLES, 0, 36);
   }
}
 
void SpinnyCube::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
   float aspect = static_cast<float>(w) / static_cast<float>(h);
   proj_matrix->setToIdentity();
   proj_matrix->perspective(50.0f, aspect, 0.1f, 1000.0f);
}
 
void SpinnyCube::timerEvent(QTimerEvent *)
{
   if (time->elapsed() % 4000 < 2000)
       many = false;
   else
       many = true;
   updateGL();
}
 

Я не увидел установки вью (glOrtho или gluPerspective), может кто-то это делает автоматом/пулеметом, но мне об этом ничего не известно.
Теперь готов ответить))
Задаётся проекционная матрица в resizeGL. Далее передаём её в шейдер. Туда же матрицу ModelView и координаты вершины.
В шейдере делаем
Код
C++ (Qt)
gl_Position = proj_matrix * mv_matrix * position;


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Август 27, 2014, 17:02
Я никогда не использовал *Context.
Читаю справку - вижу ... Не буду говорить что.
В чём прелесть использования этого контекста. Также непонятно, как он прикручивается к моему QGLWidget.
Вы использовали контекст ВСЕГДА. "Оказывается я уже 30 лет говорю прозой"  :) Нет контекста - ничего нет. По аналогии это как QPainter для обычного рисования.

Неясно с использованием VAO и VBO.
Правильно ли я интерпретирую, что VAO необходим для передачи данных из ОЗУ в GPU для каждого кадра, а VBO для единовременного наполнения массива в памяти видеокарты и неоднократного использования?
Нет. VBO это вот
Код
C++ (Qt)
       glGenBuffers(1, &buffer);
       glBindBuffer(GL_ARRAY_BUFFER, buffer);
       glBufferData(GL_ARRAY_BUFFER,
                    sizeof(vertex_positions),
                    vertex_positions,
                    GL_STATIC_DRAW);
       glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
Но это только координаты вертексов. А есть еще нормали, текстуры, возможно цвета вертексов. И для каждого атрибута надо повторять процедуру VBO с др буфером. И перед каждым рендером надо биндить все буфера. VAO позволяет сделать бинд одним вызовом, т.е просто упрощает использование VBO. Но заполнять все данные все равно надо.

В следующем примере я вижу следующий код:
Пытаюсь перевести таким образом:
Код
C++ (Qt)
   QOpenGLVertexArrayObject* vao = new QOpenGLVertexArrayObject(this);
   vao->create();
   vao->bind();
 
   QOpenGLBuffer* buffer = new QOpenGLBuffer;
   buffer->create();
   buffer->bind();
   buffer->setUsagePattern(QOpenGLBuffer::StaticDraw);
   buffer->allocate(vertex_positions, sizeof(vertex_positions));
 
   program->setAttributeBuffer(0, GL_FLOAT, 0, 3);
   program->enableAttributeArray(0);
 
Что может быть не так?
Последние 2 строки - первый аргумент ноль, а надо
Код
C++ (Qt)
int loc = program->attributeLocation("posAttr");


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 27, 2014, 17:15
Последние 2 строки - первый аргумент ноль, а надо
Код
C++ (Qt)
int loc = program->attributeLocation("posAttr");

Я в итоге использовал 0.
Где-то краем глаза видел, что 0 играет какое-то определённое значение.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Hrundel от Август 27, 2014, 20:52
Последние 2 строки - первый аргумент ноль, а надо
Код
C++ (Qt)
int loc = program->attributeLocation("posAttr");

Я в итоге использовал 0.
Где-то краем глаза видел, что 0 играет какое-то определённое значение.

Код
C++ (Qt)
void QGLShaderProgram::setAttributeBuffer ( int location, GLenum type, int offset, int tupleSize, int stride = 0 )

Sets an array of vertex values on the attribute at location in this shader program, starting at a specific offset in the currently bound vertex buffer.
The stride indicates the number of bytes between vertices. A default stride value of zero indicates that the vertices are densely packed in the value array.

То есть - ноль указывает на то, что вертексы плотно упакованы в массиве значений. То есть - проще говоря - расстояние в байтах между вершинами отсутствует.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 27, 2014, 21:13
Мы все говорим про location = 0?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 28, 2014, 07:32
Я вот все думаю, а на сколько правильно использовать новый функционал при создании CAE приложения, а не игр.
Большинство примеров не запускается у меня на нетбуке по каким-либо причинам. В основном, потому что у меня максимальная версия OpenGL 3.0. Перелопатив шейдеры под 3.0 я, возможно, получу результат, но при этом нет гарантии, что приложение будет работать на других машинах.
В линукс, на сколько я понимаю, имеется возможность установить mesa, которая заменит OpenGL 3.0 только для intel (слава богу у меня оный), либо нужно иметь nvidia и их дрова.
Но с другой стороны, если писать программу без использования шейдеров, то её нельзя будет портировать на ES (поправьте, если ошибаюсь).
У кого какие мысли на этот счет?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Hrundel от Август 28, 2014, 23:17
Мы все говорим про location = 0?

А ты игнорируешь тексты на английском?


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Август 29, 2014, 07:34
Нет, вовсе не игнорирую. Изначально речь шла про location=0. Но, судя по тому, что вы прокомментировали часть описывающую плотность массива, вы привлекали внимание к stride=0.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Сентябрь 02, 2014, 07:28
[off]К сожалению, я выпал из обсуждения на неск дней - упыри разбомбили подстанцию, сидел без света  :'([/off]
Я вот все думаю, а на сколько правильно использовать новый функционал при создании CAE приложения, а не игр.
Большинство примеров не запускается у меня на нетбуке по каким-либо причинам. В основном, потому что у меня максимальная версия OpenGL 3.0. Перелопатив шейдеры под 3.0 я, возможно, получу результат, но при этом нет гарантии, что приложение будет работать на других машинах.
В линукс, на сколько я понимаю, имеется возможность установить mesa, которая заменит OpenGL 3.0 только для intel (слава богу у меня оный), либо нужно иметь nvidia и их дрова.
Но с другой стороны, если писать программу без использования шейдеров, то её нельзя будет портировать на ES (поправьте, если ошибаюсь).
У кого какие мысли на этот счет?
Да, все именно так. Более того, 2.0 и даже меньше у меня реально, и вопрос об игнорировании таких юзеров еще не будет стоять минимум год. При этом даже скромный шейдер заметно тормозит, обеспечиваю альтернативу вообще без шейдеров. Про "замену 3.0" не знаю, но совсем не исключено что она сведется у "софтваре эмуляции" - с ужасными тормозами.

Но "надо понимать" что рано или поздно переводить на шейдера все равно придется. Уже сейчас есть трудности  Qt+OpenGL desktop, дальше их будет больше. Поэтому предлагаю вернуться к супер-библии  :)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Сентябрь 02, 2014, 09:23
Согласен. У меня на нетбуке не поддерживается 3.3, что мешает создавать шейдеры. Точнее их можно создавать, но нужно знать все старые конструкции из поддерживаемых моим оборудованием версий. функции из 1.2 покрывают все мои требования к компьютерной графике и они поддерживаются на всех картах desktop. Но есть проблема. Невозможно портировать программу на es.
Сейчас очень здорово процветает эра планшетов. И, возможно, скоро потребуется делать софт не только под рабочую станцию, но и под переносные устройства. Например 3D визуализация результатов расчёта в виде презентации.

Думаю, на данном этапе мне нужно знать и 1.2 и 4.х. В первую очередь 1.2. Так как она больше применяется и там можно лучше разобраться с основами.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Сентябрь 02, 2014, 09:44
функции из 1.2 покрывают все мои требования к компьютерной графике и они поддерживаются на всех картах desktop.
Мои познания в OpenGL значительно скромнее ваших. У меня есть множество белых пятен. Вот одно из них. Есть такой способ  рисования с помощью glBegin()\glEnd(), который не поддерживается новыми версиями OpenGL. Какой есть универсальный способ, чтобы он гарантированно работал на всех PC (со старыми и новыми версиями OpenGL)?

Как называется следующий способ рисования? Может он универсальный и будет работать на всех PC?
Код
C++ (Qt)
   glVertexPointer(3, GL_FLOAT, 0, VertexArray);
   glTexCoordPointer(2, GL_FLOAT, 0, TextureArray);
   glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, IndexArray);
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Сентябрь 02, 2014, 13:13
Универсальный, наверное, будет такой, который описан в книжке, представленной вами за 2006 год.
Тот код, что вы представили, не поддерживается ES.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: Igors от Сентябрь 02, 2014, 13:27
Какой есть универсальный способ, чтобы он гарантированно работал на всех PC (со старыми и новыми версиями OpenGL)?
На моей памяти какого-то "универсального" OpenGL не существовало никогда, что вполне естественно вследствие его гнусной хардварной природы. Всегда были extensions которых могло не быть на какой-то карте, всегда надо было чего-то латать и.т.п. Сейчас, в связи с прорывом es/шейдеров это просто несколько усугубилось.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Сентябрь 02, 2014, 15:06
Спасибо! Стало понятнее :)

P.S. Я так понимаю, что SuperBible базируется на примерах. Я бы взялся за переписывание из третьего издания в скором времени (я думаю, OpenGL 2006 года ещё будет актуален). Но из 6-ого в этом году точно не потяну. __Heaven__, не бросайте это дело :) Это огромный вклад в сообщество :) Я перелистывал её, там такие красивые примеры во второй половине! Ну хотя бы пару примеров в месяц :) Через пару лет мне они бы очень пригодились :D


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: 8Observer8 от Сентябрь 05, 2014, 17:33
Я создал тему "Примеры из SuperBible (3-го издания) на Qt" (http://www.prog.org.ru/topic_27563_0.html)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Сентябрь 12, 2014, 15:20
Рисуем текстуру:
Код
C++ (Qt)
#ifndef SIMPLETEXTURE_H
#define SIMPLETEXTURE_H
 
#include <QGLWidget>
 
class QOpenGLShaderProgram;
class QOpenGLVertexArrayObject;
class QOpenGLTexture;
 
class SimpleTexture : public QGLWidget
{
   Q_OBJECT
public:
   explicit SimpleTexture(QWidget *parent = 0);
//    ~SimpleTexture();
 
signals:
 
public slots:
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL(int w, int h);
 
   QOpenGLShaderProgram* program;
   QOpenGLTexture* texture;
void generate_texture(float * data, int width, int height)
{
   int x, y;
 
   for (y = 0; y < height; y++)
   {
       for (x = 0; x < width; x++)
       {
           data[(y * width + x) * 4 + 0] = (float)((x & y) & 0xFF) / 255.0f;
           data[(y * width + x) * 4 + 1] = (float)((x | y) & 0xFF) / 255.0f;
           data[(y * width + x) * 4 + 2] = (float)((x ^ y) & 0xFF) / 255.0f;
           data[(y * width + x) * 4 + 3] = 1.0f;
       }
   }
}
 
};
 
#endif // SIMPLETEXTURE_H
 
Код
C++ (Qt)
#include "simpletexture.h"
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QPainter>
#include <QOpenGLTexture>
 
const char* vs_source =
   "#version 420 core                                                              \n"
   "                                                                               \n"
   "void main(void)                                                                \n"
   "{                                                                              \n"
   "    const vec4 vertices[] = vec4[](vec4( 0.75, -0.75, 0.5, 1.0),               \n"
   "                                   vec4(-0.75, -0.75, 0.5, 1.0),               \n"
   "                                   vec4( 0.75,  0.75, 0.5, 1.0));              \n"
   "                                                                               \n"
   "    gl_Position = vertices[gl_VertexID];                                       \n"
   "}                                                                              \n";
const char* fs_source =
   "#version 430 core                                                              \n"
   "                                                                               \n"
   "uniform sampler2D s;                                                           \n"
   "                                                                               \n"
   "out vec4 color;                                                                \n"
   "                                                                               \n"
   "void main(void)                                                                \n"
   "{                                                                              \n"
   "    color = texture(s, gl_FragCoord.xy / textureSize(s, 0));                   \n"
   "}                                                                              \n";
 
SimpleTexture::SimpleTexture(QWidget *parent) :
   QGLWidget(parent)
{
   setWindowTitle("Simple Texture");
   program = new QOpenGLShaderProgram(this);
   texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
}
 
//SimpleTexture::~SimpleTexture()
//{
//    delete texture;
//}
 
void SimpleTexture::initializeGL()
{
   glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
 
   texture->create();
   texture->bind();
   texture->setMipLevels(8);
   texture->setFormat(QOpenGLTexture::RGBA32F);
   texture->setSize(256, 256);
   texture->allocateStorage();
 
 
   float data[256 * 256 * 4];
   generate_texture(data, 256, 256);
 
   texture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::Float32, data);
 
   program->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_source);
   program->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_source);
   program->bind();
}
 
void SimpleTexture::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT);
   glDrawArrays(GL_TRIANGLES, 0, 3);
}
 
void SimpleTexture::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 
Только у меня почему-то деструктор не захотел линковаться. Не стал ломать голову.
(https://imagizer.imageshack.us/v2/656x518q90/909/cS1214.png)


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: vulko от Сентябрь 26, 2014, 08:37
Согласен. У меня на нетбуке не поддерживается 3.3, что мешает создавать шейдеры. Точнее их можно создавать, но нужно знать все старые конструкции из поддерживаемых моим оборудованием версий. функции из 1.2 покрывают все мои требования к компьютерной графике и они поддерживаются на всех картах desktop. Но есть проблема. Невозможно портировать программу на es.
Сейчас очень здорово процветает эра планшетов. И, возможно, скоро потребуется делать софт не только под рабочую станцию, но и под переносные устройства. Например 3D визуализация результатов расчёта в виде презентации.

Думаю, на данном этапе мне нужно знать и 1.2 и 4.х. В первую очередь 1.2. Так как она больше применяется и там можно лучше разобраться с основами.

Ну почему же нельзя. Вполне можно.
Сложность зависит от того что нужно получить в итоге.
Раз уж 1.2 покрывает потребности, скорее всего каких-то супер эффектов не требуется и обычная 3д графика в виде VBO либо объекты с натянутыми текстурами переносятся очень просто. Если есть glBegin..glEnd, нужно их перевести на VBO.
Ну и ещё нужно будет ручками перемножить матрицы и закинуть её в glFrustM вроде.

В свое время портировал на андройде gl 1.1 -> gl es 2.0. Все оказалось достаточно просто.
Шейдеры для обычных объектов сложности тоже не представляют, обычно достаточно найти где-нибудь готовый.


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Октябрь 07, 2014, 13:26
Падающие инопланетяне:

alienrain.h
Код
C++ (Qt)
#ifndef ALIENRAIN_H
#define ALIENRAIN_H
 
#include <QGLWidget>
 
class QOpenGLShaderProgram;
class QOpenGLFunctions_4_3_Compatibility;
class QTime;
class QOpenGLTexture;
class QOpenGLBuffer;
 
class AlienRain : public QGLWidget
{
Q_OBJECT
 
public:
AlienRain(QWidget *parent = 0);
~AlienRain();
 
private:
 
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void timerEvent(QTimerEvent*);
 
QOpenGLFunctions_4_3_Compatibility* ogl;
QTime* time;
   QOpenGLShaderProgram* program;
   QOpenGLTexture* texture;
   QOpenGLBuffer* buffer;
 
protected:
float           droplet_x_offset[256];
float           droplet_rot_speed[256];
float           droplet_fall_speed[256];
 
};
 
#endif // ALIENRAIN_H
 
alienrain.cpp
Код
C++ (Qt)
#include "alienrain.h"
 
#include <QOpenGLFunctions_4_3_Compatibility>
#include <qopengltexture.h>
#include <QDebug>
#include <cmath>
#include "ktx.h"
#include <qdatetime.h>
#include <QOpenGLShaderProgram>
#include <QOpenGLShader>
#include <QOpenGLTexture>
#include <QOpenGLBuffer>
 
typedef float vec4[4];
 
// Random number generator
static unsigned int seed = 0x13371337;
 
 
static inline float random_float()
{
float res;
unsigned int tmp;
 
seed *= 16807;
 
tmp = seed ^ (seed >> 4) ^ (seed << 15);
 
*((unsigned int *)&res) = (tmp >> 9) | 0x3F800000;
 
return (res - 1.0f);
}
 
 
AlienRain::AlienRain(QWidget *parent)
: QGLWidget(parent)
{
setWindowTitle("Alien Rain");
 
ogl = new QOpenGLFunctions_4_3_Compatibility;
time = new QTime;
time->start();
   program = new QOpenGLShaderProgram;
   buffer = new QOpenGLBuffer(static_cast<QOpenGLBuffer::Type>(GL_UNIFORM_BUFFER));
   texture = 0;
   startTimer(16);
}
 
AlienRain::~AlienRain()
{
delete ogl;
delete time;
   delete program;
   delete buffer;
   if (texture)
       delete texture;
}
 
void AlienRain::initializeGL()
{
   glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
ogl->initializeOpenGLFunctions();
 
   program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/alienrain.vert");
   program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/alienrain.frag");
   program->bind();
 
   texture = ktx::load("D:/Docs/GLSL/media/textures/aliens.ktx");
   texture->bind();
 
 
   buffer->create();
   buffer->bind();
   buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
   buffer->allocate(256 * sizeof(vec4));
 
for (int i = 0; i < 256; i++)
{
droplet_x_offset[i] = random_float() * 2.0f - 1.0f;
droplet_rot_speed[i] = (random_float() + 0.5f) * ((i & 1) ? -3.0f : 3.0f);
droplet_fall_speed[i] = random_float() + 0.2f;
}
 
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
 
void AlienRain::resizeGL(int w, int h)
{
   glViewport(0, 0, w, h);
}
 
void AlienRain::paintGL()
{
float t = time->elapsed() / 1000.0f;
 
   glClear(GL_COLOR_BUFFER_BIT);
   program->bind();
 
   ogl->glBindBufferBase(buffer->type(), 0, buffer->bufferId());
 
   vec4* droplet = (vec4*) buffer->map(QOpenGLBuffer::WriteOnly);
for (int i = 0; i < 256; i++)
{
droplet[i][0] = droplet_x_offset[i];
droplet[i][1] = 2.0f - fmodf((t + float(i)) * droplet_fall_speed[i], 4.31f);
droplet[i][2] = t * droplet_rot_speed[i];
droplet[i][3] = 0.0f;
}
   buffer->unmap();
 
int alien_index;
for (alien_index = 0; alien_index < 256; alien_index++)
{
       ogl->glVertexAttribI1i(0, alien_index);
       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
}
 
void AlienRain::timerEvent(QTimerEvent*)
{
updateGL();
}
 
alienrain.vert
Код
C++ (Qt)
#version 410 core
 
layout (location = 0) in int alien_index;
 
out VS_OUT
{
   flat int alien;
   vec2 tc;
} vs_out;
 
struct droplet_t
{
   float x_offset;
   float y_offset;
   float orientation;
   float unused;
};
 
layout (std140) uniform droplets
{
   droplet_t droplet[256];
};
 
void main(void)
{
   const vec2[4] position = vec2[4](vec2(-0.5, -0.5),
                                    vec2( 0.5, -0.5),
                                    vec2(-0.5,  0.5),
                                    vec2( 0.5,  0.5));
   vs_out.tc = position[gl_VertexID].xy + vec2(0.5);
   float co = cos(droplet[alien_index].orientation);
   float so = sin(droplet[alien_index].orientation);
   mat2 rot = mat2(vec2(co, so),
                   vec2(-so, co));
   vec2 pos = 0.25 * rot * position[gl_VertexID];
   gl_Position = vec4(pos.x + droplet[alien_index].x_offset,
                      pos.y + droplet[alien_index].y_offset,
                      0.5, 1.0);
   vs_out.alien = alien_index % 64;
}
 
alienrain.frag
Код
C++ (Qt)
#version 410 core
 
layout (location = 0) out vec4 color;
 
in VS_OUT
{
   flat int alien;
   vec2 tc;
} fs_in;
 
uniform sampler2DArray tex_aliens;
 
void main(void)
{
   color = texture(tex_aliens, vec3(fs_in.tc, float(fs_in.alien)));
}
 

ktx.h
Код
C++ (Qt)
#ifndef KTX_H
#define KTX_H
 
class QOpenGLTexture;
 
namespace ktx
{
 
struct header
{
unsigned char identifier[12];
unsigned int endianness;
unsigned int gltype;
unsigned int gltypesize;
unsigned int glformat;
unsigned int glinternalformat;
unsigned int glbaseinternalformat;
unsigned int pixelwidth;
unsigned int pixelheight;
unsigned int pixeldepth;
unsigned int arrayelements;
unsigned int faces;
unsigned int miplevels;
unsigned int keypairbytes;
};
 
union keyvaluepair
{
unsigned int size;
unsigned char rawbytes[4];
};
 
QOpenGLTexture* load(const char * filename, unsigned int tex = 0);
 
}
 
#endif // KTX_H
 
ktx.cpp
Код
C++ (Qt)
#include "ktx.h"
#include <QFile>
#include <QOpenGLTexture>
#include <QOpenGLFunctions_4_3_Core>
#include <QDebug>
 
namespace ktx
{
 
static const unsigned char identifier[] =
{
0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
};
 
static const unsigned int swap32(const unsigned int u32)
{
union
{
unsigned int u32;
unsigned char u8[4];
} a, b;
 
a.u32 = u32;
for (int i = 0; i < 4; i++)
b.u8[i] = a.u8[3 - i];
 
return b.u32;
}
 
 
QOpenGLTexture* load(const char * filename, unsigned int tex)
{
       QOpenGLFunctions_4_3_Core ogl;
       ogl.initializeOpenGLFunctions();
QFile file(filename);
GLuint temp = 0;
header h;
size_t data_start, data_end;
QVector<unsigned char> data;
QOpenGLTexture::Target target = static_cast<QOpenGLTexture::Target>(0);
 
if (!file.open(QFile::ReadOnly))
{
qDebug() << "KTX not opened";
return 0;
}
 
if (file.read(reinterpret_cast<char*>(&h), sizeof(h)) != sizeof(h))
{
qDebug() << "KTX header read error";
return 0;
}
 
if (QString::compare(
QByteArray(reinterpret_cast<const char*>(identifier), sizeof(identifier)),
QByteArray(reinterpret_cast<const char*>(h.identifier), sizeof(h.identifier))))
{
qDebug() << "KTX bad header";
return 0;
}
 
if (h.endianness == 0x01020304)
{
h.endianness = swap32(h.endianness);
h.gltype = swap32(h.gltype);
h.gltypesize = swap32(h.gltypesize);
h.glformat = swap32(h.glformat);
h.glinternalformat = swap32(h.glinternalformat);
h.glbaseinternalformat = swap32(h.glbaseinternalformat);
h.pixelwidth = swap32(h.pixelwidth);
h.pixelheight = swap32(h.pixelheight);
h.pixeldepth = swap32(h.pixeldepth);
h.arrayelements = swap32(h.arrayelements);
h.faces = swap32(h.faces);
h.miplevels = swap32(h.miplevels);
h.keypairbytes = swap32(h.keypairbytes);
}
 
else if (h.endianness != 0x04030201)
{
qDebug() << "KTX bad header";
return 0;
}
 
// Guess target (texture type)
if (h.pixelheight == 0)
{
if (h.arrayelements == 0)
target = QOpenGLTexture::Target1D;
else
target = QOpenGLTexture::Target1DArray;
}
else if (h.pixeldepth == 0)
{
if (h.arrayelements == 0)
{
if (h.faces == 0)
target = QOpenGLTexture::Target2D;
else
target = QOpenGLTexture::TargetCubeMap;
}
else
{
if (h.faces == 0)
target = QOpenGLTexture::Target2DArray;
else
target = QOpenGLTexture::TargetCubeMapArray;
}
}
else
target = QOpenGLTexture::Target3D;
 
// Check for insanity...
if (target == 0 ||                                    // Couldn't figure out target
(h.pixelwidth == 0) ||                                  // Texture has no width???
(h.pixelheight == 0 && h.pixeldepth != 0))              // Texture has depth but no height???
{
qDebug() << "KTX bad header";
return 0;
}
 
temp = tex;
 
QOpenGLTexture* texture = new QOpenGLTexture(target);
texture->create();
texture->bind();
tex = texture->textureId();
 
data_start = file.pos();
data_end = file.size();
 
data.resize(data_end - data_start);
data.fill(0);
 
file.read(reinterpret_cast<char*>(data.data()), data.size());
 
if (h.miplevels == 0)
{
h.miplevels = 1;
}
 
switch (target)
{
case QOpenGLTexture::Target1D:
//                glTexStorage1D(GL_TEXTURE_1D, h.miplevels, h.glinternalformat, h.pixelwidth);
//                glTexSubImage1D(GL_TEXTURE_1D, 0, 0, h.pixelwidth, h.glformat, h.glinternalformat, data);
break;
case QOpenGLTexture::Target2D:
//                glTexStorage2D(GL_TEXTURE_2D, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight);
//                {
//                    unsigned char * ptr = data;
//                    unsigned int height = h.pixelheight;
//                    unsigned int width = h.pixelwidth;
//                    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//                    for (unsigned int i = 0; i < h.miplevels; i++)
//                    {
//                        glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, width, height, h.glformat, h.gltype, ptr);
//                        ptr += height * calculate_stride(h, width, 1);
//                        height >>= 1;
//                        width >>= 1;
//                        if (!height)
//                            height = 1;
//                        if (!width)
//                            width = 1;
//                    }
//                }
break;
case QOpenGLTexture::Target3D:
//                glTexStorage3D(GL_TEXTURE_3D, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.pixeldepth);
//                glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.pixeldepth, h.glformat, h.gltype, data);
break;
case QOpenGLTexture::Target1DArray:
//                glTexStorage2D(GL_TEXTURE_1D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.arrayelements);
//                glTexSubImage2D(GL_TEXTURE_1D_ARRAY, 0, 0, 0, h.pixelwidth, h.arrayelements, h.glformat, h.gltype, data);
break;
case QOpenGLTexture::Target2DArray:
// texture->setMipLevels(h.miplevels);
// texture->setSize(h.pixelwidth, h.pixelheight, h.pixeldepth);
// texture->setLayers(h.arrayelements);
// texture->allocateStorage();
 
// texture->setData(static_cast<QOpenGLTexture::PixelFormat> (h.glformat),
// static_cast<QOpenGLTexture::PixelType> (h.gltype),
// data.data());
 
//                glTexStorage3D(GL_TEXTURE_2D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements);
//                glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.arrayelements, h.glformat, h.gltype, data);
           ogl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements);
           ogl.glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.arrayelements, h.glformat, h.gltype, data.data());
break;
case QOpenGLTexture::TargetCubeMap:
//                glTexStorage2D(GL_TEXTURE_CUBE_MAP, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight);
// glTexSubImage3D(GL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.faces, h.glformat, h.gltype, data);
//                {
//                    unsigned int face_size = calculate_face_size(h);
//                    for (unsigned int i = 0; i < h.faces; i++)
//                    {
//                        glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, h.pixelwidth, h.pixelheight, h.glformat, h.gltype, data + face_size * i);
//                    }
//                }
break;
case QOpenGLTexture::TargetCubeMapArray:
//                glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements);
//                glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.faces * h.arrayelements, h.glformat, h.gltype, data);
break;
}
//        if (h.miplevels == 1)
//                texture->generateMipMaps();
return texture;
}
 
}
 


Название: Re: Примеры из SuperBible под Qt 5.3
Отправлено: __Heaven__ от Октябрь 07, 2014, 13:35
Файлик текстур (aliens.ktx) в архиве с официального сайта http://openglsuperbible.com/files/sb6media_2013_11_10.zip (http://openglsuperbible.com/files/sb6media_2013_11_10.zip)