Вы должны определить индекс атрибута posAttr
после того, как программа связана:
Q_ASSERT(shader->link());
posAttribute = shader->attributeLocation("posAttr");
Поскольку проверка глубины включена, необходимо очистить буфер глубины.См. glClear
:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Вы не используете какую-либо модель, вид или матрицу проекции, поэтому координаты должны быть установлены в нормализованном пространстве устройства.Это означает, что все координаты должны находиться в диапазоне [-1,0, 1,0], особенно следует учитывать ближнюю и дальнюю плоскости -1,0 и 1,0.По умолчанию функция проверки глубины равна GL_LESS
, поэтому полоса отсечения ограничивается дальней плоскостью, поскольку координата z в 1,0 равна не меньше, чем в дальней плоскости 1,0.Используйте z координату 0,0 для вершин (конечно, что-то вроде 0,99 тоже будет работать):
GLfloat vertices[] = { 0.0f, 0.707f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f };
shader->setAttributeArray(posAttribute,vertices, 3);
3D-параметр glDrawArrays
должен быть числом вершина не количество примитивов:
glDrawArrays(GL_TRIANGLES, 0, 3);
Соответствующие части кода могут выглядеть следующим образом:
void Glwidget::initializeGL()
{
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &Glwidget::cleanup);
initializeOpenGLFunctions();
glClearColor(.0f, .0f, .0f, 1.0f);
shader = new QOpenGLShaderProgram(this);
shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
Q_ASSERT(shader->link());
posAttribute = shader->attributeLocation("posAttr");
Q_ASSERT(shader->bind());
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
void Glwidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat vertices[] = { 0.0f, 0.707f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f };
shader->setAttributeArray(posAttribute,vertices, 3);
glEnableVertexAttribArray(posAttribute);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(posAttribute);
}
Обратите внимание, поскольку Выбор лица включен, у вас естьсоблюдать порядок намотки примитивов (это так, в вашем коде).
Кроме того, как упоминалось @derhass, в комментариях вы должны изменить фрагментный шейдер.Вы должны определить Выходную переменную .(Примечание: используйте Необработанные строковые литералы ):
static const char* fragmentShaderSource = R"(
#version 330 core
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.0, 1.0, 0.0);
}
)";
Предварительный просмотр:
Если вы хотите рисовать линии вместо полигонов, то вы можете сделать это с помощью GL_LINE_LOOP
.См. Линейные примитивы .
glDrawArrays(GL_LINE_LOOP, 0, 3);