使用坐标数组在 QOpenGLWidget 中绘制 GL_LINE
Draw GL_LINE in QOpenGLWidget using array of coordinates
我已经使用 QtCreator 完成了工作应用程序。我的渲染 class 是
GLRendWindow::GLRendWindow(QWidget *parent): QOpenGLWidget(parent)
现在我想使用带有顶点坐标的数组来绘制对象。
我在这个页面上找到了一些绘制三角形的教程:
OpenGL Window Example
我试着重复使用它来画简单的线
void GLRendWindow::drawLine()
{
GLfloat line[] =
{
0.5f, 1.0f,
0.5f, -1.0f
};
GLfloat line_colors[] =
{
1.0f, 0.0f, 0.0f, // red
0.0f, 0.0f, 1.0f, // blue
};
shaderProgram->bind();
glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, 0, line);
glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
glEnableVertexAttribArray(colAttr);
glEnableVertexAttribArray(posAttr);
glDrawArrays(GL_LINE, 0, 2);
glDisableVertexAttribArray(posAttr);
glDisableVertexAttribArray(colAttr);
shaderProgram->release();
}
也是我的初始化方法
void GLRendWindow::initializeGL()
{
initializeOpenGLFunctions();
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
shaderProgram = new QOpenGLShaderProgram(this);
shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
shaderProgram->link();
posAttr = shaderProgram->attributeLocation("posAttr");
colAttr = shaderProgram->attributeLocation("colAttr");
}
和绘制方法
void GLRendWindow::paintGL()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
drawLine();
if (isUpdated)
{
//some other stuff
isUpdated = false;
}
glFlush();
}
和调整大小方法
void GLRendWindow::resizeGL(int w, int h)
{
glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
if ( w < h && w > 0 )
{
glFrustum( - 1.0, 1.0, - 1.0 * h / w, 1.0 * h / w, 1.0, 5.0 );
}
else
{
if ( w >= h && h > 0 )
{
glFrustum( - 0.3 * w / h, 0.3 * w / h, - 0.3, 0.3, 0.5, 5.0 );
}
}
}
但是当我运行应用程序时,没有绘制任何东西。没有错误,没有异常,什么都没有。
在本教程中,我看到
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";
这里可能隐藏了解决方案,但我完全不明白它是什么以及这里发生了什么。我什至不确定这是否是绘制简单线条所必需的。
我应该怎么做才能使用坐标数组看到直线?
您错过了为颜色属性设置指定通用顶点属性数据的数组 (attribute lowp vec4 colAttr;
)。这类似于指定顶点属性。
例如,将以下代码添加到 GLRendWindow::drawLine
:
GLfloat line_colors[] =
{
1.0f, 0.0f, 0.0f, // red
0.0f, 0.0f, 1.0f // blue
};
glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
glEnableVertexAttribArray(colAttr);
您没有指定颜色属性数组,所以colAttr
的值默认为(0, 0, 0)。其实你是在黑底上画一条黑线。
您正在混合不同的技术。您有一个带有矩阵 Uniform:
的着色器程序
uniform highp mat4 matrix;\n"
void main() {
// [...]
gl_Position = matrix * posAttr;
}
你根本就没有设置这身制服。相反,您尝试设置遗留的 OpenGL 固定函数矩阵。遗留电流矩阵的内容并没有神奇地出现在单一变量中。
使用setUniformValue
设置矩阵uniform的值:
QMatrix4x4 matrix;
int matrix_location = shaderprogram->uniformLocation("matrix");
matrix.setToIdentity();
shaderprogram->setUniformValue(matrix_location, matrix);
问题也出在这里
glDrawArrays(GL_LINE, 0, 2);
应该是
glDrawArrays(GL_LINES, 0, 2);
我不得不改变
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
到
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = posAttr;\n"
"}\n";
我已经使用 QtCreator 完成了工作应用程序。我的渲染 class 是
GLRendWindow::GLRendWindow(QWidget *parent): QOpenGLWidget(parent)
现在我想使用带有顶点坐标的数组来绘制对象。
我在这个页面上找到了一些绘制三角形的教程:
OpenGL Window Example
我试着重复使用它来画简单的线
void GLRendWindow::drawLine()
{
GLfloat line[] =
{
0.5f, 1.0f,
0.5f, -1.0f
};
GLfloat line_colors[] =
{
1.0f, 0.0f, 0.0f, // red
0.0f, 0.0f, 1.0f, // blue
};
shaderProgram->bind();
glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, 0, line);
glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
glEnableVertexAttribArray(colAttr);
glEnableVertexAttribArray(posAttr);
glDrawArrays(GL_LINE, 0, 2);
glDisableVertexAttribArray(posAttr);
glDisableVertexAttribArray(colAttr);
shaderProgram->release();
}
也是我的初始化方法
void GLRendWindow::initializeGL()
{
initializeOpenGLFunctions();
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
shaderProgram = new QOpenGLShaderProgram(this);
shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
shaderProgram->link();
posAttr = shaderProgram->attributeLocation("posAttr");
colAttr = shaderProgram->attributeLocation("colAttr");
}
和绘制方法
void GLRendWindow::paintGL()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
drawLine();
if (isUpdated)
{
//some other stuff
isUpdated = false;
}
glFlush();
}
和调整大小方法
void GLRendWindow::resizeGL(int w, int h)
{
glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
if ( w < h && w > 0 )
{
glFrustum( - 1.0, 1.0, - 1.0 * h / w, 1.0 * h / w, 1.0, 5.0 );
}
else
{
if ( w >= h && h > 0 )
{
glFrustum( - 0.3 * w / h, 0.3 * w / h, - 0.3, 0.3, 0.5, 5.0 );
}
}
}
但是当我运行应用程序时,没有绘制任何东西。没有错误,没有异常,什么都没有。 在本教程中,我看到
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";
这里可能隐藏了解决方案,但我完全不明白它是什么以及这里发生了什么。我什至不确定这是否是绘制简单线条所必需的。
我应该怎么做才能使用坐标数组看到直线?
您错过了为颜色属性设置指定通用顶点属性数据的数组 (attribute lowp vec4 colAttr;
)。这类似于指定顶点属性。
例如,将以下代码添加到 GLRendWindow::drawLine
:
GLfloat line_colors[] =
{
1.0f, 0.0f, 0.0f, // red
0.0f, 0.0f, 1.0f // blue
};
glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
glEnableVertexAttribArray(colAttr);
您没有指定颜色属性数组,所以colAttr
的值默认为(0, 0, 0)。其实你是在黑底上画一条黑线。
您正在混合不同的技术。您有一个带有矩阵 Uniform:
的着色器程序uniform highp mat4 matrix;\n" void main() { // [...] gl_Position = matrix * posAttr; }
你根本就没有设置这身制服。相反,您尝试设置遗留的 OpenGL 固定函数矩阵。遗留电流矩阵的内容并没有神奇地出现在单一变量中。
使用setUniformValue
设置矩阵uniform的值:
QMatrix4x4 matrix;
int matrix_location = shaderprogram->uniformLocation("matrix");
matrix.setToIdentity();
shaderprogram->setUniformValue(matrix_location, matrix);
问题也出在这里
glDrawArrays(GL_LINE, 0, 2);
应该是
glDrawArrays(GL_LINES, 0, 2);
我不得不改变
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
到
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = posAttr;\n"
"}\n";