having trouble drawing coloured vertices using sha

2019-09-14 12:59发布

问题:

ok so this is the code I use to put the vertex array and buffers onto the graphics card.

void Mesh3D::InitializeBuffers(GLuint program) {
    float largestPos = findLargestPosition(&col->vectorGeometry);
    std::cout << "largestPos is: ";
    std::cout << largestPos;
    std::cout << "\n";
    int loc;
    vaos = new GLuint[nVectorGeometry];
    glGenVertexArrays(nVectorGeometry, vaos);//The vertex array object stores the array of vertice indexes used to find the vertex in the buffer vertex buffer object.. 

    vbosPosition = new GLuint[nVectorGeometry];
    vbosNormal = new GLuint[nVectorGeometry];
    vbosColor = new GLuint[nVectorGeometry];
    glGenBuffers(nVectorGeometry, vbosPosition);
    glGenBuffers(nVectorGeometry, vbosNormal);
    glGenBuffers(nVectorGeometry, vbosColor);
    // Configure VBOs to hold positions and normals for each geometry
    for (int i = 0; i<nVectorGeometry; i++)//i used to iterate through the individual 
    {

        glBindVertexArray(vaos[i]);
        int size = col->vectorGeometry[i].map["POSITION"].size / 4;
        float* scaledData = (float*)malloc(size*sizeof(float));
        float* p = (float*)col->vectorGeometry[i].map["POSITION"].data;
        for (int j = 0; j < size; j++)
        {
            *(scaledData+j)=*(p+j)/largestPos;

            if (*(scaledData + j) < -0.5)
            {
                std::cout << "scaledData[j] is: ";
                std::cout << *(scaledData + j);
                std::cout << "\n";
            }
        }

        // Set vertex coordinate data
        glBindBuffer(GL_ARRAY_BUFFER, vbosPosition[i]);
        glBufferData(GL_ARRAY_BUFFER, col->vectorGeometry[i].map["POSITION"].size, scaledData, GL_STATIC_DRAW);
        free(scaledData);


        loc = glGetAttribLocation(program, "in_coords");//get a GLuint for the attribute and put it into GLuint loc.
        glVertexAttribPointer(loc, col->vectorGeometry[i].map["POSITION"].stride, col->vectorGeometry[i].map["POSITION"].type, GL_FALSE, 0, 0);//glVertexAttribPointer — loc specifies the index of the generic vertex attribute to be modified.
        glEnableVertexAttribArray(0);
#ifdef Testing_Mesh3D
        PrintGLVertex(vbosPosition[i], col->vectorGeometry[i].map["POSITION"].size / 4);
#endif      // Set normal vector data
        glBindBuffer(GL_ARRAY_BUFFER, vbosNormal[i]);
        glBufferData(GL_ARRAY_BUFFER, col->vectorGeometry[i].map["NORMAL"].size, col->vectorGeometry[i].map["NORMAL"].data, GL_STATIC_DRAW);
        loc = glGetAttribLocation(program, "in_normals");
        glVertexAttribPointer(loc, col->vectorGeometry[i].map["NORMAL"].stride, col->vectorGeometry[i].map["NORMAL"].type, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);

        Material* material = col->mapGeometryUrlToMaterial2Effect[col->vectorGeometry[i].id];
        if (material->effect1.size() > 0)
        {
            std::cout << "size of effect is: ";
            std::cout << material->effect1.size();
            std::cout << "\n";
            Effect* effect1 = material->effect1[0];
            if (effect1->type == enumEffectTypes::color)
            {
                glBindBuffer(GL_ARRAY_BUFFER, vbosColor[i]);
                Color color = effect1->color;
                //initialize a buffer array for the color with the color for all the geometry repeated over and over.
                int vectorColorsSize = col->vectorGeometry[i].map["POSITION"].size;
                float* vectorColors = (float*)malloc(vectorColorsSize*sizeof(float));
                for (int j = 0; j <vectorColorsSize; j=j+4)
                {
                    float* f = vectorColors + j;
                    for (int k = 0; k < color.stride; k++)
                    {
                        *(f + k) = *(color.values + k);
                    }
                }

                glBufferData(GL_ARRAY_BUFFER, vectorColorsSize*sizeof(float), vectorColors, GL_STATIC_DRAW);
                loc = glGetAttribLocation(program, "in_colors");
                glVertexAttribPointer(loc, color.stride , color.type, GL_FALSE, 0, 0);

            }
            else
            {

            }

        }
        glEnableVertexAttribArray(1);
    }

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

I know for a fact the array containing the floating point 4 float color data is fully initialized and contains a the same color repeated over and over for each vertex. However for some reason I am still only seeing a black color being drawn instead of the actual color the objects should be.

This is my vertex shader and fragment shader

#pragma once
#ifndef Included_shaders
#define Included_shaders

#include<stdio.h>
#include<iostream>
static std::string  shaderVert = "#version 330\n"
"in vec3 in_coords;\n"
"in vec3 in_normals;\n"
"in vec4 in_colors; \n"//added by me
"out vec3 vertex_normal;\n"
"out vec4 vertex_color;\n"
"void main(void) {\n"
"vertex_normal = in_normals;\n"
"vertex_color = in_colors;\n"//added by me
"gl_Position = vec4(in_coords, 1.0);\n"
"}\n";

static std::string shaderFrag = "#version 330\n"
"in vec3 vertex_normal;\n"
"in vec4 vertex_color;\n"
"out vec4 output_color;\n"
"layout(std140) uniform LightParameters{\n"
"vec4 diffuse_intensity;\n"
"vec4 ambient_intensity;\n"
"vec4 light_direction;\n"
"};\n"
"uniform vec4 diffuse_color;\n"
"void main() {\n"
"/* Compute cosine of angle of incidence */\n"
"float cos_incidence = dot(vertex_normal, light_direction.xyz);\n"
"cos_incidence = clamp(cos_incidence, 0, 1);\n"
"/* Compute Blinn term */\n"
"vec3 view_direction = vec3(0, 0, 1);\n"
"vec3 half_angle = normalize(light_direction.xyz + view_direction);\n"
"float blinn_term = dot(vertex_normal, half_angle);\n"
"blinn_term = clamp(blinn_term, 0, 1);\n"
"blinn_term = pow(blinn_term, 1.0);\n"
"output_color=vertex_color\n;"
"}\n";
#endif

This is the function i call to draw

void Mesh3D::DrawToParent()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Draw elements of each mesh in the vector
    for (int i = 0; i<nVectorGeometry; i++)
    {
        glBindVertexArray(vaos[i]);
        glDrawElements(col->vectorGeometry[i].primitive/*This is 4 for GL_Triangles*/, col->vectorGeometry[i].index_count,
            GL_UNSIGNED_SHORT, col->vectorGeometry[i].indices);
    }
    glBindVertexArray(0);
    glutSwapBuffers();
}

I would really appreciate it if someone could figure out where I am going wrong. I am rather new to drawing 3d graphics with opengl but wanted to create my own classes to draw complicated 3d scenes. I have the objects vertices being drawn correctly but now im trying to add the color which I also read in from the COLLADA file.

回答1:

I believe the problem is that you glEnableVertexAttribArray(0); twice and glEnableVertexAttribArray(1); once. Instead you should enable the vertex attribute locations that you used to point to your data.

So, after each glVertexAttribPointer call glEnableVertexAttribArray(loc);

Appendix: All the necessary steps for using a VBO (taken from some of my code) its in Go, but the functions work exactly the same.

Vbos[2].Bind(gl.ARRAY_BUFFER)
gl.BufferData(gl.ARRAY_BUFFER, size*4, texCoord, gl.STREAM_DRAW)
self.texcoordloc.AttribPointer(4, gl.FLOAT, false, 0, nil)
self.texcoordloc.EnableArray()
defer self.texcoordloc.DisableArray()