C++ opengl示例化每个顶点的颜色(每个三角形有三种颜色)

ijnw1ujt  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(82)

概述:我正在尝试从绘制调用到示例化。我想保持对各个顶点颜色的控制。
工作材料:C++、OpenGL、Macos。我正在和三个四人组一起工作。三个四边形 * 每个四边形两个唯一三角形= 18个单独顶点。
预期结果:三个四边形,其颜色由总共18个唯一的用户确定的顶点颜色插值。每个四象限有六种独特的颜色。
我能做的:我目前能够示例化顶点位置的变换矩阵,并生成3个有意定位的四边形。
我还不能做的事:我一直无法使我的设置检索每一个传入的顶点正好一种颜色。这是我所知道的最小情况。最小值是它有模型顶点位置,变换位置,和(希望)* 唯一的颜色。
我尝试过的:阅读大量的Kronos函数签名,探索glBufferData(),glVertexAttribPointer()和glDrawArraysInstanced()函数中有限可变值的所有参数空间,直到无用。
main.cpp:

#define VTXPOSLOC 0 // Vertex Position Location
#define INSCOLLOC 1 // Instance Color Location
#define INSMATLOC 2 // Instance Matrix Location
...
float vtxdat[18]   = {  0.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, 0.0f,
                        0.0f, 0.0f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f, 0.0f };
    std::vector <glm::mat4> iMV; // instanceMatricesVec
    std::vector <glm::vec3> iCV; // instanceColorsVec
    unsigned int instanceCount = 3;
    for (unsigned int i=0; i<instanceCount; i++){
        for (int j=0; j<6; j++) // 6 == number of vertices req to make TWO unique triangles in vtxdat
        {
            float xC = j/2.0f; 
            float yC = i/2.0f;
            glm::vec3 colorvec3 = glm::vec3(xC,yC,0.0f);
            iCV.push_back(colorvec3);
        }

        glm::mat4 transmat4 = glm::translate ( glm::mat4(1.0f), glm::vec3 ( i,0,0 ) );
        iMV.push_back(transmat4);
    }
    glUseProgram      ( shadprogID ); // Does NOT need to be here. ONLY in while loop.
    glGenVertexArrays ( 1, &VAO );
    glBindVertexArray ( VAO );
    glGenBuffers      ( 1, &VBO );
    glBindBuffer      ( GL_ARRAY_BUFFER,VBO );
    glBufferData      ( GL_ARRAY_BUFFER,sizeof(vtxdat),vtxdat,GL_STATIC_DRAW );
    glVertexAttribPointer     ( VTXPOSLOC,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)(0*sizeof(float)));
    glEnableVertexAttribArray ( VTXPOSLOC );
    
    glGenBuffers      ( 1, &colorVBO );
    glBindBuffer      ( GL_ARRAY_BUFFER,colorVBO );
    glBufferData      ( GL_ARRAY_BUFFER,iCV.size() * sizeof(glm::vec3),iCV.data(),GL_STATIC_DRAW );
    glVertexAttribPointer     ( INSCOLLOC,3,GL_FLOAT,GL_FALSE,6*sizeof(float),(void*)(0));
    glEnableVertexAttribArray ( INSCOLLOC );
    
    glGenBuffers      ( 1, &instanceVBO );
    glBindBuffer      ( GL_ARRAY_BUFFER,instanceVBO );
    glBufferData      ( GL_ARRAY_BUFFER,iMV.size() * sizeof(glm::mat4),iMV.data(),GL_STATIC_DRAW );
    
    for (int i = 0; i < 4; i++) {
        glVertexAttribPointer     ( INSMATLOC+i,4,GL_FLOAT,GL_FALSE,sizeof(glm::mat4),(void*)(i*sizeof(glm::vec4)));
        glEnableVertexAttribArray ( INSMATLOC+i );
        glVertexAttribDivisor     ( INSMATLOC+i, 1 );
    }

    while ( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 ) {
...        
        glm::mat4 projmat4 = glm::perspective(glm::radians(fov), (float)WINDOWWIDTH / (float)WINDOWHEIGHT, 0.1f, 100.0f);
        glm::mat4 viewmat4 = glm::lookAt(camPs, camPs + camFr, camUp);
        
        glUniformMatrix4fv(projmat4ID, 1, GL_FALSE, &projmat4[0][0]); // to vs
        glUniformMatrix4fv(viewmat4ID, 1, GL_FALSE, &viewmat4[0][0]); // to vs
              
        glDrawArraysInstanced(GL_TRIANGLES, 0, 6, instanceCount);
...
    };

字符串
顶点着色器:

#version 330 core
layout(location = 0) in vec3 vtxPos;
layout(location = 1) in vec3 iCV;
layout(location = 2) in mat4 iMV;
out vec3 fragmentColor;
uniform mat4 projmat4;
uniform mat4 viewmat4;
void main(){
    vec4 transformedPos = iMV * vec4(vtxPos,1.0f);
    gl_Position = projmat4 * viewmat4 * transformedPos;
    fragmentColor = iCV;
}

9cbw7uwe

9cbw7uwe1#

你的颜色值似乎有点奇怪?

float xC = j / 2.0f; 
            float yC = i / 2.0f;

字符串
尤其是考虑到你的步伐:

glVertexAttribPointer(INSCOLLOC, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float),(void*)(0));


他们大多数都在1.0以上,这是故意的吗?
不管怎样,我想我明白你想干什么了:

unsigned int instanceCount = 3;
    for (unsigned int i=0; i<instanceCount; i++){
        for (int j=0; j<6; j++) // 6 == number of vertices req to make TWO unique triangles in vtxdat
        {
            float xC = j/2.0f; 
            float yC = i/2.0f;
            glm::vec3 colorvec3 = glm::vec3(xC,yC,0.0f);
            iCV.push_back(colorvec3);
        }

        glm::mat4 transmat4 = glm::translate ( glm::mat4(1.0f), glm::vec3 ( i,0,0 ) );
        iMV.push_back(transmat4);
    }


可惜这行不通。示例0将使用颜色[0:5]。示例1将使用颜色[0:5]。示例2将使用颜色[0:5]。
问题是,当渲染示例时,顶点和颜色缓冲区被重置回VBO的开始。将属性divisor设置为1的那些参数将在每个示例中前进一次。没有办法使彩色VBO前进超过前6个条目。
你基本上有两种方法可以解决这个问题。
1.将颜色数据加载为纹理 (即6 x 3像素,用于NumVerts * NumInstances)。然后你就可以使用着色器中的顶点和示例ID来执行texelfetch。

uniform sampler2D colours;

void main() {
   vec4 colour = texelFetch(colours, ivec2(gl_VertexID, gl_InstanceID), 0);
}


1.使用着色器存储缓冲区。

layout(std430, binding = 3) buffer colour_buffer
{
    vec4 colours[];
};

void main() {
   vec4 col = colours[gl_InstanceID * 6 + gl_VertexID];
}

相关问题