8 / 8 / 1
Регистрация: 18.11.2019
Сообщений: 109
1

Где найти примеры небольших программ на C++ OpenGL 3.3+

26.10.2020, 13:52. Показов 5827. Ответов 27

Author24 — интернет-сервис помощи студентам
Здравствуйте. Пробую писать чё-то с OpenGL, но чем больше я это делаю, тем больше убеждаюсь, что что-то я делаю не так. Решил заглянуть как делают другие - поисковик выдал только уроки, и примеры на устаревшем OpenGL. Решил написать на форум, может тут скажете где найти примеры программ, а не код с уроков .-.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.10.2020, 13:52
Ответы с готовыми решениями:

Где найти примеры программ для начинающих
где можно найти веб-c-предлагаемых,программ,для Начинающux

Где найти примеры реально работающих технических заданий на разработку программ?
Где найти примеры реально работающих т. заданий на разработку программ? Подскажите, пожалуйста....

Интересуют исходники небольших программ на С#
Интересуют исходники небольших программ на С# Где реализованы именно программы , не объяснения...

Написания небольших программ для вычислений
Здравствуйте. Возникла необходимость написания небольших программ для вычислений, построении...

27
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
23.11.2020, 18:24 21
Author24 — интернет-сервис помощи студентам
Пример змейки из туториала от NoobTuts: Python Snake Game, переписанный на Qt C++

Демка для Windows: Snake2DNoobTuts_OpenGLES20_Qt5Cpp.zip (11 МБайт)

Исходники на OpenGL 3.3 для Desktop

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QOpenGLWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
#include <QtGui/QKeyEvent>
#include <QtCore/QList>
#include <QtCore/QMutableListIterator>
#include <QtCore/QTimer>
#include <QtCore/QRandomGenerator>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setFocusPolicy(Qt::StrongFocus);
    }
signals:
    void updateScore(QString score);
    void updateLives(QString lives);
private slots:
    void onUpdate() {
        // Move snake
        // Insert new position in the beginning of the snake list
        m_snake.insert(0, m_snake[0] + m_snakeDir);
        m_snake.removeLast();
        // Collision with itself
        int hx = m_snake[0].x();
        int hy = m_snake[0].y();
        for (int i = 0; i < m_snake.length(); i++) {
            if (i == 0)
                continue;
            if (hx == m_snake[i].x() && hy == m_snake[i].y()) {
                m_food.clear();
                m_snake.clear();
                m_snake.append(m_startPos);
                m_snakeDir = m_startDir;
                emit updateLives("Lives: " + QString::number(--m_lives));
                update();
                return;
            }
        }
        // Spawn food
        // Spawn food with 5% chance
        int r = QRandomGenerator::global()->bounded(0, 20);
        if (r == 0) {
            int x = QRandomGenerator::global()->bounded(0, m_fieldWidth);
            int y = QRandomGenerator::global()->bounded(0, m_fieldHeight);
            m_food.append(QVector2D(x, y));
        }
        // Let the snake eat the food
        // Get the snake's head x and y position
        QMutableListIterator<QVector2D> i(m_food);
        while (i.hasNext()) {
            QVector2D f = i.next();
            if (hx == f.x() && hy == f.y()) { // Is the head where the food is?
                m_snake.append(QVector2D(f.x(), f.y())); // Make the snake longer
                i.remove(); // Remove the food
                m_score += 10;
                emit updateScore("Score: " + QString::number(m_score));
            }
        }
        // Collisions with borders
        if (hx < 0 || m_fieldWidth <= hx ||
            hy < 0 || m_fieldHeight <= hy)
        {
            m_lives--;
            m_food.clear();
            m_snake.clear();
            m_snake.append(m_startPos);
            m_snakeDir = m_startDir;
            if (m_lives == 0) {
                m_lives = 3;
                m_score = 0;
                emit updateScore("Score: " + QString::number(m_score));
            }
            emit updateLives("Lives: " + QString::number(m_lives));
        }
        update();
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    float m_fieldWidth = 20.f; // Internal resolution
    float m_fieldHeight = 20.f; // Internal resolution
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_modelMatrix;
    QList<QVector2D> m_snake; // Snake list of (x, y) positions
    QList<QVector2D> m_food;
    QVector2D m_startPos = QVector2D(5.f, 10.f);
    QVector2D m_startDir = QVector2D(1, 0);
    QVector2D m_snakeDir = m_startDir; // Snake movement direction
    QTimer m_timer;
    int m_score = 0;
    int m_lives = 3;
 
    void initializeGL() override {
//        qDebug() << QString("w = %1, h = %2").arg(width()).arg(height());
        glClearColor(0.f, 0.f, 0.f, 1.f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "uniform mat4 uMvpMatrix;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "uniform vec4 uColor;"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = uColor;"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        float vertPositions[] = {
            0.f, 0.f, 0.f,
            1.f, 0.f, 0.f,
            0.f, 1.f, 0.f,
            1.f, 1.f, 0.f
        };
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        m_projMatrix.ortho(0.f, m_fieldWidth, 0.f, m_fieldHeight, -100.f, 100.f);
        m_snake.append(m_startPos);
        emit updateScore("Score: " + QString::number(m_score));
        emit updateLives("Lives: " + QString::number(m_lives));
        connect(&m_timer, &QTimer::timeout, this, &OpenGLWidget::onUpdate);
        m_timer.start(200);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        drawFood();
        drawSnake();
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void keyPressEvent(QKeyEvent *e) override {
        if (e->key() == Qt::Key_W || e->key() == Qt::Key_Up)
            if (m_snakeDir != QVector2D(0, -1))
                m_snakeDir = QVector2D(0, 1);
        if (e->key() == Qt::Key_S || e->key() == Qt::Key_Down)
            if (m_snakeDir != QVector2D(0, 1))
                m_snakeDir = QVector2D(0, -1);
        if (e->key() == Qt::Key_A || e->key() == Qt::Key_Left)
            if (m_snakeDir != QVector2D(1, 0))
                m_snakeDir = QVector2D(-1, 0);
        if (e->key() == Qt::Key_D || e->key() == Qt::Key_Right)
            if (m_snakeDir != QVector2D(-1, 0))
                m_snakeDir = QVector2D(1, 0);
    }
    void drawRect(float x, float y, float width, float height, QColor color) {
        m_modelMatrix.setToIdentity();
        m_modelMatrix.translate(QVector3D(x, y, 0.f));
        m_modelMatrix.scale(width, height, 1.f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", m_projMatrix * m_modelMatrix);
        m_program.setUniformValue("uColor", color);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void drawSnake() {
        foreach (const QVector2D &cell, m_snake) {
            drawRect(cell.x(), cell.y(), 1, 1, QColor(255, 255, 255, 255));
        }
    }
    void drawFood() {
        foreach (const QVector2D &f, m_food) {
            drawRect(f.x(), f.y(), 1, 1, QColor(0, 0, 255, 255));
        }
    }
};
 
class Window : public QWidget {
public:
    Window(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("C++ OpenGL");
        setFixedSize(239, 268);
        QFont font = QFont("Areal", 14);
        m_labelScore.setFont(font);
        m_labelScore.setText("");
        m_labelScore.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_labelLives.setFont(font);
        m_labelLives.setText("");
        m_labelLives.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        QHBoxLayout *hboxOutput = new QHBoxLayout();
        hboxOutput->addWidget(&m_labelScore);
        hboxOutput->addWidget(&m_labelLives);
        QHBoxLayout *hbox = new QHBoxLayout();
        hbox->addWidget(&m_openGLWidget);
        QVBoxLayout *vbox = new QVBoxLayout(this);
        vbox->addLayout(hboxOutput);
        vbox->addLayout(hbox);
        connect(&m_openGLWidget, &OpenGLWidget::updateScore,
                [this](const QString &s){ m_labelScore.setText(s); });
        connect(&m_openGLWidget, &OpenGLWidget::updateLives,
                [this](const QString &s){ m_labelLives.setText(s); });
    }
private:
    OpenGLWidget m_openGLWidget;
    QLabel m_labelScore;
    QLabel m_labelLives;
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Window w;
    w.show();
    return a.exec();
}


Исходники на OpenGL ES 2.0 для Desktop, Android и iOS

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QOpenGLWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
#include <QtGui/QKeyEvent>
#include <QtCore/QList>
#include <QtCore/QMutableListIterator>
#include <QtCore/QTimer>
#include <QtCore/QRandomGenerator>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setFocusPolicy(Qt::StrongFocus);
    }
signals:
    void updateScore(QString score);
    void updateLives(QString lives);
private slots:
    void onUpdate() {
        // Move snake
        // Insert new position in the beginning of the snake list
        m_snake.insert(0, m_snake[0] + m_snakeDir);
        m_snake.removeLast();
        // Collision with itself
        int hx = m_snake[0].x();
        int hy = m_snake[0].y();
        for (int i = 0; i < m_snake.length(); i++) {
            if (i == 0)
                continue;
            if (hx == m_snake[i].x() && hy == m_snake[i].y()) {
                m_food.clear();
                m_snake.clear();
                m_snake.append(m_startPos);
                m_snakeDir = m_startDir;
                emit updateLives("Lives: " + QString::number(--m_lives));
                update();
                return;
            }
        }
        // Spawn food
        // Spawn food with 5% chance
        int r = QRandomGenerator::global()->bounded(0, 20);
        if (r == 0) {
            int x = QRandomGenerator::global()->bounded(0, m_fieldWidth);
            int y = QRandomGenerator::global()->bounded(0, m_fieldHeight);
            m_food.append(QVector2D(x, y));
        }
        // Let the snake eat the food
        // Get the snake's head x and y position
        QMutableListIterator<QVector2D> i(m_food);
        while (i.hasNext()) {
            QVector2D f = i.next();
            if (hx == f.x() && hy == f.y()) { // Is the head where the food is?
                m_snake.append(QVector2D(f.x(), f.y())); // Make the snake longer
                i.remove(); // Remove the food
                m_score += 10;
                emit updateScore("Score: " + QString::number(m_score));
            }
        }
        // Collisions with borders
        if (hx < 0 || m_fieldWidth <= hx ||
            hy < 0 || m_fieldHeight <= hy)
        {
            m_lives--;
            m_food.clear();
            m_snake.clear();
            m_snake.append(m_startPos);
            m_snakeDir = m_startDir;
            if (m_lives == 0) {
                m_lives = 3;
                m_score = 0;
                emit updateScore("Score: " + QString::number(m_score));
            }
            emit updateLives("Lives: " + QString::number(m_lives));
        }
        update();
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    float m_fieldWidth = 20.f; // Internal resolution
    float m_fieldHeight = 20.f; // Internal resolution
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_modelMatrix;
    QList<QVector2D> m_snake; // Snake list of (x, y) positions
    QList<QVector2D> m_food;
    QVector2D m_startPos = QVector2D(5.f, 10.f);
    QVector2D m_startDir = QVector2D(1, 0);
    QVector2D m_snakeDir = m_startDir; // Snake movement direction
    QTimer m_timer;
    int m_score = 0;
    int m_lives = 3;
 
    void initializeGL() override {
//        qDebug() << QString("w = %1, h = %2").arg(width()).arg(height());
        glClearColor(0.f, 0.f, 0.f, 1.f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "uniform mat4 uMvpMatrix;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "uniform vec4 uColor;"
                "void main()"
                "{"
                "    gl_FragColor = uColor;"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        float vertPositions[] = {
            0.f, 0.f, 0.f,
            1.f, 0.f, 0.f,
            0.f, 1.f, 0.f,
            1.f, 1.f, 0.f
        };
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        m_projMatrix.ortho(0.f, m_fieldWidth, 0.f, m_fieldHeight, -100.f, 100.f);
        m_snake.append(m_startPos);
        emit updateScore("Score: " + QString::number(m_score));
        emit updateLives("Lives: " + QString::number(m_lives));
        connect(&m_timer, &QTimer::timeout, this, &OpenGLWidget::onUpdate);
        m_timer.start(200);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        drawFood();
        drawSnake();
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void keyPressEvent(QKeyEvent *e) override {
        if (e->key() == Qt::Key_W || e->key() == Qt::Key_Up)
            if (m_snakeDir != QVector2D(0, -1))
                m_snakeDir = QVector2D(0, 1);
        if (e->key() == Qt::Key_S || e->key() == Qt::Key_Down)
            if (m_snakeDir != QVector2D(0, 1))
                m_snakeDir = QVector2D(0, -1);
        if (e->key() == Qt::Key_A || e->key() == Qt::Key_Left)
            if (m_snakeDir != QVector2D(1, 0))
                m_snakeDir = QVector2D(-1, 0);
        if (e->key() == Qt::Key_D || e->key() == Qt::Key_Right)
            if (m_snakeDir != QVector2D(-1, 0))
                m_snakeDir = QVector2D(1, 0);
    }
    void drawRect(float x, float y, float width, float height, QColor color) {
        m_modelMatrix.setToIdentity();
        m_modelMatrix.translate(QVector3D(x, y, 0.f));
        m_modelMatrix.scale(width, height, 1.f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", m_projMatrix * m_modelMatrix);
        m_program.setUniformValue("uColor", color);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void drawSnake() {
        foreach (const QVector2D &cell, m_snake) {
            drawRect(cell.x(), cell.y(), 1, 1, QColor(255, 255, 255, 255));
        }
    }
    void drawFood() {
        foreach (const QVector2D &f, m_food) {
            drawRect(f.x(), f.y(), 1, 1, QColor(0, 0, 255, 255));
        }
    }
};
 
class Window : public QWidget {
public:
    Window(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("C++ OpenGL");
        setFixedSize(239, 268);
        QFont font = QFont("Areal", 14);
        m_labelScore.setFont(font);
        m_labelScore.setText("");
        m_labelScore.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_labelLives.setFont(font);
        m_labelLives.setText("");
        m_labelLives.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        QHBoxLayout *hboxOutput = new QHBoxLayout();
        hboxOutput->addWidget(&m_labelScore);
        hboxOutput->addWidget(&m_labelLives);
        QHBoxLayout *hbox = new QHBoxLayout();
        hbox->addWidget(&m_openGLWidget);
        QVBoxLayout *vbox = new QVBoxLayout(this);
        vbox->addLayout(hboxOutput);
        vbox->addLayout(hbox);
        connect(&m_openGLWidget, &OpenGLWidget::updateScore,
                [this](const QString &s){ m_labelScore.setText(s); });
        connect(&m_openGLWidget, &OpenGLWidget::updateLives,
                [this](const QString &s){ m_labelLives.setText(s); });
    }
private:
    OpenGLWidget m_openGLWidget;
    QLabel m_labelScore;
    QLabel m_labelLives;
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Window w;
    w.show();
    return a.exec();
}


Название: Snake2DNoobTuts_OpenGLES20_Qt5Cpp.gif
Просмотров: 246

Размер: 65.3 Кб
Вложения
Тип файла: zip Snake2DNoobTuts_OpenGLES20_Qt5Cpp.zip (11.09 Мб, 13 просмотров)
1
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
24.11.2020, 15:45 22
Вращение кубика с помощью клавиш клавиатуры на Qt C++. За основу взяты примеры из книги по WebGL: этот и этот (книга: англ., рус.)

Номера вершин заданы таким образом:
Код
    //    v6----- v5
    //   /|      /|
    //  v1------v0|
    //  | |     | |
    //  | |v7---|-|v4
    //  |/      |/
    //  v2------v3
Демка для Windows: RotateCubeByKeys_OpenGLES20_Qt5Cpp.rar (9 МБайт)

Управление: WASD и клавиши стрелок клавиатуры

Исходники на OpenGL 3.3 для Desktop

main.cpp

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QKeyEvent>
#include <QtGui/QMatrix4x4>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr)
        : QOpenGLWidget(parent)
        , m_indexBuffer(QOpenGLBuffer::IndexBuffer)
    {
        setWindowTitle("Qt C++, OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_normalBuffer;
    QOpenGLBuffer m_indexBuffer;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_amountOfVertices;
    const float m_ANGLE_STEP = 3.f;
    float m_angle = 0.f;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "in vec4 aNormal;"
                "uniform mat4 uMvpMatrix;"
                "uniform mat4 uNormalMatrix;"
                "out vec4 vColor;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "    vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));"
                "    vec4 color = vec4(1.0, 0.4, 0.0, 1.0);"
                "    vec3 normal = normalize((uNormalMatrix * aNormal).xyz);"
                "    float nDotL = max(dot(normal, lightDirection), 0.0);"
                "    vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "in vec4 vColor;"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = vColor;"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        m_amountOfVertices = initVertexBuffers();
        m_viewMatrix.lookAt(
                    QVector3D(20.f, 15.f, 30.f), // eye position
                    QVector3D(0.f, 0.f, 0.f),    // center
                    QVector3D(0.f, 1.f, 0.f));   // up
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        m_modelMatrix.setToIdentity();
        m_modelMatrix.translate(QVector3D(0.f, 0.f, 0.f));
        m_modelMatrix.rotate(m_angle, QVector3D(0.f, 1.f, 0.f));
        m_modelMatrix.scale(7.f, 7.f, 7.f);
        drawBox();
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        m_projMatrix.setToIdentity();
        m_projMatrix.perspective(50.f, (float)width()/height(), 0.1f, 100.f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", m_projMatrix * m_viewMatrix);
    }
    void keyPressEvent(QKeyEvent *e) override {
        switch (e->key()) {
            case Qt::Key_Left:
            case Qt::Key_A:
                m_angle = (int)(m_angle + m_ANGLE_STEP) % 360;
                break;
            case Qt::Key_Right:
            case Qt::Key_D:
                m_angle = (int)(m_angle - m_ANGLE_STEP) % 360;
                break;
        }
        update();
    }
    int initVertexBuffers() {
        //    v6----- v5
        //   /|      /|
        //  v1------v0|
        //  | |     | |
        //  | |v7---|-|v4
        //  |/      |/
        //  v2------v3
        float vertPositions[] = {
            // v0-v1-v2-v3 front
            1.f, 1.f, 1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f, 1.f,
            // v0-v3-v4-v5 right
            1.f, 1.f, 1.f, 1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f,
            // v0-v5-v6-v1 up
            1.f, 1.f, 1.f, 1.f, 1.f, -1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f,
            // v1-v6-v7-v2 left
           -1.f, 1.f, 1.f, -1.f, 1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f,
            // v7-v4-v3-v2 down
           -1.f, -1.f, -1.f, 1.f, -1.f, -1.f, 1.f, -1.f, 1.f, -1.f, -1.f, 1.f,
            // v4-v7-v6-v5 back
            1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f, -1.f, 1.f, 1.f, -1.f
        };
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        float normals[] = {
            // v0-v1-v2-v3 front
            0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
            // v0-v3-v4-v5 right
            1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
            // v0-v5-v6-v1 up
            0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
            // v1-v6-v7-v2 left
            -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
            // v7-v4-v3-v2 down
            0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
            // v4-v7-v6-v5 back
            0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f
        };
        m_normalBuffer.create();
        m_normalBuffer.bind();
        m_normalBuffer.allocate(normals, sizeof(normals));
        m_program.bindAttributeLocation("aNormal", 1);
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        int indices[] = {
            0, 1, 2, 0, 2, 3,           // front
            4, 5, 6, 4, 6, 7,           // right
            8, 9, 10, 8, 10, 11,        // up
            12, 13, 14, 12, 14, 15,     // left
            16, 17, 18, 16, 18, 19,     // down
            20, 21, 22, 20, 22, 23      // back
        };
        m_indexBuffer.create();
        m_indexBuffer.bind();
        m_indexBuffer.allocate(indices, sizeof(indices));
 
        int amountOfVertices = sizeof(indices) / sizeof(indices[0]);
        return amountOfVertices;
    }
    void drawBox() {
        QMatrix4x4 mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", mvpMatrix);
        QMatrix4x4 normalMatrix;
        normalMatrix = m_modelMatrix.inverted();
        normalMatrix = normalMatrix.transposed();
        m_program.setUniformValue("uNormalMatrix", normalMatrix);
        m_vertPosBuffer.bind();
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        m_normalBuffer.bind();
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        glDrawElements(GL_TRIANGLES, m_amountOfVertices, GL_UNSIGNED_INT, nullptr);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Исходники на OpenGL ES 2.0 для Desktop, Android и iOS

main.cpp

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QKeyEvent>
#include <QtGui/QMatrix4x4>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr)
        : QOpenGLWidget(parent)
        , m_indexBuffer(QOpenGLBuffer::IndexBuffer)
    {
        setWindowTitle("Qt C++, OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_normalBuffer;
    QOpenGLBuffer m_indexBuffer;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_amountOfVertices;
    const float m_ANGLE_STEP = 3.f;
    float m_angle = 0.f;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "attribute vec4 aNormal;"
                "uniform mat4 uMvpMatrix;"
                "uniform mat4 uNormalMatrix;"
                "varying vec4 vColor;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "    vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));"
                "    vec4 color = vec4(1.0, 0.4, 0.0, 1.0);"
                "    vec3 normal = normalize((uNormalMatrix * aNormal).xyz);"
                "    float nDotL = max(dot(normal, lightDirection), 0.0);"
                "    vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);"
                "}";
        const char *fragShaderSrc =
                "varying vec4 vColor;"
                "void main()"
                "{"
                "    gl_FragColor = vColor;"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        m_amountOfVertices = initVertexBuffers();
        m_viewMatrix.lookAt(
                    QVector3D(20.f, 15.f, 30.f), // eye position
                    QVector3D(0.f, 0.f, 0.f),    // center
                    QVector3D(0.f, 1.f, 0.f));   // up
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        m_modelMatrix.setToIdentity();
        m_modelMatrix.translate(QVector3D(0.f, 0.f, 0.f));
        m_modelMatrix.rotate(m_angle, QVector3D(0.f, 1.f, 0.f));
        m_modelMatrix.scale(7.f, 7.f, 7.f);
        drawBox();
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        m_projMatrix.setToIdentity();
        m_projMatrix.perspective(50.f, (float)width()/height(), 0.1f, 100.f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", m_projMatrix * m_viewMatrix);
    }
    void keyPressEvent(QKeyEvent *e) override {
        switch (e->key()) {
            case Qt::Key_Left:
            case Qt::Key_A:
                m_angle = (int)(m_angle + m_ANGLE_STEP) % 360;
                break;
            case Qt::Key_Right:
            case Qt::Key_D:
                m_angle = (int)(m_angle - m_ANGLE_STEP) % 360;
                break;
        }
        update();
    }
    int initVertexBuffers() {
        //    v6----- v5
        //   /|      /|
        //  v1------v0|
        //  | |     | |
        //  | |v7---|-|v4
        //  |/      |/
        //  v2------v3
        float vertPositions[] = {
            // v0-v1-v2-v3 front
            1.f, 1.f, 1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f, 1.f,
            // v0-v3-v4-v5 right
            1.f, 1.f, 1.f, 1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f,
            // v0-v5-v6-v1 up
            1.f, 1.f, 1.f, 1.f, 1.f, -1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f,
            // v1-v6-v7-v2 left
           -1.f, 1.f, 1.f, -1.f, 1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f,
            // v7-v4-v3-v2 down
           -1.f, -1.f, -1.f, 1.f, -1.f, -1.f, 1.f, -1.f, 1.f, -1.f, -1.f, 1.f,
            // v4-v7-v6-v5 back
            1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f, -1.f, 1.f, 1.f, -1.f
        };
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        float normals[] = {
            // v0-v1-v2-v3 front
            0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
            // v0-v3-v4-v5 right
            1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
            // v0-v5-v6-v1 up
            0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
            // v1-v6-v7-v2 left
            -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
            // v7-v4-v3-v2 down
            0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
            // v4-v7-v6-v5 back
            0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f
        };
        m_normalBuffer.create();
        m_normalBuffer.bind();
        m_normalBuffer.allocate(normals, sizeof(normals));
        m_program.bindAttributeLocation("aNormal", 1);
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        int indices[] = {
            0, 1, 2, 0, 2, 3,           // front
            4, 5, 6, 4, 6, 7,           // right
            8, 9, 10, 8, 10, 11,        // up
            12, 13, 14, 12, 14, 15,     // left
            16, 17, 18, 16, 18, 19,     // down
            20, 21, 22, 20, 22, 23      // back
        };
        m_indexBuffer.create();
        m_indexBuffer.bind();
        m_indexBuffer.allocate(indices, sizeof(indices));
 
        int amountOfVertices = sizeof(indices) / sizeof(indices[0]);
        return amountOfVertices;
    }
    void drawBox() {
        QMatrix4x4 mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", mvpMatrix);
        QMatrix4x4 normalMatrix;
        normalMatrix = m_modelMatrix.inverted();
        normalMatrix = normalMatrix.transposed();
        m_program.setUniformValue("uNormalMatrix", normalMatrix);
        m_vertPosBuffer.bind();
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        m_normalBuffer.bind();
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        glDrawElements(GL_TRIANGLES, m_amountOfVertices, GL_UNSIGNED_INT, nullptr);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Название: RotateCubeByKeys_OpenGLES20_Qt5Cpp.gif
Просмотров: 384

Размер: 160.1 Кб
Вложения
Тип файла: rar RotateCubeByKeys_OpenGLES20_Qt5Cpp.rar (9.08 Мб, 8 просмотров)
1
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
25.11.2020, 17:06 23
Переписал этот пример скелетной анимации на двух костях из книги по WebGL (англ., рус.) на Qt C++

Управление:
  • Нижняя кость крутится вокруг оси Y с помощью клавиш AD (или стрелок: влево-вправо)
  • Верхняя кость крутится вокруг оси Z с помощью клавиш WS (или стрелок: вверх-вниз)

Демка для Windows: JointModel_DemoForWindows.zip (11.08 Мб)

Исходники:
Исходники на OpenGL 3.3 для Desktop

main.cpp

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QKeyEvent>
#include <QtGui/QMatrix4x4>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr)
        : QOpenGLWidget(parent)
        , m_indexBuffer(QOpenGLBuffer::IndexBuffer)
    {
        setWindowTitle("Qt C++, OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_normalBuffer;
    QOpenGLBuffer m_indexBuffer;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_amountOfVertices;
    const float m_ANGLE_STEP = 3.f;
    float m_arm1Angle = -90.f;
    float m_joint1Angle = 0.f;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "attribute vec4 aNormal;"
                "uniform mat4 uMvpMatrix;"
                "uniform mat4 uNormalMatrix;"
                "varying vec4 vColor;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "    vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));"
                "    vec4 color = vec4(1.0, 0.4, 0.0, 1.0);"
                "    vec3 normal = normalize((uNormalMatrix * aNormal).xyz);"
                "    float nDotL = max(dot(normal, lightDirection), 0.0);"
                "    vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);"
                "}";
        const char *fragShaderSrc =
                "varying vec4 vColor;"
                "void main()"
                "{"
                "    gl_FragColor = vColor;"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        m_amountOfVertices = initVertexBuffers();
        m_viewMatrix.lookAt(
                    QVector3D(20.f, 10.f, 30.f), // eye position
                    QVector3D(0.f, 0.f, 0.f),    // center
                    QVector3D(0.f, 1.f, 0.f));   // up
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // Arm1
        float arm1Length = 10.f;
        m_modelMatrix.setToIdentity();
        m_modelMatrix.translate(QVector3D(0.f, -12.f, 0.f));
        m_modelMatrix.rotate(m_arm1Angle, QVector3D(0.f, 1.f, 0.f));
        drawBox();
 
        // Arm2
        m_modelMatrix.translate(QVector3D(0.f, arm1Length, 0.f));
        m_modelMatrix.rotate(m_joint1Angle, QVector3D(0.f, 0.f, 1.f));
        m_modelMatrix.scale(1.3f, 1.f, 1.3);
        drawBox();
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        m_projMatrix.setToIdentity();
        m_projMatrix.perspective(50.f, (float)width()/height(), 0.1f, 100.f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", m_projMatrix * m_viewMatrix);
    }
    void keyPressEvent(QKeyEvent *e) override {
        switch (e->key()) {
            case Qt::Key_Up:
            case Qt::Key_W:
                if (m_joint1Angle < 135.f) {
                    m_joint1Angle += m_ANGLE_STEP;
                }
                break;
            case Qt::Key_Down:
            case Qt::Key_S:
                if (m_joint1Angle > -135.f) {
                    m_joint1Angle -= m_ANGLE_STEP;
                }
                break;
            case Qt::Key_Left:
            case Qt::Key_A:
                m_arm1Angle = (int)(m_arm1Angle + m_ANGLE_STEP) % 360;
                break;
            case Qt::Key_Right:
            case Qt::Key_D:
                m_arm1Angle = (int)(m_arm1Angle - m_ANGLE_STEP) % 360;
                break;
        }
        update();
    }
    int initVertexBuffers() {
        float vertPositions[] = {
            // v0-v1-v2-v3 front
            1.5f, 10.f, 1.5f, -1.5f, 10.f, 1.5f, -1.5f, 0.f, 1.5f, 1.5f, 0.f, 1.5f,
            // v0-v3-v4-v5 right
            1.5f, 10.f, 1.5f, 1.5f, 0.f, 1.5f, 1.5f, 0.f, -1.5f, 1.5f, 10.f, -1.5f,
            // v0-v5-v6-v1 up
            1.5f, 10.f, 1.5f, 1.5f, 10.f, -1.5f, -1.5f, 10.f, -1.5f, -1.5f, 10.f, 1.5f,
            // v1-v6-v7-v2 left
            -1.5f, 10.f, 1.5f, -1.5f, 10.f, -1.5f, -1.5f, 0.f, -1.5f, -1.5f, 0.f, 1.5f,
            // v7-v4-v3-v2 down
            -1.5f, 0.f, -1.5f, 1.5f, 0.f, -1.5f, 1.5f, 0.f, 1.5f, -1.5f, 0.f, 1.5f,
            // v4-v7-v6-v5 back
            1.5f, 0.f, -1.5f, -1.5f, 0.f, -1.5f, -1.5f, 10.f, -1.5f, 1.5f, 10.f, -1.5f
        };
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        float normals[] = {
            // v0-v1-v2-v3 front
            0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
            // v0-v3-v4-v5 right
            1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
            // v0-v5-v6-v1 up
            0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
            // v1-v6-v7-v2 left
            -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
            // v7-v4-v3-v2 down
            0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
            // v4-v7-v6-v5 back
            0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f
        };
        m_normalBuffer.create();
        m_normalBuffer.bind();
        m_normalBuffer.allocate(normals, sizeof(normals));
        m_program.bindAttributeLocation("aNormal", 1);
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        int indices[] = {
            0, 1, 2, 0, 2, 3,           // front
            4, 5, 6, 4, 6, 7,           // right
            8, 9, 10, 8, 10, 11,        // up
            12, 13, 14, 12, 14, 15,     // left
            16, 17, 18, 16, 18, 19,     // down
            20, 21, 22, 20, 22, 23      // back
        };
        m_indexBuffer.create();
        m_indexBuffer.bind();
        m_indexBuffer.allocate(indices, sizeof(indices));
 
        int amountOfVertices = sizeof(indices) / sizeof(indices[0]);
        return amountOfVertices;
    }
    void drawBox() {
        QMatrix4x4 mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", mvpMatrix);
        QMatrix4x4 normalMatrix;
        normalMatrix = m_modelMatrix.inverted();
        normalMatrix = normalMatrix.transposed();
        m_program.setUniformValue("uNormalMatrix", normalMatrix);
        m_vertPosBuffer.bind();
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        m_normalBuffer.bind();
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        glDrawElements(GL_TRIANGLES, m_amountOfVertices, GL_UNSIGNED_INT, nullptr);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Исходники на OpenGL ES 2.0 для Desktop, Android и iOS

main.cpp

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QKeyEvent>
#include <QtGui/QMatrix4x4>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr)
        : QOpenGLWidget(parent)
        , m_indexBuffer(QOpenGLBuffer::IndexBuffer)
    {
        setWindowTitle("Qt C++, OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_normalBuffer;
    QOpenGLBuffer m_indexBuffer;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_amountOfVertices;
    const float m_ANGLE_STEP = 3.f;
    float m_arm1Angle = -90.f;
    float m_joint1Angle = 0.f;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "attribute vec4 aNormal;"
                "uniform mat4 uMvpMatrix;"
                "uniform mat4 uNormalMatrix;"
                "varying vec4 vColor;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "    vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));"
                "    vec4 color = vec4(1.0, 0.4, 0.0, 1.0);"
                "    vec3 normal = normalize((uNormalMatrix * aNormal).xyz);"
                "    float nDotL = max(dot(normal, lightDirection), 0.0);"
                "    vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);"
                "}";
        const char *fragShaderSrc =
                "varying vec4 vColor;"
                "void main()"
                "{"
                "    gl_FragColor = vColor;"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        m_amountOfVertices = initVertexBuffers();
        m_viewMatrix.lookAt(
                    QVector3D(20.f, 10.f, 30.f), // eye position
                    QVector3D(0.f, 0.f, 0.f),    // center
                    QVector3D(0.f, 1.f, 0.f));   // up
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // Arm1
        float arm1Length = 10.f;
        m_modelMatrix.setToIdentity();
        m_modelMatrix.translate(QVector3D(0.f, -12.f, 0.f));
        m_modelMatrix.rotate(m_arm1Angle, QVector3D(0.f, 1.f, 0.f));
        drawBox();
 
        // Arm2
        m_modelMatrix.translate(QVector3D(0.f, arm1Length, 0.f));
        m_modelMatrix.rotate(m_joint1Angle, QVector3D(0.f, 0.f, 1.f));
        m_modelMatrix.scale(1.3f, 1.f, 1.3);
        drawBox();
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        m_projMatrix.setToIdentity();
        m_projMatrix.perspective(50.f, (float)width()/height(), 0.1f, 100.f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", m_projMatrix * m_viewMatrix);
    }
    void keyPressEvent(QKeyEvent *e) override {
        switch (e->key()) {
            case Qt::Key_Up:
            case Qt::Key_W:
                if (m_joint1Angle < 135.f) {
                    m_joint1Angle += m_ANGLE_STEP;
                }
                break;
            case Qt::Key_Down:
            case Qt::Key_S:
                if (m_joint1Angle > -135.f) {
                    m_joint1Angle -= m_ANGLE_STEP;
                }
                break;
            case Qt::Key_Left:
            case Qt::Key_A:
                m_arm1Angle = (int)(m_arm1Angle + m_ANGLE_STEP) % 360;
                break;
            case Qt::Key_Right:
            case Qt::Key_D:
                m_arm1Angle = (int)(m_arm1Angle - m_ANGLE_STEP) % 360;
                break;
        }
        update();
    }
    int initVertexBuffers() {
        float vertPositions[] = {
            // v0-v1-v2-v3 front
            1.5f, 10.f, 1.5f, -1.5f, 10.f, 1.5f, -1.5f, 0.f, 1.5f, 1.5f, 0.f, 1.5f,
            // v0-v3-v4-v5 right
            1.5f, 10.f, 1.5f, 1.5f, 0.f, 1.5f, 1.5f, 0.f, -1.5f, 1.5f, 10.f, -1.5f,
            // v0-v5-v6-v1 up
            1.5f, 10.f, 1.5f, 1.5f, 10.f, -1.5f, -1.5f, 10.f, -1.5f, -1.5f, 10.f, 1.5f,
            // v1-v6-v7-v2 left
            -1.5f, 10.f, 1.5f, -1.5f, 10.f, -1.5f, -1.5f, 0.f, -1.5f, -1.5f, 0.f, 1.5f,
            // v7-v4-v3-v2 down
            -1.5f, 0.f, -1.5f, 1.5f, 0.f, -1.5f, 1.5f, 0.f, 1.5f, -1.5f, 0.f, 1.5f,
            // v4-v7-v6-v5 back
            1.5f, 0.f, -1.5f, -1.5f, 0.f, -1.5f, -1.5f, 10.f, -1.5f, 1.5f, 10.f, -1.5f
        };
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        float normals[] = {
            // v0-v1-v2-v3 front
            0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
            // v0-v3-v4-v5 right
            1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
            // v0-v5-v6-v1 up
            0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
            // v1-v6-v7-v2 left
            -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
            // v7-v4-v3-v2 down
            0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
            // v4-v7-v6-v5 back
            0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f
        };
        m_normalBuffer.create();
        m_normalBuffer.bind();
        m_normalBuffer.allocate(normals, sizeof(normals));
        m_program.bindAttributeLocation("aNormal", 1);
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        int indices[] = {
            0, 1, 2, 0, 2, 3,           // front
            4, 5, 6, 4, 6, 7,           // right
            8, 9, 10, 8, 10, 11,        // up
            12, 13, 14, 12, 14, 15,     // left
            16, 17, 18, 16, 18, 19,     // down
            20, 21, 22, 20, 22, 23      // back
        };
        m_indexBuffer.create();
        m_indexBuffer.bind();
        m_indexBuffer.allocate(indices, sizeof(indices));
 
        int amountOfVertices = sizeof(indices) / sizeof(indices[0]);
        return amountOfVertices;
    }
    void drawBox() {
        QMatrix4x4 mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", mvpMatrix);
        QMatrix4x4 normalMatrix;
        normalMatrix = m_modelMatrix.inverted();
        normalMatrix = normalMatrix.transposed();
        m_program.setUniformValue("uNormalMatrix", normalMatrix);
        m_vertPosBuffer.bind();
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);
        m_normalBuffer.bind();
        m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(1);
        glDrawElements(GL_TRIANGLES, m_amountOfVertices, GL_UNSIGNED_INT, nullptr);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Название: JointModel_OpenGLES20_Qt5Cpp.gif
Просмотров: 211

Размер: 125.5 Кб
Вложения
Тип файла: zip JointModel_DemoForWindows.zip (11.08 Мб, 5 просмотров)
Тип файла: zip JointModel_OpenGL33_Qt5Cpp-master.zip (3.2 Кб, 5 просмотров)
Тип файла: zip JointModel_OpenGLES20_Qt5Cpp-master.zip (68.9 Кб, 3 просмотров)
1
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
28.11.2020, 15:28 24
Загрузка плоскости из .dae (Collada) с помощью Assimp на Qt C++ и OpenGL

Plane.dae

XML
1
 


Демка для Windows: LoadPlaneWithAssimp_ReleaseForWindows.zip (13.53 Мб)
Где найти примеры небольших программ на C++ OpenGL 3.3+


Исходники на OpenGL 3.3 для Desktop

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Add these lines to .pro:
// INCLUDEPATH += "E:\Libs\assimp-5.0.1-mingw-32bit\include"
// LIBS += -L"E:\Libs\assimp-5.0.1-mingw-32bit\lib"
// LIBS += -lopengl32 -lassimp -lIrrXML -lzlibstatic
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtWidgets/QMessageBox>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QMatrix4x4>
#include <QtGui/QVector3D>
#include <QtCore/QDebug>
#include "assimp/Importer.hpp"
#include <assimp/scene.h>
#include <assimp/postprocess.h>
 
class OpenGLWidget : public QOpenGLWidget {
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget (parent) {
        setWindowTitle("Qt C++, OpenGL");
        resize(300, 300);
    }
private:
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLShaderProgram m_program;
    int m_numVertices;
    void initializeGL() override {
        glClearColor(0.1f, 0.1f, 0.1f, 1.f);
        glEnable(GL_DEPTH_TEST);
        Assimp::Importer importer;
        const char *path = "Models/PlaneBlender8.dae";
        const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
        if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
            qDebug() << "Assimp Error:" << importer.GetErrorString();
            QMessageBox::critical(this, "Assimp Error:", importer.GetErrorString());
            return;
        }
        m_numVertices = scene->mMeshes[0]->mNumVertices;
        float vertPositions[m_numVertices * 3];
        int vertPosIndex = 0;
        for (int i = 0; i < m_numVertices; i++) {
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].x;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].y;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].z;
//            qDebug() << scene->mMeshes[0]->mVertices[i].x << ", "
//                     << scene->mMeshes[0]->mVertices[i].y << ", "
//                     << scene->mMeshes[0]->mVertices[i].z;
        }
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "uniform mat4 uModelMatrix;"
                "void main()"
                "{"
                "    gl_Position = uModelMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = vec4(0.5, 0.2, 0.7, 1.0);"
                "}";
        m_program.create();
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        QMatrix4x4 modelMatrix;
        modelMatrix.scale(0.5);
        m_program.bind();
        m_program.setUniformValue("uModelMatrix", modelMatrix);
        m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 3);
        m_program.enableAttributeArray("aPosition");
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
    }
};
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Исходники на OpenGL ES 2.0 для Desktop, Android и iOS

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Add these lines to .pro:
// INCLUDEPATH += "E:\Libs\assimp-5.0.1-mingw-32bit\include"
// LIBS += -L"E:\Libs\assimp-5.0.1-mingw-32bit\lib"
// LIBS += -lopengl32 -lassimp -lIrrXML -lzlibstatic
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtWidgets/QMessageBox>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QMatrix4x4>
#include <QtGui/QVector3D>
#include <QtCore/QDebug>
#include "assimp/Importer.hpp"
#include <assimp/scene.h>
#include <assimp/postprocess.h>
 
class OpenGLWidget : public QOpenGLWidget {
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget (parent) {
        setWindowTitle("Qt C++, OpenGL");
        resize(300, 300);
    }
private:
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLShaderProgram m_program;
    int m_numVertices;
    void initializeGL() override {
        glClearColor(0.1f, 0.1f, 0.1f, 1.f);
        glEnable(GL_DEPTH_TEST);
        Assimp::Importer importer;
        const char *path = "Models/PlaneBlender8.dae";
        const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
        if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
            qDebug() << "Assimp Error:" << importer.GetErrorString();
            QMessageBox::critical(this, "Assimp Error:", importer.GetErrorString());
            return;
        }
        m_numVertices = scene->mMeshes[0]->mNumVertices;
        float vertPositions[m_numVertices * 3];
        int vertPosIndex = 0;
        for (int i = 0; i < m_numVertices; i++) {
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].x;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].y;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].z;
//            qDebug() << scene->mMeshes[0]->mVertices[i].x << ", "
//                     << scene->mMeshes[0]->mVertices[i].y << ", "
//                     << scene->mMeshes[0]->mVertices[i].z;
        }
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "uniform mat4 uModelMatrix;"
                "void main()"
                "{"
                "    gl_Position = uModelMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "void main()"
                "{"
                "    gl_FragColor = vec4(0.5, 0.2, 0.7, 1.0);"
                "}";
        m_program.create();
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        QMatrix4x4 modelMatrix;
        modelMatrix.scale(0.5);
        m_program.bind();
        m_program.setUniformValue("uModelMatrix", modelMatrix);
        m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 3);
        m_program.enableAttributeArray("aPosition");
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
    }
};
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Где найти примеры небольших программ на C++ OpenGL 3.3+
Вложения
Тип файла: zip LoadPlaneWithAssimp_ReleaseForWindows.zip (13.53 Мб, 0 просмотров)
1
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
28.11.2020, 15:42 25
Загрузка плоскости из .dae (Collada) с помощью Assimp на Qt C++ и OpenGL

Демка для Windows: LoadPlaneWithAssimp_ReleaseForWindows.zip (13.53 Мб)
Где найти примеры небольших программ на C++ OpenGL 3.3+


Исходники:
Исходники на OpenGL 3.3 для Desktop

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Add these lines to .pro:
// INCLUDEPATH += "E:\Libs\assimp-5.0.1-mingw-32bit\include"
// LIBS += -L"E:\Libs\assimp-5.0.1-mingw-32bit\lib"
// LIBS += -lopengl32 -lassimp -lIrrXML -lzlibstatic
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtWidgets/QMessageBox>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QMatrix4x4>
#include <QtGui/QVector3D>
#include <QtCore/QDebug>
#include "assimp/Importer.hpp"
#include <assimp/scene.h>
#include <assimp/postprocess.h>
 
class OpenGLWidget : public QOpenGLWidget {
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget (parent) {
        setWindowTitle("Qt C++, OpenGL");
        resize(300, 300);
    }
private:
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLShaderProgram m_program;
    int m_numVertices;
    void initializeGL() override {
        glClearColor(0.1f, 0.1f, 0.1f, 1.f);
        glEnable(GL_DEPTH_TEST);
        Assimp::Importer importer;
        const char *path = "Models/PlaneBlender8.dae";
        const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
        if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
            qDebug() << "Assimp Error:" << importer.GetErrorString();
            QMessageBox::critical(this, "Assimp Error:", importer.GetErrorString());
            return;
        }
        m_numVertices = scene->mMeshes[0]->mNumVertices;
        float vertPositions[m_numVertices * 3];
        int vertPosIndex = 0;
        for (int i = 0; i < m_numVertices; i++) {
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].x;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].y;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].z;
//            qDebug() << scene->mMeshes[0]->mVertices[i].x << ", "
//                     << scene->mMeshes[0]->mVertices[i].y << ", "
//                     << scene->mMeshes[0]->mVertices[i].z;
        }
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "uniform mat4 uModelMatrix;"
                "void main()"
                "{"
                "    gl_Position = uModelMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = vec4(0.5, 0.2, 0.7, 1.0);"
                "}";
        m_program.create();
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        QMatrix4x4 modelMatrix;
        modelMatrix.scale(0.5);
        m_program.bind();
        m_program.setUniformValue("uModelMatrix", modelMatrix);
        m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 3);
        m_program.enableAttributeArray("aPosition");
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
    }
};
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Исходники на OpenGL ES 2.0 для Desktop, Android и iOS

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Add these lines to .pro:
// INCLUDEPATH += "E:\Libs\assimp-5.0.1-mingw-32bit\include"
// LIBS += -L"E:\Libs\assimp-5.0.1-mingw-32bit\lib"
// LIBS += -lopengl32 -lassimp -lIrrXML -lzlibstatic
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtWidgets/QMessageBox>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QMatrix4x4>
#include <QtGui/QVector3D>
#include <QtCore/QDebug>
#include "assimp/Importer.hpp"
#include <assimp/scene.h>
#include <assimp/postprocess.h>
 
class OpenGLWidget : public QOpenGLWidget {
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget (parent) {
        setWindowTitle("Qt C++, OpenGL");
        resize(300, 300);
    }
private:
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLShaderProgram m_program;
    int m_numVertices;
    void initializeGL() override {
        glClearColor(0.1f, 0.1f, 0.1f, 1.f);
        glEnable(GL_DEPTH_TEST);
        Assimp::Importer importer;
        const char *path = "Models/PlaneBlender8.dae";
        const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
        if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
            qDebug() << "Assimp Error:" << importer.GetErrorString();
            QMessageBox::critical(this, "Assimp Error:", importer.GetErrorString());
            return;
        }
        m_numVertices = scene->mMeshes[0]->mNumVertices;
        float vertPositions[m_numVertices * 3];
        int vertPosIndex = 0;
        for (int i = 0; i < m_numVertices; i++) {
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].x;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].y;
            vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].z;
//            qDebug() << scene->mMeshes[0]->mVertices[i].x << ", "
//                     << scene->mMeshes[0]->mVertices[i].y << ", "
//                     << scene->mMeshes[0]->mVertices[i].z;
        }
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "uniform mat4 uModelMatrix;"
                "void main()"
                "{"
                "    gl_Position = uModelMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "void main()"
                "{"
                "    gl_FragColor = vec4(0.5, 0.2, 0.7, 1.0);"
                "}";
        m_program.create();
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        QMatrix4x4 modelMatrix;
        modelMatrix.scale(0.5);
        m_program.bind();
        m_program.setUniformValue("uModelMatrix", modelMatrix);
        m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 3);
        m_program.enableAttributeArray("aPosition");
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
    }
};
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


PlaneBlender8.dae

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <asset>
    <contributor>
      <author>Blender User</author>
      <authoring_tool>Blender 2.83.5 commit date:2020-08-19, commit time:06:07, hash:c2b144df395f</authoring_tool>
    </contributor>
    <created>2020-11-27T14:01:41</created>
    <modified>2020-11-27T14:01:41</modified>
    <unit name="meter" meter="1"/>
    <up_axis>Z_UP</up_axis>
  </asset>
  <library_images/>
  <library_geometries>
    <geometry id="Plane-mesh" name="Plane">
      <mesh>
        <source id="Plane-mesh-positions">
          <float_array id="Plane-mesh-positions-array" count="12">-1 -1 0 1 -1 0 -1 1 0 1 1 0</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-positions-array" count="4" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh-normals">
          <float_array id="Plane-mesh-normals-array" count="3">0 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-normals-array" count="1" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh-map-0">
          <float_array id="Plane-mesh-map-0-array" count="12">1 0 0 1 0 0 1 0 1 1 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-map-0-array" count="6" stride="2">
              <param name="S" type="float"/>
              <param name="T" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <vertices id="Plane-mesh-vertices">
          <input semantic="POSITION" source="#Plane-mesh-positions"/>
        </vertices>
        <triangles count="2">
          <input semantic="VERTEX" source="#Plane-mesh-vertices" offset="0"/>
          <input semantic="NORMAL" source="#Plane-mesh-normals" offset="1"/>
          <input semantic="TEXCOORD" source="#Plane-mesh-map-0" offset="2" set="0"/>
          <p>1 0 0 2 0 1 0 0 2 1 0 3 3 0 4 2 0 5</p>
        </triangles>
      </mesh>
    </geometry>
  </library_geometries>
  <library_visual_scenes>
    <visual_scene id="Scene" name="Scene">
      <node id="Plane" name="Plane" type="NODE">
        <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
        <instance_geometry url="#Plane-mesh" name="Plane"/>
      </node>
    </visual_scene>
  </library_visual_scenes>
  <scene>
    <instance_visual_scene url="#Scene"/>
  </scene>
</COLLADA>


Где найти примеры небольших программ на C++ OpenGL 3.3+
Вложения
Тип файла: zip LoadPlaneWithAssimp_ReleaseForWindows.zip (13.53 Мб, 8 просмотров)
Тип файла: zip LoadPlaneWithAssimp_OpenGLES20_Qt5Cpp-master.zip (6.2 Кб, 5 просмотров)
Тип файла: zip LoadPlaneWithAssimp_OpenGL33_Qt5Cpp-master.zip (6.2 Кб, 5 просмотров)
1
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
28.11.2020, 16:06 26
О некоторых плюсах и минусах Assimp, по моему мнению, написал в этом сообщении: Рисование 3Д-моделей в Qt Creator
1
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
28.11.2020, 18:02 27
Цитата Сообщение от 8Observer8 Посмотреть сообщение
О некоторых плюсах и минусах Assimp, по моему мнению,
например его минус еще:
Один формат файла может содержать например 2 и более обьектов один например с треугольников другой с полигонов, получишь вылит, что то еще было с uv, еще например если это формат файла dae и на модель налеплено куча текстур или материалов однозначно вылет программы, еще баги с анимацией но не все читает. А так это одна хорошая штуковина для начало но не для фирм так это точно, если придерживаться что модель будет иметь нормали, вершинны(триангулированые), текстурные координаты, одна анимация, возможно это все пофиксели в новой версии но не думаю, в формата dae а так же в gltf много вариаций, не возможно описать все варианты сам пробывал))))
2
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
18.12.2020, 21:06 28
Лучший ответ Сообщение было отмечено XLAT как решение

Решение

Вывод картинки (текстуры) на OpenGL 3.3 (OpenGL ES 2.0) и Qt C++ с плавающем диапазоном координат по оси X



Выставляется система координат в центре клиентской области рисования. Диапазон по оси Y фиксированный и определяется константой WORLD_HEIGHT. Диапазон по оси X плавающий и зависит от соотношения сторон клиентской области окна. Определяется система координат ортографической матрицей проекции по следующему алгоритму:

C++ (Qt)
1
2
3
4
5
6
7
8
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        float aspect = (float) w / h;
        float worldWidth = aspect * WORLD_HEIGHT;
        m_projMatrix.setToIdentity();
        m_projMatrix.ortho(-worldWidth / 2.f, worldWidth / 2.f,
                           -WORLD_HEIGHT / 2.f, WORLD_HEIGHT / 2.f, 50.f, -50.f);
    }
Метод resizeGL(int w, int h) вызывается автоматически: первый раз после создания окна, а последующие разы вызвается каждый раз при изменении размера окна.

Исходники на OpenGL 3.3 для Desktop

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Add this line to .pro:
// LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLTexture>
#include <QtGui/QMatrix4x4>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget() : m_texture(QOpenGLTexture::Target2D) {
        setWindowTitle("OpenGL 3.3. Qt C++");
        resize(400, 400);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_texCoordBuffer;
    QOpenGLTexture m_texture;
    QMatrix4x4 m_mvpMatrix;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_uMvpMatrixLocation;
    const float WORLD_HEIGHT = 50;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        resize(400, 400);
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "in vec2 aTexCoord;"
                "uniform mat4 uMvpMatrix;"
                "out vec2 vTexCoord;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "    vTexCoord = aTexCoord;"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "uniform sampler2D uSampler;"
                "in vec2 vTexCoord;"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = texture2D(uSampler, vTexCoord);"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        float vertPositions[] = {
            -0.5f, -0.5f, 0.f,
            0.5f, -0.5f, 0.f,
            -0.5f, 0.5f, 0.f,
            0.5f, 0.5f, 0.f
        };
        float texCoords[] = {
            0.f, 1.f,
            1.f, 1.f,
            0.f, 0.f,
            1.f, 0.f
        };
        initVertexBuffer(m_vertPosBuffer, vertPositions, sizeof(vertPositions), "aPosition", 0, 3);
        initVertexBuffer(m_texCoordBuffer, texCoords, sizeof(texCoords), "aTexCoord", 1, 2);
        m_texture.create();
        m_texture.setData(QImage(":/Textures/WornBrownBrickwork_256.png"));
        m_texture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
        m_texture.setWrapMode(QOpenGLTexture::ClampToEdge);
        m_program.bind();
        m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
        m_modelMatrix.scale(QVector3D(50.f, 50.f, 1.f));
        m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 40.f),
                            QVector3D(0.f, 0.f, 0.f),
                            QVector3D(0.f, 1.f, 0.f));
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
        m_texture.bind();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        float aspect = (float) w / h;
        float worldWidth = aspect * WORLD_HEIGHT;
        m_projMatrix.setToIdentity();
        m_projMatrix.ortho(-worldWidth / 2.f, worldWidth / 2.f,
                           -WORLD_HEIGHT / 2.f, WORLD_HEIGHT / 2.f, 50.f, -50.f);
    }
    void initVertexBuffer(QOpenGLBuffer &buffer, float data[], int amount,
                          const char *locationName, int locationIndex, int tupleSize) {
        buffer.create();
        buffer.bind();
        buffer.allocate(data, amount);
        m_program.bindAttributeLocation(locationName, locationIndex);
        m_program.setAttributeBuffer(locationIndex, GL_FLOAT, 0, tupleSize);
        m_program.enableAttributeArray(locationIndex);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}


Исходники на OpenGL ES 2.0 для Desktop, Android и iOS

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Add this line to .pro:
// win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLTexture>
#include <QtGui/QMatrix4x4>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget() : m_texture(QOpenGLTexture::Target2D) {
        setWindowTitle("OpenGL 3.3. Qt C++");
        resize(400, 400);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_texCoordBuffer;
    QOpenGLTexture m_texture;
    QMatrix4x4 m_mvpMatrix;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_uMvpMatrixLocation;
    const float WORLD_HEIGHT = 50;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        resize(400, 400);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "attribute vec2 aTexCoord;"
                "uniform mat4 uMvpMatrix;"
                "varying vec2 vTexCoord;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "    vTexCoord = aTexCoord;"
                "}";
        const char *fragShaderSrc =
                "uniform sampler2D uSampler;"
                "varying vec2 vTexCoord;"
                "void main()"
                "{"
                "    gl_FragColor = texture2D(uSampler, vTexCoord);"
                "}";
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
        float vertPositions[] = {
            -0.5f, -0.5f, 0.f,
            0.5f, -0.5f, 0.f,
            -0.5f, 0.5f, 0.f,
            0.5f, 0.5f, 0.f
        };
        float texCoords[] = {
            0.f, 1.f,
            1.f, 1.f,
            0.f, 0.f,
            1.f, 0.f
        };
        initVertexBuffer(m_vertPosBuffer, vertPositions, sizeof(vertPositions), "aPosition", 0, 3);
        initVertexBuffer(m_texCoordBuffer, texCoords, sizeof(texCoords), "aTexCoord", 1, 2);
        m_texture.create();
        m_texture.setData(QImage(":/Textures/WornBrownBrickwork_256.png"));
        m_texture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
        m_texture.setWrapMode(QOpenGLTexture::ClampToEdge);
        m_program.bind();
        m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
        m_modelMatrix.scale(QVector3D(50.f, 50.f, 1.f));
        m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 40.f),
                            QVector3D(0.f, 0.f, 0.f),
                            QVector3D(0.f, 1.f, 0.f));
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
        m_texture.bind();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
        float aspect = (float) w / h;
        float worldWidth = aspect * WORLD_HEIGHT;
        m_projMatrix.setToIdentity();
        m_projMatrix.ortho(-worldWidth / 2.f, worldWidth / 2.f,
                           -WORLD_HEIGHT / 2.f, WORLD_HEIGHT / 2.f, 50.f, -50.f);
    }
    void initVertexBuffer(QOpenGLBuffer &buffer, float data[], int amount,
                          const char *locationName, int locationIndex, int tupleSize) {
        buffer.create();
        buffer.bind();
        buffer.allocate(data, amount);
        m_program.bindAttributeLocation(locationName, locationIndex);
        m_program.setAttributeBuffer(locationIndex, GL_FLOAT, 0, tupleSize);
        m_program.enableAttributeArray(locationIndex);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}


Миниатюра
Где найти примеры небольших программ на C++ OpenGL 3.3+
Вложения
Тип файла: zip TextureInOneFile_OpenGLES20Qt5Cpp.zip (139.5 Кб, 3 просмотров)
Тип файла: zip TextureInOneFile_OpenGL33Qt5Cpp.zip (139.5 Кб, 3 просмотров)
1
18.12.2020, 21:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.12.2020, 21:06
Помогаю со студенческими работами здесь

Где найти примеры игр на Android?
Все доброго уважаемые! Вопрос не тривиальный. Изучаю Android, в пример решил сделать собственное...

Где найти примеры задач из книги Дейтела по C++
Скачал книгу Дейтела на C++ не могу найти примеры задач, мб есть у кого?

БД SQLite где найти примеры работы с API?
Доброго времени суток. Взялся за разработку ГИС под конкретного заказчика. Нужно хранить...

Где можно найти примеры разработки 1с конфигурации?
Дайте ссылки по разработке 1с конфигурации . Что бы там мы решали задачи какого нибудь предприятия...

Где найти примеры с синхронным/асинхронным UDP?
Добрый день всем. Ребята подскажите где можно найти примеры с синхронным UDP. Подскажите...

Где можно найти примеры больших проектов C#
Нужно разработать бизнес проект на свободную тему, применяемый на практике. Хочу найти где-нибудь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru