在现代 OpenGL 中添加 RGB 颜色和纹理映射

时间:2021-05-30 12:08:01

标签: c++ opengl

我目前正在绘制一个球体,但我希望可以选择在球体上使用 3D 着色和纹理。我知道我的代码正确知道允许我插入纹理,因为我有 u、v 坐标,但我不知道如何做到这一点。

球体计算

    const float pi = 3.1414927f;
GLint layers = 100;
GLint circumferenceTiles = 100;
std::vector<float> va;
std::vector<int> ia;

// create the vertex attributes
va.reserve((layers + 1)* (circumferenceTiles + 1) * 5);  // 5 floats: x, y, z, u, v 
for (int il = 0; il <= layers; ++il)
{
    float layer_rel = (float)il / (float)layers;
    float layer_ang = (1.0f - 2.0f * layer_rel) * pi / 2.0f;
    float layer_sin = std::sin(layer_ang);
    float layer_cos = std::cos(layer_ang);
    for (int ic = 0; ic <= circumferenceTiles; ic++)
    {
        float circum_rel = (float)ic / (float)circumferenceTiles;
        float cricum_ang = circum_rel * 2.0f * pi - pi;
        float circum_sin = std::sin(cricum_ang);
        float circum_cos = std::cos(cricum_ang);

        va.push_back(layer_cos * circum_cos); // x
        va.push_back(layer_cos * circum_sin); // y
        va.push_back(layer_sin);              // z
        va.push_back(circum_rel);             // u
        va.push_back(1.0f - layer_rel);       // v
    }
}

// create the face indices 
ia.reserve(layers * circumferenceTiles * 6);
for (int il = 0; il < layers; ++il)
{
    for (int ic = 0; ic < circumferenceTiles; ic++)
    {
        int i0 = il * (circumferenceTiles + 1) + ic;
        int i1 = i0 + 1;
        int i3 = i0 + circumferenceTiles + 1;
        int i2 = i3 + 1;

        int faces[]{ i0, i1, i2, i0, i2, i3 };
        ia.insert(ia.end(), faces + (il == 0 ? 3 : 0), faces + (il == layers - 1 ? 3 : 6));
    }
}

绑定

    // Vertex Array
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Vertex Buffer
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, va.size() * sizeof(*va.data()), va.data(), GL_STATIC_DRAW);

// Index Buffer
GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ia.size() * sizeof(*ia.data()), ia.data(), GL_STATIC_DRAW);

GLuint v_attr_inx = 0;
glVertexAttribPointer(v_attr_inx, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
glEnableVertexAttribArray(v_attr_inx);

GLuint t_attr_inx = 1;
glVertexAttribPointer(t_attr_inx, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glEnableVertexAttribArray(t_attr_inx);

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

绘图

        glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, (GLsizei)ia.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

片段着色器

    #version 330 core

// Interpolated values from the vertex shaders
in vec3 fragmentColor;

// Ouput data
layout(location = 0) out vec4 color;
uniform vec4 u_Color;

void main(){

    // Output color = color specified in the vertex shader, 
    // interpolated between all 3 surrounding vertices
    color = u_Color;

}

顶点着色器

    #version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 texcoord;

// Output data ; will be interpolated for each fragment.
out vec3 fragmentColor;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){    
    // The color of each vertex will be interpolated
    // to produce the color of each fragment
    fragmentColor = texcoord;

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
}

目前,当我编写 vec3 texcoord 时,我可以更改颜色,但无法以线模式显示球体。但是当我将其更改为 vec2 时,我可以将其更改为有线模式但无法更改颜色。

0 个答案:

没有答案
相关问题