/
glwidget.cpp
134 lines (111 loc) · 4.13 KB
/
glwidget.cpp
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
#include "glwidget.h"
/// шейдеры для рисования (определяем статически, можно конечно же потом грузить из файла)
static const char *vertexShaderSource =
"#version 330 core\n"
"uniform mat4 projectionMatrix;\n"
"in vec3 position;\n"
"in vec3 color;\n"
"out vec3 fragmentColor;\n"
"void main(void) {\n"
// перевод вершинных координат в однородные
"gl_Position = projectionMatrix * vec4(position, 1.0);\n"
// передаем цвет вершины в фрагментный шейдер
"fragmentColor = color; }\n";//*/
static const char *fragmentShaderSource =
"#version 330 core\n"
"in vec3 fragmentColor;\n"
"out vec4 color;\n"
"void main(void) {\n"
// зададим цвет пикселя
"color = vec4(fragmentColor, 1.0); }\n";//*/
GLWidget::GLWidget( const QGLFormat& format, QWidget* parent )
: QGLWidget( format, parent ),
m_vertexBuffer( QGLBuffer::VertexBuffer )
{
}
void GLWidget::initializeGL()
{
QGLFormat glFormat = QGLWidget::format();
if ( !glFormat.sampleBuffers() )
qWarning() << "Could not enable sample buffers";
// Set the clear color to black
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
// Prepare a complete shader program…
if ( !prepareShaderProgram( ":/simple.vert", ":/simple.frag" ) )
return;
// We need us some vertex data. Start simple with a triangle ;-)
float points[] = {-0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f,
0.0f, 0.5f, 0.0f, 1.0f};
m_vertexBuffer.create();
m_vertexBuffer.setUsagePattern( QGLBuffer::StaticDraw );
if ( !m_vertexBuffer.bind() )
{
qWarning() << "Could not bind vertex buffer to the context";
return;
}
m_vertexBuffer.allocate( points, 3 * 4 * sizeof( float ) );
// Bind the shader program so that we can associate variables from
// our application to the shaders
if ( !m_shader.bind() )
{
qWarning() << "Could not bind shader program to context";
return;
}
// Enable the "vertex" attribute to bind it to our currently bound
// vertex buffer.
m_shader.setAttributeBuffer( "vertex", GL_FLOAT, 0, 4 );
m_shader.enableAttributeArray( "vertex" );
/*glfuncs = m_context->versionFunctions();
if (!glfuncs) {
qDebug()<<"Не поддерживается версия OpenGL этой программой.";
exit(1); //Хъюстон, у нас проблема номер раз
}
glfuncs->initializeOpenGLFunctions();
uint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);//*/
qDebug() << QString((const char*)glGetString(GL_VERSION)) << "\n" << QString((const char*)glGetString(GL_VENDOR))<< "\n" << QString((const char*)glGetString(GL_RENDERER));//<< "\n" << glGetString(GL_EXTENTIONS);
}
bool GLWidget::prepareShaderProgram( const QString& vertexShaderPath,
const QString& fragmentShaderPath )
{
// First we load and compile the vertex shader…
//bool result = m_shader.addShaderFromSourceFile( QGLShader::Vertex, vertexShaderPath );
bool result = m_shader.addShaderFromSourceCode(QGLShader::Vertex, vertexShaderSource);
if ( !result )
qWarning() << m_shader.log();
// …now the fragment shader…
//result = m_shader.addShaderFromSourceFile( QGLShader::Fragment, fragmentShaderPath );
result = m_shader.addShaderFromSourceCode(QGLShader::Fragment, fragmentShaderSource);
if ( !result )
qWarning() << m_shader.log();
// …and finally we link them to resolve any references.
result = m_shader.link();
if ( !result )
qWarning() << "Could not link shader program:" << m_shader.log();
return result;
}
void GLWidget::resizeGL( int w, int h )
{
// Set the viewport to window dimensions
glViewport( 0, 0, w, qMax( h, 1 ) );
}
void GLWidget::paintGL()
{
// Clear the buffer with the current clearing color
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Draw stuff
glDrawArrays( GL_TRIANGLES, 0, 3 );
}
void GLWidget::keyPressEvent( QKeyEvent* e )
{
switch ( e->key() )
{
case Qt::Key_Escape:
QCoreApplication::instance()->quit();
break;
default:
QGLWidget::keyPressEvent( e );
}
}