има проблеми с изчертаването на цветни върхове с помощта на шейдър в 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