混淆尝试使用glDrawElements使用顶点和片段着色器绘制彩色元素以进行绘制

时间:2015-06-05 14:25:32

标签: opengl colors drawing

我正在创建一组类来读取COLLADA文件中的3d对象。我开始使用一些基本代码来读取位置和法线并使用opengl绘制它们。我添加了代码以成功缩放顶点,并添加了我需要读取的所有代码,以及与COLLAD文件中每个图形元素相关的颜色或纹理。但现在我需要添加代码来绘制颜色的顶点。我创建了缓冲区对象数组来容纳每个顶点数组和缓冲区对象的颜色数组。 这是我从COLLADA文件中获取的数据构建数组的代码: 请记住,我仍然在创造它并不完美。

// 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(1);
        glBindBuffer(GL_ARRAY_BUFFER, vbosColor[i]);
        Material* material = col->mapGeometryUrlToMaterial2Effect[col->vectorGeometry[i].id];
        if (material->effect1.size() > 0)
        {
            Effect effect1 = material->effect1[0];
            if (effect1.type == enumEffectTypes::color)
            {
                Color color = effect1.color;
                glBufferData(GL_ARRAY_BUFFER, color.length, color.values, GL_STATIC_DRAW);
                loc = glGetAttribLocation(program, "in_colors");
                glVertexAttribPointer(loc, color.length, color.type, GL_FALSE, 0, 0);

            }
            else
            {

            }

        }

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

// Initialize uniform data
void Mesh3D::InitializeUniforms(GLuint program) {

    GLuint program_index, ubo_index;
    struct LightParameters params;

    // Specify the rotation matrix
    glm::vec4 diff_color = glm::vec4(0.3f, 0.3f, 1.0f, 1.0f);
    GLint location = glGetUniformLocation(program, "diffuse_color");
    glUniform4fv(location, 1, &(diff_color[0]));

    // Initialize UBO data
    params.diffuse_intensity = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
    params.ambient_intensity = glm::vec4(0.3f, 0.3f, 0.3f, 1.0f);
    params.light_direction = glm::vec4(-1.0f, -1.0f, 0.25f, 1.0f);

    // Set the uniform buffer object
    glUseProgram(program);
    glGenBuffers(1, &ubo);
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    glBufferData(GL_UNIFORM_BUFFER, 3 * sizeof(glm::vec4), &params, GL_STREAM_DRAW);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);
    glUseProgram(program);

    // Match the UBO to the uniform block
    glUseProgram(program);
    ubo_index = 0;
    program_index = glGetUniformBlockIndex(program, "LightParameters");
    glUniformBlockBinding(program, program_index, ubo_index);
    glBindBufferRange(GL_UNIFORM_BUFFER, ubo_index, ubo, 0, 3 * sizeof(glm::vec4));
    glUseProgram(program);

这是一个听众文件,其中包含两个字符串文字,其中包含用于构建顶点和片段着色器的字符串。我再次对此不熟悉并且不确定如何修改着色器以包含彩色顶点,我已经开始为四个浮动颜色添加输入vec4(包括alpha)。有什么帮助吗?

#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"
"void main(void) {\n"
"vertex_normal = in_normals;\n"
"gl_Position = vec4(in_coords, 1.0);\n"
"}\n";

static std::string shaderFrag = "#version 330\n"
"in vec3 vertex_normal;\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"
"/* Set specular color and compute final color */\n"
"vec4 specular_color = vec4(0.25, 0.25, 0.25, 1.0);\n"
"output_color = ambient_intensity * diffuse_color +\n"
"diffuse_intensity * diffuse_color * cos_incidence +\n"
"diffuse_intensity * specular_color * blinn_term;\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();
}
我对glVertexAttribPointer和glGetAttribLocation感到有点困惑,虽然我认为我得到了基本的想法。我是否正确使用此权利。

我是否正确设置颜色的缓冲区对象。我是否正确我在此缓冲区中的每个顶点都有一个颜色,现在我只放置了适用于此数组中所有相关缓冲区的单一颜色,可能需要更改它?

当我调用glDrawElements时,我究竟如何绘制彩色顶点?

不要只是向我介绍一下opengl的资源,很多罗嗦的解释对我来说都没什么用。

1 个答案:

答案 0 :(得分:0)

制作顶点着色器输出颜色并使片段着色器将其作为输入。颜色将在顶点之间插值。

是的,您似乎已正确理解了glAttribPointer。

DrawElements获取您想要绘制的顶点的索引。最后一个参数不应包含索引。相反,它应该是null。索引应使用int指定。

如果颜色缓冲区被正确绑定,则不需要为颜色执行任何特殊的id drawElements。着色器将获得所有启用的attribarrays。

如果您运行代码并且告诉我您遇到了什么问题,我可以帮助您。如果代码更容易阅读,它也会有所帮助。如果将其拆分为十行以下的函数,您可能会自己发现一些错误,并可能删除一些重复。