Qt Opengl-QOpenGLTexture-3D

  • 关于纹理,可以理解为图像数据,在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

猜你喜欢

转载自blog.csdn.net/qq_39175540/article/details/85337711