Qt5中包含了OpenGL模塊,並且對其進行了一些封裝,下面就Qt5中OpenGL的程序寫法舉例:
Qt5中雖然包含了OpenGL,但是沒有添加“glu.h>”庫,所以有些以前在Qt4中的寫法會不太成功,比如設置投影矩陣等,具體方法可以參考:http://blog.csdn.net/ccf19881030/article/details/17842981中的做法。
但是在下面的例子中沒有加入glu庫,是完全基於Qt中OpenGL寫的。
實驗平臺
VS2010+Qt5.5;
實驗步驟
- 新建Qt工程,包含QOpenGL模塊
在控件中可以加入QOpenGLWidget控件,但是也可以對其做提升。代碼如下:
class OpenGLWidget : public QOpenGLWidget , protected QOpenGLFunctions
{
Q_OBJECT
public:
OpenGLWidget(QWidget *parent=0);
~OpenGLWidget();
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
2.初始化工作
OpenGLWidget::OpenGLWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
QSurfaceFormat format;
format.setDepthBufferSize(24);
setFormat(format);
setMouseTracking(false);
}
3.設置視圖模型投影矩陣
Qt5中OpenGL的視圖-投影矩陣是要自己設置的,不再免費提供。故:
QMatrix4x4 mModelMatrix;//模型矩陣
QMatrix4x4 mViewMatrix; //視圖矩陣
QMatrix4x4 mProjectionMatrix; //投影矩陣
QMatrix4x4 mMVPMatrix; //MVP矩陣
最後mMVPMatrix = mProjectionMatrix * mViewMatrix * mModelMatrix;
4.着色器
GLSL是OpenGL着色語言的統稱,是一種編程語言,在應用程序中使用頂點或片段着色器,按照如下步驟:
對於每個着色器對象:
- 創建着色器對象;
- 把着色器源代碼編譯爲目標代碼;
驗證;
然後將多個着色器對象鏈接到一個着色器程序中,需要:創建一個着色器程序;
- 將着色器對象鏈接到程序;
- 鏈接着色器程序;
- 驗證;
着色器代碼解讀:
const GLchar *vshader_source =
"attribute vec4 posAttr;\n"
"uniform mat4 matrix;\n"
"void main() {\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
const GLchar *cshader_source =
"uniform vec4 color;\n"
"void main(){\n"
" gl_FragColor= color;\n"
"}\n";
“attribute”表示輸入變量,輸出爲”varying”。”uniform”限定一個變量的值由應用程序在着色器執行之前指定,並且在圖圓的處理過程中不會變化。
“vec4”是類似於QVector4D,”mat4”類似QMatrix4x4;
5.代碼工作
void OpenGLWidget::resizeGL(int w, int h)
{
mProjectionMatrix.setToIdentity();
mProjectionMatrix.perspective(60.0f, w / float(h), 0.01f, 1000.0f);//投影矩陣
}
void OpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
shadercode();
}
void OpenGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mModelMatrix.setToIdentity();
mModelMatrix.rotate(angles, 0.0f, 1.0f, 0.0f);
drawelem();
OpenGLWidget::update();//刷新
}
void OpenGLWidget::shadercode()
{
const GLchar *vshader_source =
"attribute vec4 posAttr;\n"
"uniform mat4 matrix;\n"
"void main() {\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
const GLchar *cshader_source =
"uniform vec4 color;\n"
"void main(){\n"
" gl_FragColor= color;\n"
"}\n";
angles=0.0;
m_shaderprogram=new QOpenGLShaderProgram(this);
QOpenGLShader vecShader(QOpenGLShader::Vertex);
vecShader.compileSourceCode(vshader_source);
QOpenGLShader colShader(QOpenGLShader::Fragment);
//vec_handl=m_shaderprogram->addShaderFromSourceCode(QOpenGLShader::Vertex,vshader_source);
//col_handl=m_shaderprogram->addShaderFromSourceCode(QOpenGLShader::Fragment,cshader_source);
colShader.compileSourceCode(cshader_source);
m_shaderprogram->addShader(&vecShader);
m_shaderprogram->addShader(&colShader);
m_shaderprogram->link();
vec_handl=m_shaderprogram->attributeLocation("posAttr");
col_handl=m_shaderprogram->uniformLocation("color");
mvp_handl=m_shaderprogram->uniformLocation("matrix");
mViewMatrix.lookAt(QVector3D(0.0f, 0.0f, -3.0f), QVector3D(0.0f, 0.0f, 1.0f), QVector3D(0.0f, 1.0f, 0.0f));
}
void OpenGLWidget::drawelem()
{
static GLfloat const triangleVertices[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f
};
QVector4D colors(1.0f, 1.0f, 0.0f, 1.0f) ;
mMVPMatrix = mProjectionMatrix * mViewMatrix * mModelMatrix;
m_shaderprogram->enableAttributeArray(vec_handl);
m_shaderprogram->setAttributeArray(vec_handl,triangleVertices,3);
m_shaderprogram->setUniformValue(mvp_handl,mMVPMatrix);
m_shaderprogram->setUniformValue("color",colors);
glDrawArrays(GL_TRIANGLES, 0, 3);
m_shaderprogram->bind();
m_shaderprogram->disableAttributeArray(vec_handl);
m_shaderprogram->disableAttributeArray(col_handl);
}