WEN_MONSTER 2022-01-10 10:17 采纳率: 0%
浏览 19
已结题

OpenGL纹理边缘颜色为什么是对称边的颜色?

我拿qt-opengl做一个体数据的三维可视化,先创建QOpenGLBuffer模型,然后把数据填入QImage并应用在QOpenGLTexture,最后在显示时把纹理贴在对应模型面上。
现在问题是显示出来结果中间没问题,但边缘颜色是对称边的颜色,如图左边缘颜色是右边缘的,上边缘是下边缘的,(因为其他需求,现在这个面分成了4个部分,这不重要,合在一起就是中间那两条线没了,但整体还是边缘颜色对称的)。

img

部分实现

void Widgets3D::initializeGL()
{
    initializeOpenGLFunctions();
    makeObject();

#define PROGRAM_VERTEX_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1

    vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char* vsrc =
        "attribute highp vec4 vertex;\n"
        "attribute mediump vec4 texCoord;\n"
        "varying mediump vec4 texc;\n"
        "uniform mediump mat4 matrix;\n"
        "void main(void)\n"
        "{\n"
        "    gl_Position = matrix * vertex;\n"
        "    texc = texCoord;\n"
        "}\n";
    vshader->compileSourceCode(vsrc);

    fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char* fsrc =
        "uniform sampler2D texture;\n"
        "varying mediump vec4 texc;\n"
        "void main(void)\n"
        "{\n"
        "    gl_FragColor = texture2D(texture, texc.st);\n"
        "}\n";
    fshader->compileSourceCode(fsrc);

    program = new QOpenGLShaderProgram;
    program->addShader(vshader);
    program->addShader(fshader);
    program->link();
}

void Widgets3D::paintGL()
{
    glClearColor(0.95, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    program->bind();
    QMatrix4x4 m;
    if (height() > width())
        m.ortho(-0.5f, +0.5f, +0.5f * height() / width(), -0.5f * height() / width(), 4.0f, 15.0f);
    else
        m.ortho(-0.5f * width() / height(), +0.5f * width() / height(), +0.5f, -0.5f, 4.0f, 15.0f);
    m.translate(0.0f, 0.0f, -10.0f);
    m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f);
    m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);
    m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);
    program->setUniformValue("matrix", m);
    program->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
    program->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
    program->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat));
    program->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat));
    
    if ((xRot % 5760 >= 0 && xRot % 5760 < (360 * 4) && yRot % 5760 >= (360 * 12) && yRot % 5760 < (360 * 16)) ||
        (xRot % 5760 >= (360 * 4) && xRot % 5760 < (360 * 8) && yRot % 5760 >= (360 * 4) && yRot % 5760 < (360 * 8)))
    {
        if (showX) { SideTexture[0]->bind(); glDrawArrays(GL_TRIANGLE_FAN, 0 * 4, 4); }
        //...其他纹理
    }
    //...其他情况
    program->release();
}

void Widgets3D::makeObject(void)
{
    if (_type == 0) DrawXSide<int>(xPos, mapX);
    else if (_type == 1) DrawXSide<float>(xPos, mapX);
    else if (_type == 2) DrawXSide<double>(xPos, mapX);
    QImage mapX1 = mapX->copy(0, 0, yPos + 1, zPos + 1);
    QImage mapX2 = mapX->copy(0, zPos, yPos + 1, _sizeZ - zPos);
    QImage mapX3 = mapX->copy(yPos, 0, _sizeY - yPos, zPos + 1);
    QImage mapX4 = mapX->copy(yPos, zPos, _sizeY - yPos, _sizeZ - zPos);
    SideTexture[0] = new QOpenGLTexture(mapX1.mirrored());
    SideTexture[1] = new QOpenGLTexture(mapX2.mirrored());
    SideTexture[2] = new QOpenGLTexture(mapX3.mirrored());
    SideTexture[3] = new QOpenGLTexture(mapX4.mirrored());
    //...其他面
    creatVbo();
}

void Widgets3D::creatVbo(void)
{
    double coords[7][4][3] = {/*...各面位置*/};

    QList<GLfloat> vertData;
    for (int i = 0; i < 4; ++i)//X
        for (int j = 0; j < 4; ++j) {
            vertData.append(0.35 * coords[i][j][0]);
            vertData.append(0.35 * coords[i][j][1]);
            vertData.append(0.35 * coords[i][j][2]);
            vertData.append(j == 0 || j == 3);
            vertData.append(j == 0 || j == 1);
        }
    //...其他面

    m_vbo.release();
    m_vbo.destroy();
    m_vbo.create();
    m_vbo.bind();
    m_vbo.allocate(vertData.constData(), vertData.count() * sizeof(GLfloat));
}
  • 写回答

1条回答 默认 最新

  • 有问必答小助手 2022-01-11 11:17
    关注

    你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


    本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


    因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。

    评论

报告相同问题?

问题事件

  • 系统已结题 1月18日
  • 创建了问题 1月10日

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器