Qt Opengl-QOpenGLTexture-3D
阿新 • • 發佈:2019-01-11
- 關於紋理,可以理解為影象資料,在2D紋理中,就是將一張影象蓋在模型上,模型中空;至於3D紋理,就可以解釋為若干張影象,在通俗講就是多維陣列,多層切片的實體。
- 紋理座標,x軸水平向右,y軸垂直向上,z軸朝向螢幕內,可以看作是3維座標下的第一象限的單元格。
- 紋理貼圖,可以理解為,斷續的頂點資料和多維資料建立一個map(這是我們常規理解,當然也可以是紋理到頂點的map)
一個矩形上貼一個圖片,如下:
/* 頂點 紋理 * x y z x y z * -0.5, -0.5, 0, 0, 0, 0 * 0.5, -0.5, 0, 1, 0, 0 * 0.5, 0.5, 0, 1, 1, 0, * -0.5, 0.5, 0, 0, 1, 0, */
下面說說3D紋理的理解
void CubeRender::initTexture() { // 圖片的寬,高,圖片的張數 int width; int height; int count // QImage imageList 載入 // 將imageList資料拷貝到buffer,image的格式Format_RGBA8888 uchar *buffer = getImageData(imageList); // 建立3D紋理 m_texture = new QOpenGLTexture(QOpenGLTexture::Target3D); m_texture->create(); m_texture->setSize(width, height, count); m_texture->setFormat(QOpenGLTexture::RGBA8_UNorm); m_texture->allocateStorage(); // 紋理資料填充 m_texture->setData(QOpenGLTexture::RGBA,QOpenGLTexture::UInt8,buffer); // 過濾處理 m_texture->setMinMagFilters(QOpenGLTexture::Nearest,QOpenGLTexture::Nearest); // 3軸環繞 m_texture->setWrapMode(QOpenGLTexture::DirectionS,QOpenGLTexture::ClampToEdge); m_texture->setWrapMode(QOpenGLTexture::DirectionT,QOpenGLTexture::ClampToEdge); m_texture->setWrapMode(QOpenGLTexture::DirectionR,QOpenGLTexture::ClampToEdge); delete [] buffer; buffer = nullptr; }
這樣,我們就做好一個3D紋理,使用時
// 頂點資料(頂點座標,紋理座標) void CubeRender::render(QMatrix4x4 vpmat){ m_buffer.bind(); m_indexBuffer.bind(); m_shaderPro->bind(); // 使用一個紋理,因為我們只建立了一個 m_shaderPro->setUniformValue("qt_Texture0", 0); // 頂點座標 m_shaderPro->enableAttributeArray(0); m_shaderPro->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(QVector3D)); // 紋理座標 m_shaderPro->enableAttributeArray(1); m_shaderPro->setAttributeBuffer(1, GL_FLOAT, sizeof(QVector3D)*vertexVec.length(), 3, sizeof(QVector3D)); // 矩陣 QMatrix4x4 modelMat; modelMat.setToIdentity(); m_shaderPro->setUniformValue("qt_ModelViewProjectionMatrix",vpmat * modelMat); // 3D紋理繫結 m_texture->bind(); // 繪製 因為我們使用了索引buffer即EBO glDrawElements(GL_QUADS, 24, GL_UNSIGNED_SHORT, nullptr); // 釋放 m_texture->release(); m_shaderPro->release(); m_indexBuffer.release(); m_buffer.release(); }
著色器部分,紋理座標通過屬性由程式傳給頂點著色器,進而中傳給片元著色器
/***頂點著色器***/
attribute vec4 qt_Vertex;
// 紋理座標
attribute vec3 qt_MultiTexCoord0;
uniform mat4 qt_ModelViewProjectionMatrix;
// 中傳紋理座標
varying vec3 qt_TexCoord0;
void main(void)
{
gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex;
qt_TexCoord0 = qt_MultiTexCoord0;
}
/***片元著色器***/
uniform sampler3D qt_Texture0;
varying vec3 qt_TexCoord0;
void main(void)
{
gl_FragColor = texture3D(qt_Texture0, qt_TexCoord0);
}
-
QOpenGLBuffer,buffer的型別,VBO/EBO;buffer的用法,static/Dynamic