qt opengl 混合实现半透明

30 篇文章 10 订阅

     在二维绘图里面的半透明很简单,把alpha通道的值不设置为1或者255就能看见后面的物体;后面物体的清晰度根据设置值的大小来决定。而在opengl中要实现半透明效果也很简单,但相比二维绘图还是要麻烦一些了。

      其方法为启用GL_BLEND混合功能,设置混合因子;这样opengl就会用混合因子将前、后两个物体颜色进行混合;这里有很多种混合方式,可以只显示前面物体,也可以只显示后面物体,也可以像素叠加(分为rgb叠加,alpha叠加)等待。

     我实现的效果如下

      实现相比以前简单得多,就设置了下启用GL_BLEND功能,和设置混合因子。其它的渲染器我是用的前面的现成的

这里我只介绍绿色图片的混合实现,其渲染器很简单就是一个普通的纹理2d图片

#ifndef IMAGERENDER_H
#define IMAGERENDER_H

#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLExtraFunctions>
class ImageRender
{
public:
    ImageRender() = default;
    ~ImageRender();
    void initsize(QString fileName);
    void render(QOpenGLExtraFunctions *f,QMatrix4x4 &pMatrix,QMatrix4x4 &vMatrix,QMatrix4x4 &mMatrix);

private:
    QOpenGLShaderProgram program_;
    QOpenGLTexture *texture_{nullptr};
    QOpenGLBuffer vbo_;
};

#endif // IMAGERENDER_H
#include "imagerender.h"

ImageRender::~ImageRender()
{
    texture_->destroy();
    delete texture_;
}

void ImageRender::initsize(QString fileName)
{
    program_.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,"vsrc.vert");
    program_.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,"fsrc.frag");
    program_.link();

    texture_ = new QOpenGLTexture(QImage(fileName));
    texture_->setMinificationFilter(QOpenGLTexture::LinearMipMapNearest);
    texture_->setMagnificationFilter(QOpenGLTexture::LinearMipMapLinear);
    texture_->setWrapMode(QOpenGLTexture::DirectionS,QOpenGLTexture::ClampToEdge);
    texture_->setWrapMode(QOpenGLTexture::DirectionT,QOpenGLTexture::ClampToEdge);
    GLfloat points[4 * 3 + 8]{
        -1.0,-1.0,0.0,
        +1.0,-1.0,0.0,
        +1.0,+1.0,0.0,
        -1.0,+1.0,0.0,

        0.0,1.0,
        1.0,1.0,
        1.0,0.0,
        0.0,0.0
    };
    vbo_.create();
    vbo_.bind();
    vbo_.allocate(points, sizeof points);
}

void ImageRender::render(QOpenGLExtraFunctions *f, QMatrix4x4 &pMatrix, QMatrix4x4 &vMatrix, QMatrix4x4 &mMatrix)
{
    f->glEnable(GL_DEPTH_TEST);
    f->glEnable(GL_CULL_FACE);

    program_.bind();
    vbo_.bind();
    f->glActiveTexture(GL_TEXTURE0 + 0);
    program_.setUniformValue("sTexture",0);
    program_.setUniformValue("uPMatrix",pMatrix);
    program_.setUniformValue("uVMatrix",vMatrix);
    program_.setUniformValue("uMMatrix",mMatrix);
    program_.enableAttributeArray(0);
    program_.enableAttributeArray(1);

    program_.setAttributeBuffer(0,GL_FLOAT,0,3,3 * sizeof GLfloat);
    program_.setAttributeBuffer(1,GL_FLOAT,4 * 3 * sizeof GLfloat, 2, 2 * sizeof GLfloat);
    texture_->bind(0);
    f->glDrawArrays(GL_TRIANGLE_FAN,0,4);

    program_.disableAttributeArray(0);
    program_.disableAttributeArray(1);
    texture_->release();
    vbo_.release();
    program_.release();

    f->glDisable(GL_DEPTH_TEST);
    f->glDisable(GL_CULL_FACE);
}

其shader如下

#version 330
uniform mat4 uPMatrix,uVMatrix,uMMatrix;
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec2 aTexture;
smooth out vec2 vTextureCood;

void main(void)
{
    gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aPosition,1);
    vTextureCood = aTexture;
}
#version 330
uniform sampler2D sTexture;
in vec2 vTextureCood;
out vec4 fragColor;

void main(void)
{
    fragColor = texture2D(sTexture,vTextureCood);
}

  其它的还用到了mipmap纹理渲染器,和一个obj模型渲染器,在前面有就不介绍了。在使用时根据需要打开混合功能。

    mMatrix.setToIdentity();
    mMatrix.translate(3,1,10);
    imageRender_.render(f,pMatrix,vMatrix,mMatrix); //不启用混合

    f->glEnable(GL_BLEND); //启用混合
    mMatrix.setToIdentity();
    mMatrix.translate(-1.2,1.6,10);
    mMatrix.scale(1.2);
    f->glBlendFunc(GL_SRC_COLOR,GL_ONE_MINUS_SRC_COLOR); //用前物体因子用rgba、后物体因子为前物体rgba的1-前物体的rgba值(opengl中颜色值为0-1)。实现的效果类似于透过有色玻璃看物体
    imageRender_.render(f,pMatrix,vMatrix,mMatrix);

    mMatrix.setToIdentity();
    mMatrix.translate(1.0,2.6,10);
    f->glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //以前物体的透明度为基准,前物体全透明,就只能看见后面的物体;前物体半透明,就能看见后面物体。
    imageRender1_.render(f,pMatrix,vMatrix,mMatrix);
    f->glDisable(GL_BLEND);//关闭混合

  源码到此下载https://download.csdn.net/download/wanghualin033/10854601

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt OpenGLQt框架中的一个模块,用于在Qt应用程序中使用OpenGL。它提供了一组类和函数,使得开发者可以轻松地在Qt应用中实现图形渲染和交互。 要使用Qt OpenGL实现室内移动,我们可以按照以下步骤进行: 1. 创建Qt OpenGL窗口:使用QOpenGLWidget类创建一个新的窗口,该窗口将用于显示OpenGL渲染的图形。在这个窗口中,可以自定义视图和交互方式。 2. 加载室内地图:将室内地图的数据加载到Qt应用程序中。可以使用OpenGL的纹理映射功能将地图贴到墙壁和地面上,以实现真实感的效果。 3. 实现相机控制:实现相机控制以实现室内移动。可以通过鼠标和键盘事件来控制相机的位置和朝向。例如,使用鼠标移动来改变相机的视角,使用键盘控制相机的移动方向。可以使用OpenGL的矩阵操作来实现相机控制。 4. 实现物体的渲染:根据需要,在室内地图中渲染出其他的物体,例如家具、人物等。可以使用OpenGL的3D模型加载功能来实现物体的加载和渲染。 5. 实现碰撞检测:为了使室内移动更加真实,可以实现碰撞检测功能。例如,当相机接近墙壁时,禁止相机继续前进,或者当相机碰撞到其他物体时,禁止相机继续移动。 6. 实现光照效果:为了实现更逼真的室内场景,可以添加光照效果。可以使用OpenGL的光源和材质属性来设置光照效果,例如点光源、聚光灯等。 通过以上步骤,我们可以使用Qt OpenGL实现室内移动。这样的应用程序可以用于虚拟现实、游戏开发、建筑可视化等领域,提供交互和沉浸式的体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值