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

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

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

Сообщений: 11445


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

1) Каковы функции шейдеров? Из книжки я, как пользователь, ничего не понял. Если я хочу сделать квартиру (для начала, без мебели) по которой я могу ходить и смотреть планировку, каковы будут функции каждого из шейдеров?
Для этого никакие шейдера не нужны, делаете модель и рисуете ее прозаичным glDrawElements. Располагаете в каждой комнате по лампочке. Клеите обои (текстурой). Остальное сводится к рулению камерой. Если нужно "не проходить сквозь стены" - такой пример есть в Bullet.

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

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

Далее, чувствую, пойдут умножения матриц на вектора - там точно будет тёмный лес.
Ну и чего/кого там бояться?
Записан
8Observer8
Гость
« Ответ #76 : Август 22, 2014, 17:13 »

Igors, спасибо большое за подробный ответ!
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



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

Камера есть всегда, без нее нет рендера. Разница лишь в способе ее задания, но все ее параметры должны быть определены и не меняться в течение всего рендера.

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

Ну и чего/кого там бояться?
Ну, по-первой сознание как-то отрицает материал. А в 3 издании к этому плавно все ведется.
Записан
8Observer8
Гость
« Ответ #78 : Август 24, 2014, 12:04 »

Один человек посоветовал изучить:
GLSL: https://code.google.com/p/gl33lessons/wiki/Lesson02
Камера: https://code.google.com/p/gl33lessons/wiki/Lesson04

P.S. Лично я в свободное время пока изучаю "классический" OpenGL по третьему изданию СуперБиблии
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #79 : Август 27, 2014, 09:52 »

Совсем я запутался с vao и vbo...
Кто-нибудь пользовался QOpenGLContext, QSurface?
Не понимаю, на сколько необходимо использовать QOpenGLContext.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Не понимаю, на сколько необходимо использовать QOpenGLContext.
По-моему никакой необходимости в этом нет, можно спокойно действовать на уровне QGLContext
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #81 : Август 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);
 
Что может быть не так?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #82 : Август 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;
« Последнее редактирование: Август 27, 2014, 17:08 от __Heaven__ » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #83 : Август 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");
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



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

Последние 2 строки - первый аргумент ноль, а надо
Код
C++ (Qt)
int loc = program->attributeLocation("posAttr");

Я в итоге использовал 0.
Где-то краем глаза видел, что 0 играет какое-то определённое значение.
Записан
Hrundel
Гость
« Ответ #85 : Август 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.

То есть - ноль указывает на то, что вертексы плотно упакованы в массиве значений. То есть - проще говоря - расстояние в байтах между вершинами отсутствует.
« Последнее редактирование: Август 27, 2014, 21:07 от Hrundel » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



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

Мы все говорим про location = 0?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



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

Я вот все думаю, а на сколько правильно использовать новый функционал при создании CAE приложения, а не игр.
Большинство примеров не запускается у меня на нетбуке по каким-либо причинам. В основном, потому что у меня максимальная версия OpenGL 3.0. Перелопатив шейдеры под 3.0 я, возможно, получу результат, но при этом нет гарантии, что приложение будет работать на других машинах.
В линукс, на сколько я понимаю, имеется возможность установить mesa, которая заменит OpenGL 3.0 только для intel (слава богу у меня оный), либо нужно иметь nvidia и их дрова.
Но с другой стороны, если писать программу без использования шейдеров, то её нельзя будет портировать на ES (поправьте, если ошибаюсь).
У кого какие мысли на этот счет?
Записан
Hrundel
Гость
« Ответ #88 : Август 28, 2014, 23:17 »

Мы все говорим про location = 0?

А ты игнорируешь тексты на английском?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #89 : Август 29, 2014, 07:34 »

Нет, вовсе не игнорирую. Изначально речь шла про location=0. Но, судя по тому, что вы прокомментировали часть описывающую плотность массива, вы привлекали внимание к stride=0.
Записан
Страниц: 1 ... 4 5 [6] 7   Вверх
  Печать  
 
Перейти в:  


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