Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/30: Рейтинг темы: голосов - 30, средняя оценка - 4.73
 Аватар для MiKITA17
8 / 8 / 1
Регистрация: 18.11.2019
Сообщений: 109

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

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

Студворк — интернет-сервис помощи студентам
Здравствуйте. Пробую писать чё-то с OpenGL, но чем больше я это делаю, тем больше убеждаюсь, что что-то я делаю не так. Решил заглянуть как делают другие - поисковик выдал только уроки, и примеры на устаревшем OpenGL. Решил написать на форум, может тут скажете где найти примеры программ, а не код с уроков .-.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.10.2020, 13:52
Ответы с готовыми решениями:

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

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

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

27
Just Do It!
 Аватар для XLAT
4189 / 2644 / 654
Регистрация: 23.09.2014
Сообщений: 8,917
Записей в блоге: 3
26.10.2020, 21:28
MiKITA17,
https://code.google.com/archiv... /downloads
0
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
20.11.2020, 15:58
Пример, который рисует треугольник на Qt C++. В примере я использую OpenGL ES 2.0, чтобы он собирался и для Android и для Desktop. Я пробовал запускать это пример на Windows 10, на эмуляторе Android и на реальном Android. Пример так же можно собрать для iOS. В начале кода есть директива "#ifdef _WIN32" и она нужна для запуска примера на ноутбуках, на которых установлено две видеокарты: маломощная (экономная) и более мощная. Если ноутбук с двумя видеокартами, то без этого кода ничего не будет рисоваться. Можете взять этот код в качестве отправной точки, дальше изучать стандартные туториалы по шейдерному OpenGL:

https://learnopengl.com
http://opengl-tutorial.org
http://ogldev.org​​
https://open.gl
https://thebookofshaders.com

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
// Minimal OpenGL example that works on Notebook and Android
// Add to .pro file: win32: LIBS += -lopengl32
 
// Version in WebGL 1.0, TypeScript: https://plnkr.co/edit/gAfPR7ZIKjJXulDI?open=main.ts&preview
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent) { }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        resize(400, 500);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "void main()"
                "{"
                "    gl_Position = vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "void main()"
                "{"
                "    gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);"
                "}";
        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.f, 0.5f, 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);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
2
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
20.11.2020, 18:06
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Пример, который рисует треугольник на Qt C++
ага, вот значит где ты пропадал, учил Opengl в QT))
2
Just Do It!
 Аватар для XLAT
4189 / 2644 / 654
Регистрация: 23.09.2014
Сообщений: 8,917
Записей в блоге: 3
21.11.2020, 05:48
8Observer8,
а что за мок?
#include "main.moc"
где взять?
1
Just Do It!
 Аватар для XLAT
4189 / 2644 / 654
Регистрация: 23.09.2014
Сообщений: 8,917
Записей в блоге: 3
21.11.2020, 05:50
---
1
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
21.11.2020, 12:01
Цитата Сообщение от XLAT Посмотреть сообщение
8Observer8,
а что за мок?
#include "main.moc"
где взять?
Эта строка нужна, чтобы работал механизм сигнал/слот (как и макрос Q_OBJECT). Но в данной программе можно удалить эту строку и макрос Q_OBJECT, потому что здесь не используются сигналы и слоты. Чтобы заработало нужно один раз скомпилировать и этот файл появляется. До построения проекта main.moc не существует. Подключение main.moc делается когда хочется расположить пример в одном файле main.cpp и хочется использовать сигнал/слот, например, для GUI или для таймера (таймер нужен, например, для анимации или для игры). Для учебных маленьких примеров, я считаю, нагляднее располагать код в одном файле. Без этой строки (но с наличием Q_OBJECT) возникает ошибка:
error: undefined reference to 'vtable for Widget'
Мне подсказали, что эту проблему можно решить с помощью подключения main.moc. Подсказали здесь, в моей теме: https://forum.qt.io/topic/1179... for-widget
2
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
21.11.2020, 12:37
Анимация вращения треугольника:

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

Размер: 106.6 Кб

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
// Add to .pro file: win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QTimer>
#include <QMatrix4x4>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setWindowTitle("Qt5 C++ OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QTimer m_timer;
    QMatrix4x4 m_rotationMatrix;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "uniform mat4 uRotationMatrix;"
                "void main()"
                "{"
                "    gl_Position = uRotationMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "void main()"
                "{"
                "    gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);"
                "}";
        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.f, 0.5f, 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);
        connect(&m_timer, &QTimer::timeout, this, &Widget::slotAnimate);
        m_timer.start(1000.f/30.f);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_program.bind();
        m_program.setUniformValue("uRotationMatrix", m_rotationMatrix);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void slotAnimate() {
        m_rotationMatrix.rotate(3.f, QVector3D(0.f, 0.f, 1.f));
        update();
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
1
Модератор
Эксперт Java
 Аватар для alecss131
2836 / 1345 / 403
Регистрация: 11.08.2017
Сообщений: 4,299
Записей в блоге: 2
21.11.2020, 12:43
8Observer8, ТС просил opengl а не opengl es, прошу прекратить оффтоп
0
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
21.11.2020, 13:19
Цитата Сообщение от alecss131 Посмотреть сообщение
8Observer8, ТС просил opengl а не opengl es, прошу прекратить оффтоп
Какое грубое нарушение я сделал. Обратитесь к модератору, чтобы он удалил все оффтоп сообщения кроме вашего, потому что ваше же сообщение, конечно, не является оффтоп, оно очень важное, вы же поймали за руку нарушителя. Попросите, чтобы модератор выдал мне пожизненный бан за написание оффтоп-сообщений. Я готов понести это справедливое наказание.

Изменил свой пример на OpenGL 3.3, чтобы как-то реабилитироваться в глазах общественности, если есть ещё надежда, что меня не забанят за оффтоп. Там исправить-то надо было "attribute" на "in", по мелочи, зато теперь на Android и iOS не будет запускаться, но хозяин - барин. Тогда буду выкладывать две версии: OpenGL 3.3 для Desktop и OpenGL ES 2.0 для Desktop/Android/iOS/Web.

Название: TriangleInOneFile_OpenGL33Qt5Cpp.png
Просмотров: 279

Размер: 3.0 Кб

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
// Add to .pro file: win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setWindowTitle("Qt, OpenGL 3.3");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "void main()"
                "{"
                "    gl_Position = vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = vec4(0.5, 0.2, 0.9, 1.0);"
                "}";
        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.f, 0.5f, 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);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
1
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
21.11.2020, 13:50
Подправил пример вращения треугольника на OpenGL ES под OpenGL 3.3. Я знаю, что автор темы активно использует Qt C++. Отмечу, что в Qt С++ создание шейдерной программы делается в несколько строк, как и много другое:

C++ (Qt)
1
2
3
4
        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();
Имеется поддержка матриц, векторов и прочей линейной алгебры:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <QMatrix4x4>
...
private:
QMatrix4x4 m_rotationMatrix;
...
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_program.bind();
        m_program.setUniformValue("uRotationMatrix", m_rotationMatrix);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
 
    void slotAnimate() {
        m_rotationMatrix.rotate(5.f, QVector3D(0.f, 0.f, 1.f));
        update();
    }
Название: RotatingTriangle_OpenGL33Qt5Cpp.gif
Просмотров: 280

Размер: 107.7 Кб

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
// Add to .pro file: win32: LIBS += -lopengl32
 
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
 
#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QTimer>
#include <QMatrix4x4>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setWindowTitle("Qt5, OpenGL 3.3");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QTimer m_timer;
    QMatrix4x4 m_rotationMatrix;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "uniform mat4 uRotationMatrix;"
                "void main()"
                "{"
                "    gl_Position = uRotationMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "out vec4 fragColor;"
                "void main()"
                "{"
                "    fragColor = vec4(0.5, 0.2, 0.9, 1.0);"
                "}";
        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.f, 0.5f, 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);
        connect(&m_timer, &QTimer::timeout, this, &Widget::slotAnimate);
        m_timer.start(1000.f/30.f);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_program.bind();
        m_program.setUniformValue("uRotationMatrix", m_rotationMatrix);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    void slotAnimate() {
        m_rotationMatrix.rotate(5.f, QVector3D(0.f, 0.f, 1.f));
        update();
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
2
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
21.11.2020, 17:21
Текст и кнопки. В этом примере в одном окне совмещается OpenGLWidget и стандартное GUI на Qt. В окне происходит соединение сигналов кнопок и слота OpenGLWidget. Я считаю, что нужно изучать OpenGL вместе с GUI. Так изучать интереснее и продуктивнее. Можно создавать разнообразные примеры с этой комбинацией. С самого начала расширяется кругозор. Можно практиковаться на написании простых игрушек с выводом текста ("Жизни", "Очки" и т.д.) и кнопок ("Старт", "Пауза", "Сохранить", "Загрузить" и "т.д."). Для неигровых приложений с интерактивной 3D графикой также часто необходимо GUI. Придумывайте примеры и тренируйтесь на практике. Изучать OpenGL нужно больше на практике, а без практики будете зарываться в теорию и почти всё забывать, а практических результатов не будет, будете буксовать на месте, ваши игрушки так и не будут писаться. Многие попадали в эту ловушку на годы, как и я.

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

Размер: 81.7 Кб

Исходники на 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
// Add this line to .pro file:
// 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 <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) { }
public slots:
    void setColor(const QColor &color) {
        m_program.bind();
        m_program.setUniformValue("uColor", color);
        update();
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        resize(400, 500);
        const char *vertShaderSrc =
                "#version 330 core\n"
                "in vec3 aPosition;"
                "void main()"
                "{"
                "    gl_Position = vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "#version 330 core\n"
                "uniform vec4 uColor;"
                "void main()"
                "{"
                "    gl_FragColor = vec4(uColor);"
                "}";
        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.f, 0.5f, 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_program.bind();
        m_program.setUniformValue("uColor", QColor(255, 0, 0, 255));
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
};
 
class Window : public QWidget {
    Q_OBJECT
public:
    Window(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("Qt5 C++ OpenGL");
        resize(268, 268);
        m_hbox.addWidget(&m_openGLWidget);
        m_labelColor.setText("Red");
        m_buttonRed.setText("Red");
        m_buttonRed.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_buttonGreen.setText("Green");
        m_buttonGreen.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_buttonBlue.setText("Blue");
        m_buttonBlue.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_vbox.addWidget(&m_labelColor);
        m_vbox.addWidget(&m_buttonRed);
        m_vbox.addWidget(&m_buttonGreen);
        m_vbox.addWidget(&m_buttonBlue);
        m_vbox.addStretch(1);
        m_hbox.addLayout(&m_vbox);
        setLayout(&m_hbox);
        connect(&m_buttonRed, &QPushButton::clicked, this, &Window::slotRedButtonClick);
        connect(&m_buttonGreen, &QPushButton::clicked, this, &Window::slotGreenButtonClick);
        connect(&m_buttonBlue, &QPushButton::clicked, this, &Window::slotBlueButtonClick);
        connect(this, &Window::setColor, &m_openGLWidget, &OpenGLWidget::setColor);
    }
signals:
    void setColor(const QColor &color);
private slots:
    void slotRedButtonClick() {
        m_labelColor.setText("Red");
        emit setColor(QColor(255, 0, 0, 255));
    }
    void slotGreenButtonClick() {
        m_labelColor.setText("Green");
        emit setColor(QColor(0, 255, 0, 255));
    }
    void slotBlueButtonClick() {
        m_labelColor.setText("Blue");
        emit setColor(QColor(0, 0, 255, 255));
    }
private:
    OpenGLWidget m_openGLWidget;
    QHBoxLayout m_hbox;
    QVBoxLayout m_vbox;
    QLabel m_labelColor;
    QPushButton m_buttonRed;
    QPushButton m_buttonGreen;
    QPushButton m_buttonBlue;
};
 
#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

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
// Add this line to .pro file:
// 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 <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) { }
public slots:
    void setColor(const QColor &color) {
        m_program.bind();
        m_program.setUniformValue("uColor", color);
        update();
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        resize(400, 500);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "void main()"
                "{"
                "    gl_Position = vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "uniform vec4 uColor;"
                "void main()"
                "{"
                "    gl_FragColor = vec4(uColor);"
                "}";
        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.f, 0.5f, 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_program.bind();
        m_program.setUniformValue("uColor", QColor(255, 0, 0, 255));
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
};
 
class Window : public QWidget {
    Q_OBJECT
public:
    Window(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("Qt5 C++ OpenGL");
        resize(268, 268);
        m_hbox.addWidget(&m_openGLWidget);
        m_labelColor.setText("Red");
        m_buttonRed.setText("Red");
        m_buttonRed.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_buttonGreen.setText("Green");
        m_buttonGreen.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_buttonBlue.setText("Blue");
        m_buttonBlue.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        m_vbox.addWidget(&m_labelColor);
        m_vbox.addWidget(&m_buttonRed);
        m_vbox.addWidget(&m_buttonGreen);
        m_vbox.addWidget(&m_buttonBlue);
        m_vbox.addStretch(1);
        m_hbox.addLayout(&m_vbox);
        setLayout(&m_hbox);
        connect(&m_buttonRed, &QPushButton::clicked, this, &Window::slotRedButtonClick);
        connect(&m_buttonGreen, &QPushButton::clicked, this, &Window::slotGreenButtonClick);
        connect(&m_buttonBlue, &QPushButton::clicked, this, &Window::slotBlueButtonClick);
        connect(this, &Window::setColor, &m_openGLWidget, &OpenGLWidget::setColor);
    }
signals:
    void setColor(const QColor &color);
private slots:
    void slotRedButtonClick() {
        m_labelColor.setText("Red");
        emit setColor(QColor(255, 0, 0, 255));
    }
    void slotGreenButtonClick() {
        m_labelColor.setText("Green");
        emit setColor(QColor(0, 255, 0, 255));
    }
    void slotBlueButtonClick() {
        m_labelColor.setText("Blue");
        emit setColor(QColor(0, 0, 255, 255));
    }
private:
    OpenGLWidget m_openGLWidget;
    QHBoxLayout m_hbox;
    QVBoxLayout m_vbox;
    QLabel m_labelColor;
    QPushButton m_buttonRed;
    QPushButton m_buttonGreen;
    QPushButton m_buttonBlue;
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Window w;
    w.show();
    return a.exec();
}
2
Just Do It!
 Аватар для XLAT
4189 / 2644 / 654
Регистрация: 23.09.2014
Сообщений: 8,917
Записей в блоге: 3
22.11.2020, 11:22
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Подсказали здес
спасибо,
оказалось всё просто

но вот чёт файлик по мне тяжеловат, аж 19 Mb для почти пустого проекта...

есть ли способы засунуть верблюда в ушко?
т.е. как-то приуменьшить?
Вложения
Тип файла: rar test.rar (6.59 Мб, 20 просмотров)
0
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
22.11.2020, 13:43
XLAT,
Кликните здесь для просмотра всего текста
мы с вами немного обсудили в личке данный вопрос. Напишите, пожалуйста, в блоге инструкцию для сборки Qt в статику. Отметьте там с какими проблемами столкнулись, до какого размера сжимает UPX. Какие на ваш взгляд плюсы и минусы утилиты UPX, которая используется для сжимания EXE. Какие плюсы и минусы статической и динамической сборок. Qt позволяет использовать три лицензии: GPL, LGPL, коммерческая. Правда, не для всех модулей. Например, QChart может иметь GPL и коммерческую, но не разрешается использовать LGPL. Я знаю, что лицензия GPL позволят собирать в статику (в один EXE), но при этом нужно обеспечить пользователям доступ к исходникам проекта. LGPL позволяет скрывать исходники, но собирать можно только с динамическими библиотеками. Коммерческая позволяет скрывать исходники и собирать в статику. Я думаю, что для индивидуального разработчика и для маленькой команды никто не будет копаться в бинарнике и искать было ли нарушение лицензии. Это актуально для крупных капиталистов, которые на своём уровне могут решить, например, купив коммерческую лицензию Qt, а наёмные программисты будут использовать то, что им скажут. Лицензии для меня имеют очень низкий приоритет, а вот сборка релиза - это важный момент. Я использую пока динамику, для статики место нужно осободить для сборки Qt из исходников в статику. Тот пример, что вы собрали в статику (18 МБайт), я собрал в динамику. Весит 30.8 МБайт. В zip архиве весит 11 МБайт, а в rar - 9 МБайт. КиберФорум позволяет загружать 25 МБайт. Кстати, это я попросил когда-то администрацию повысить: сначала с 10 МБайт до 20 МБайт, а потом ещё на 5 МБайт, потому что сборки Unity в EXE весили как минимум 18 МБайт + небольшие модельки и текстуры, то есть демки могли выходить чуть больше 20 МБайт. Возвращаясь к примеру, что вы скинули, столько файлов нужно для динамики, привожу для справки:


Можете попробовать запустить, если не запустится, то напишите:


По поводу текстур отмечу, что в Qt C++ полная поддержка работы с текстурами. Ничего стороннего подключать не нужно. Более того, Qt C++ позволяет подключать текстуры в виде ресурсов: правой кнопкой по проекту > "Add New..." > "Qt" > "Qt Resource File" > кнопка "Choose..." > ввести имя ресурсов "Textures" > кнопка "Next" > кнопка "Finish" > вводим в Prefix прямой слеш: / > нажать кнопку "Add Files" > выбрать текстуры. Для доступа к текстурам из кода нужно вводить путь с двоеточием и прямым слешем в начале, например: ":/Textures/MyTexture.png". Текстура из ресурсов зашивается внутрь EXE. Таким же образом в ресурсы можно добавить шейдеры. В данном примере вес релизного EXE с текстурой внутри составляет 163 КБайта. Весь самой тестуры - 136 КБайт. Я прикрепил текстуры.

Исходники на 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
// 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 <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent), m_texture(QOpenGLTexture::Target2D) { }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_texCoordBuffer;
    QOpenGLTexture m_texture;
 
    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;"
                "out vec2 vTexCoord;"
                "void main()"
                "{"
                "    gl_Position = 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);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_texture.bind();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    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

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
// 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 <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
 
class Widget : public QOpenGLWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent), m_texture(QOpenGLTexture::Target2D) { }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_texCoordBuffer;
    QOpenGLTexture m_texture;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        resize(400, 400);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "attribute vec2 aTexCoord;"
                "varying vec2 vTexCoord;"
                "void main()"
                "{"
                "    gl_Position = 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);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        m_texture.bind();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
    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();
}



Миниатюра
Изображения
 
Вложения
Тип файла: rar RotatingTriangle_OpenGL33Qt5Cpp.rar (9.07 Мб, 10 просмотров)
Тип файла: zip RotatingTriangle_OpenGL33Qt5Cpp.zip (11.08 Мб, 11 просмотров)
1
Just Do It!
 Аватар для XLAT
4189 / 2644 / 654
Регистрация: 23.09.2014
Сообщений: 8,917
Записей в блоге: 3
22.11.2020, 14:45
дел
1
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
22.11.2020, 18:16
Выставление начала системы координат, диапазонов осей в 2D и правую/левую систему координат. Если не выставить, то начало системы координат будет в центре окна, а диапазоны осей будет: [-1, 1]. Для выставления используется метод QMatrix4x4::ortho:

C++ (Qt)
1
void QMatrix4x4::ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane)
К примеру:

C++ (Qt)
1
2
3
        projMatrix.ortho(-50.f, 50.f, -50.f, 50.f, 50.f, -50.f); // Центр
        projMatrix.ortho(0.f, 100.f, 100.f, 0.f, -100.f, 100.f); // Левый верхний угол 
        projMatrix.ortho(0.f, 100.f, 0.f, 100.f, -100.f, 100.f); // Левый нижний угол
С помощью перемены знаков nearPlane и farPlane можно выставить правую и левую систему координат, которые можно определить с помощью правой и левой руки. Используем третий вариант, то есть начало системы координат в левом нижнем углу, осеь X направлена вправо, ось Y - вверх, а ось Z - на наблюдателя.

В примере рисуется квадрат со сторонами равным 20 с координатами центра в (70, 70):

Исходники на 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
// 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 <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QMatrix4x4>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setWindowTitle("Qt C++, OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        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"
                "void main()"
                "{"
                "    gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);"
                "}";
        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
        };
        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);
        QMatrix4x4 projMatrix;
        projMatrix.ortho(0.f, 100.f, 0.f, 100.f, -100.f, 100.f);
        QMatrix4x4 modelMatrix;
        modelMatrix.translate(QVector3D(70.f, 70.f, 0.f));
        modelMatrix.scale(20.0f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", projMatrix * modelMatrix);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
};
 
#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
// 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 <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QMatrix4x4>
 
class OpenGLWidget : public QOpenGLWidget {
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {
        setWindowTitle("Qt C++, OpenGL");
        resize(268, 268);
    }
private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
 
    void initializeGL() override {
        glClearColor(0.5f, 0.8f, 0.7f, 1.f);
        const char *vertShaderSrc =
                "attribute vec3 aPosition;"
                "uniform mat4 uMvpMatrix;"
                "void main()"
                "{"
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "}";
        const char *fragShaderSrc =
                "void main()"
                "{"
                "    gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);"
                "}";
        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
        };
        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);
        QMatrix4x4 projMatrix;
        projMatrix.ortho(0.f, 100.f, 0.f, 100.f, -100.f, 100.f);
        QMatrix4x4 modelMatrix;
        modelMatrix.translate(QVector3D(70.f, 70.f, 0.f));
        modelMatrix.scale(20.0f);
        m_program.bind();
        m_program.setUniformValue("uMvpMatrix", projMatrix * modelMatrix);
    }
    void paintGL() override {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    void resizeGL(int w, int h) override {
        glViewport(0, 0, w, h);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    OpenGLWidget w;
    w.show();
    return a.exec();
}


Релиз (например, EXE) - это результат работы разработчика, поэтому прикладываю EXE для Windows: Set2DCoordSystem_OpenGL33_Qt5Cpp.zip (11.08 Мб) Это, кстати, здорово заряжает, когда выкладываешь EXE, даже если это кажется бессмысленным.

Название: Set2DCoordSystem_OpenGLES20_Qt5Cpp.png
Просмотров: 248

Размер: 2.5 Кб
Вложения
Тип файла: zip Set2DCoordSystem_OpenGL33_Qt5Cpp.zip (11.08 Мб, 5 просмотров)
1
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
23.11.2020, 12:08
Рисование прямоугольника:

C++ (Qt)
1
2
3
4
5
6
7
8
    void drawRect(float x, float y, float width, float height) {
        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);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
1
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
23.11.2020, 12:24
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Исходники на OpenGL ES 2.0 для Desktop, Android и iOS
Цитата Сообщение от 8Observer8 Посмотреть сообщение
#include <windows.h>
а что в андроиде и iOS есть заголовочный файл windows.h он же для Windows или я не правильно понял?
0
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,962
Записей в блоге: 216
23.11.2020, 12:37
Цитата Сообщение от Antikl Посмотреть сообщение
а что в андроиде и iOS есть заголовочный файл windows.h он же для Windows или я не правильно понял?
C++ (Qt)
1
2
3
4
5
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
Вот эта штука "#ifdef" называется "директива препроцессору". Она работает следующим образом. Если _WIN32 определен, то будет задействовано то, что расположено между "#ifdef" и "#endif". Определён _WIN32 только на Windows. На Window будет "#define _WIN32" При компиляции под Android и iOS вот этого определения не будет: "#define _WIN32".
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
23.11.2020, 14:02
Цитата Сообщение от 8Observer8 Посмотреть сообщение
директива препроцессору
понял, спасибо, забыл про это
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.11.2020, 14:02
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru