возникли проблемы с рисованием цветных вершин с использованием шейдера в opengl для рисования данных, считанных из файла COLLADA

Итак, это код, который я использую для размещения массива вершин и буферов на видеокарте.

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);
}

Я точно знаю, что массив, содержащий данные цвета с плавающей запятой 4, полностью инициализирован и содержит один и тот же цвет, повторяющийся снова и снова для каждой вершины. Однако по какой-то причине я все еще вижу только черный цвет, а не фактический цвет, которым должны быть объекты.

Это мой вершинный шейдер и фрагментный шейдер

#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

Это функция, которую я вызываю для рисования

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();
}

Я был бы очень признателен, если бы кто-то мог понять, где я ошибаюсь. Я новичок в рисовании 3D-графики с помощью opengl, но хотел создать свои собственные классы для рисования сложных 3D-сцен. У меня правильно рисуются вершины объектов, но теперь я пытаюсь добавить цвет, который я также прочитал из файла COLLADA.


person Harry Patrick    schedule 05.06.2015    source источник


Ответы (1)


Я считаю, что проблема в том, что вы glEnableVertexAttribArray(0); дважды и glEnableVertexAttribArray(1); один раз. Вместо этого вы должны включить расположения атрибутов вершин, которые вы использовали для указания на ваши данные.

Итак, после каждого glVertexAttribPointer вызова glEnableVertexAttribArray(loc);

Приложение: все необходимые шаги для использования VBO (взятые из моего кода) в Go, но функции работают точно так же.

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()
person Joonazan    schedule 06.06.2015