首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenGL从一个QVector3D为给定缓冲区的所有顶点着色?

OpenGL从一个QVector3D为给定缓冲区的所有顶点着色?
EN

Stack Overflow用户
提问于 2022-11-14 23:03:20
回答 1查看 22关注 0票数 1

我有一个程序来呈现面几何,然后在相同的OpenGL上下文中将数据绘制在几何图形的顶部。当VBO定义面三角形及其相关颜色时,所有的操作都是按预期进行的,但是用户已经请求将所有的几何顶点设置为单一颜色(GUI切换)。

有没有任何方法可以做到这一点,而不进入和设置的颜色部分的VBO为该颜色?只是看起来效率很低,但是我从几个小时的谷歌搜索到工作都找不到任何东西。

使用C++,QT6+

破片着色机

代码语言:javascript
复制
#version 150 core
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif

in vec3 Color;
out vec4 outColor;

void main()
{
    outColor = vec4(Color,1.0f);
}

顶点着色器

代码语言:javascript
复制
#version 150 core
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif

uniform mat4 mvp_matrix;
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
attribute vec3 color;
varying vec3 Color;

void main()
{
    Color = color;

    // Calculate vertex position in screen space
    gl_Position = mvp_matrix * a_position;

    // Pass texture coordinate to fragment shader
    // Value will be automatically interpolated to fragments inside polygon faces
    v_texcoord = a_texcoord;
}

相关代码片段:

代码语言:javascript
复制
// initializing the buffers from vectors of structures
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Geometry
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Get a copy of the geometry to reference here
    std::vector<storedGeometry::facetData> tGeom = gUseGeom.getGeom();
    // Convert vector to array
    storedGeometry::facetData* aGeom = tGeom.data();

    // Transfer vertex data to VBO 0
    geomBuf.bind();
    geomBuf.allocate(aGeom, int(tGeom.size() * sizeof(storedGeometry::facetData)));

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Currents
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Get a copy of the currents data to reference here
    std::vector<storedGeometry::facetData> tCurrents = gUseCurrents.getGeom();
    // Convert vector to array
    storedGeometry::facetData* aCurrent = tCurrents.data();

    // Transfer vertex data to VBO 1
    currentsBuf.bind();
    currentsBuf.allocate(aCurrent, int(tCurrents.size() * sizeof(storedGeometry::facetData)));




// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// drawing 
// Get shader variable locations
    int vertexLocation = program->attributeLocation("a_position");
    int colorLocation = program->attributeLocation("color");
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Plot Geometry
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if (bGeomVisible) {
        geomBuf.bind();
        program->enableAttributeArray(vertexLocation);
        program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, sizeof(QVector3D));

        program->enableAttributeArray(colorLocation);
        if (bCobbleSolid) { // Solid
// This is what I can't get to work ************************************
            //program->setAttributeValue(colorLocation, 1.0, 1.0, 1.0);
            program->setAttributeValue(colorLocation, QVector3D(1.0,1.0,1.0));
        } else { // Cobble
            program->setAttributeBuffer(colorLocation, GL_FLOAT, 3*sizeof(QVector3D), 3, sizeof(QVector3D));
        }

        // Set polygon/wiremesh or solid/filled mode based on fill/wire toggle
        if (bFillWire) {
            // Polygon = TRUE
            glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        } else {
            // Filled = FALSE
            glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        }
        // Draw geometry
        glDrawArrays(GL_TRIANGLES, 0, gUseGeom.gSize() * 6);
    }
    // Debugging
    //out << "gUseGeom.gSize(): " << gUseGeom.gSize() << Qt::endl;
    // Draw cube geometry
    //glDrawElements(GL_TRIANGLES, gUseGeom.gSize() * 3, GL_UNSIGNED_SHORT, 0);
    //glDrawArrays(GL_TRIANGLES, 0, gUseGeom.gSize() * 6);

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Plot Currents
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if (bCurrentsVisible) {
        currentsBuf.bind();
        program->enableAttributeArray(vertexLocation);
        program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0,                   3, sizeof(QVector3D));
        program->enableAttributeArray(colorLocation);
        program->setAttributeBuffer(colorLocation,  GL_FLOAT, 3*sizeof(QVector3D), 3, sizeof(QVector3D));
        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        glDrawArrays(GL_TRIANGLES, 0, gUseCurrents.gSize() * 6);
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-15 14:49:55

如果没有启用特定的顶点属性数组(使用glEnableVertexAttribArray),则该属性的值(对于所有呈现的顶点)将从当前顶点属性值中提取,这是由glVertexAttrib函数族定义的。

忘记禁用顶点属性数组,因此不使用当前的顶点属性值。您可以按以下方式修复它:

代码语言:javascript
复制
    if (bCobbleSolid) { // Solid
        program->disableAttributeArray(colorLocation);
        program->setAttributeValue(colorLocation, QVector3D(1.0,1.0,1.0));
    } else { // Cobble
        program->enableAttributeArray(colorLocation);
        program->setAttributeBuffer(colorLocation, GL_FLOAT, 3*sizeof(QVector3D), 3, sizeof(QVector3D));
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74438865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档