我是OpenGL新手,我正在学习多个教程,我注意到有多个方法用于呈现对象,但我仍然不知道它们之间的区别以及何时使用它们?
例如..。我遵循这个使用着色器渲染立方体的示例,当我试图用“正常”的方式呈现它时--如果这是一个正确的表达式。什么都没有呈现出来。我总是需要打电话给shaderProgram.setAttributeArray(),shaderProgram.enableAttributeArray()和shaderProgram.disableAttributeArray()
但是,如果我试图使用另一种方式直接呈现它--如果这是一个正确的表达式--使用glBegin()和glEnd()。什么都不起作用
另外,我还有另一个问题--着色器的概念本身,我真的不明白什么时候应该使用它,什么时候不应该使用它
以下是我的例子:
#include "glwidget.h"
GlWidget::GlWidget(QWidget *parent)
: QGLWidget(QGLFormat(/* Additional format options */), parent)
{
alpha = 25;
beta = -25;
distance = 2.5;
}
void GlWidget::initializeGL()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
qglClearColor(QColor(Qt::white));
shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
shaderProgram.link();
vertices << QVector3D(-0.5, -0.5, 0.5) << QVector3D( 0.5, -0.5, 0.5) << QVector3D( 0.5, 0.5, 0.5) // Front
<< QVector3D( 0.5, 0.5, 0.5) << QVector3D(-0.5, 0.5, 0.5) << QVector3D(-0.5, -0.5, 0.5)
<< QVector3D( 0.5, -0.5, -0.5) << QVector3D(-0.5, -0.5, -0.5) << QVector3D(-0.5, 0.5, -0.5) // Back
<< QVector3D(-0.5, 0.5, -0.5) << QVector3D( 0.5, 0.5, -0.5) << QVector3D( 0.5, -0.5, -0.5)
<< QVector3D(-0.5, -0.5, -0.5) << QVector3D(-0.5, -0.5, 0.5) << QVector3D(-0.5, 0.5, 0.5) // Left
<< QVector3D(-0.5, 0.5, 0.5) << QVector3D(-0.5, 0.5, -0.5) << QVector3D(-0.5, -0.5, -0.5)
<< QVector3D( 0.5, -0.5, 0.5) << QVector3D( 0.5, -0.5, -0.5) << QVector3D( 0.5, 0.5, -0.5) // Right
<< QVector3D( 0.5, 0.5, -0.5) << QVector3D( 0.5, 0.5, 0.5) << QVector3D( 0.5, -0.5, 0.5)
<< QVector3D(-0.5, 0.5, 0.5) << QVector3D( 0.5, 0.5, 0.5) << QVector3D( 0.5, 0.5, -0.5) // Top
<< QVector3D( 0.5, 0.5, -0.5) << QVector3D(-0.5, 0.5, -0.5) << QVector3D(-0.5, 0.5, 0.5)
<< QVector3D(-0.5, -0.5, -0.5) << QVector3D( 0.5, -0.5, -0.5) << QVector3D( 0.5, -0.5, 0.5) // Bottom
<< QVector3D( 0.5, -0.5, 0.5) << QVector3D(-0.5, -0.5, 0.5) << QVector3D(-0.5, -0.5, -0.5);
}
void GlWidget::resizeGL(int width, int height)
{
if (height == 0) {
height = 1;
}
pMatrix.setToIdentity();
pMatrix.perspective(60.0, (float) width / (float) height, 0.001, 1000);
glViewport(0, 0, width, height);
}
void GlWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 mMatrix;
QMatrix4x4 vMatrix;
QMatrix4x4 cameraTransformation;
cameraTransformation.rotate(alpha, 0, 1, 0);
cameraTransformation.rotate(beta, 1, 0, 0);
QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, distance);
QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection);
shaderProgram.bind();
shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
// This code is able to draw the cube
shaderProgram.setAttributeArray("vertex", vertices.constData());
shaderProgram.enableAttributeArray("vertex");
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
shaderProgram.disableAttributeArray("vertex");
// end
// This code is never able to draw the cube or anything
glBegin(GL_TRIANGLES);
for (int var = 0; var < vertices.size(); ++var) {
glVertex3f(vertices[var][0],vertices[var][1],vertices[var][2]);
}
glEnd();
// end
shaderProgram.release();
}发布于 2015-01-12 22:57:13
OpenGL过去有一个叫做"即时模式“的词。在它中,您将使用glBegin()和glEnd(),并在它们之间逐点指定数据(点、法线、纹理坐标)。你会在每一帧上都这样做,所以很明显这是非常慢的。这个功能早就被废弃了,但是大多数显卡驱动程序仍然支持它,以免破坏现有的软件。但是,如果您想学习现代OpenGL,我将忽略任何在其中包含glBegin()的教程。今天,您可以一次将数据传输到GPU (进入名为顶点缓冲对象的东西),然后使用一个命令(使用顶点阵列对象)进行绘制。
你的另一个问题是关于着色器。同样地,在过去的日子里,OpenGL曾经有一个固定功能管道。这意味着你只提供顶点(普通的,.)数据和图形卡继续并做它的事情。无法修改它对数据所做的操作。在现代世界中,管道的某些部分是可编程的,这意味着您可以改变管道的某些部分所做的事情(通过提供自己的程序- 着色器)。这是非常有用的,因为有许多影响是不可能达到的。同样,如果你不提供你自己的着色器,图形卡将大部分回到默认的实现,因为兼容性的原因。但是你绝对应该写你自己的着色器(基本的只有几行)。
总之,如果您开始学习现代OpenGL (VBO、VAOs、着色器),可能需要更长的时间来完成基础知识,但是如果您开始学习传统的东西,有一天您将不得不离开它,从头开始学习现代OpenGL。
编辑:将现代代码和遗留代码混合在一起通常不是一个好主意。你也许能让它起作用,但这不值得你这么做。
https://stackoverflow.com/questions/27910741
复制相似问题