0

I am trying to send the normal vector of each face of my object but it doesn't do what I am expecting. In the shader I have add this line vec4(normal, 1.) * texture(texture_, coordTexture); witch should display the texture without any lighting (normal should be vec(1., 1., 1.)). But I am getting the following result:

I am getting the following result

Which indicate that the coordinates of the normal are not sent.

Generation of the vertices:

void Chunck::generate() {
    int width = 1024;
    int height = 1024;

    for (int i = -width / 2.; i <= width / 2.; ++i)
        for (int j = -height / 2.; j <= height / 2.; ++j)
            map_m[i][j] = 50. * std::cos(i * 0.01) + 50. * std::sin(j * 0.01)
                    + std::exp(0.01 * i);

    for (int i = -width / 2.; i < width / 2.; ++i)
        for (int j = -width / 2.; j < height / 2.; ++j) {
            vertices_m.push_back(i);
            vertices_m.push_back(map_m.at(i).at(j));
            vertices_m.push_back(j);

            vertices_m.push_back((i + 1));
            vertices_m.push_back(map_m.at(i + 1).at(j));
            vertices_m.push_back(j);

            vertices_m.push_back((i + 1));
            vertices_m.push_back(map_m.at(i + 1).at(j + 1));
            vertices_m.push_back((j + 1));

            auto normal = getNormal(i, j);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            // Face 2
            vertices_m.push_back(i);
            vertices_m.push_back(map_m.at(i).at(j));
            vertices_m.push_back(j);

            vertices_m.push_back((i + 1));
            vertices_m.push_back(map_m.at(i + 1).at(j + 1));
            vertices_m.push_back((j + 1));

            vertices_m.push_back(i);
            vertices_m.push_back(map_m.at(i).at(j + 1));
            vertices_m.push_back((j + 1));

            normal = getNormal2(i, j);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            std::vector<float> vec =
                    { 0, 0, 1., 0, 1., 1., 0, 0, 0, 1., 1., 1. };
            texture_m.insert(texture_m.end(), vec.begin(), vec.end());

        }
}

Drawing:

void Chunck::draw() const {

    glBindBuffer(GL_ARRAY_BUFFER, vboID_m);


    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(vertices_m.size() * sizeof(float)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0,
            BUFFER_OFFSET(
                    vertices_m.size() * texture_m.size() * sizeof(float)));
    glEnableVertexAttribArray(2);


    glBindTexture(GL_TEXTURE_2D, grassTexture_m.getID());
    glDrawArrays(GL_TRIANGLES, 0, vertices_m.size() / 3);
    glBindTexture(GL_TEXTURE_2D, 0);

    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);


    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Loading of the vertices normals to the VBO:

void Chunck::load() {
    grassTexture_m.load();

    if (glIsBuffer(vboID_m) == GL_TRUE)
        glDeleteBuffers(1, &vboID_m);

    glGenBuffers(1, &vboID_m);
    glBindBuffer(GL_ARRAY_BUFFER, vboID_m);
    {
        glBufferData(GL_ARRAY_BUFFER, (vertices_m.size() + texture_m.size()) * sizeof(float), 0,
        GL_STATIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_m.size() * sizeof(float), vertices_m.data());
        glBufferSubData(GL_ARRAY_BUFFER, vertices_m.size() * sizeof(float),
                texture_m.size() * sizeof(float), texture_m.data());
        glBufferSubData(GL_ARRAY_BUFFER, vertices_m.size() * texture_m.size() * sizeof(float),
                        normals_m.size() * sizeof(float), normals_m.data());
    }
    glBindBuffer(GL_ARRAY_BUFFER, 0);

}

Vertex shader:

#version 330 core

in vec3 in_Vertex;
in vec2 in_TexCoord0;
in vec3 in_normal;

uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;


out vec2 coordTexture;
out vec3 normal;
out vec3 FragPos;


void main()
{
    gl_Position = projection * view * model * vec4(in_Vertex, 1.0);
    FragPos = vec3(model * vec4(in_Vertex, 1.0));
    coordTexture = in_TexCoord0;
    normal = in_normal;
}

Fragment shader:

#version 330 core

in vec2 coordTexture;
in vec3 normal;
in vec3 FragPos;

uniform sampler2D texture_;

out vec4 out_Color;

void main()
{
    float ambientStrength = 0.1;
    vec3 lightColor = vec3(1., 1., 1.);
    vec3 ambient = ambientStrength * lightColor;

    vec3 lightDir = normalize(vec3(0., 10000., 0.) - FragPos);
    float diff = max(dot(normal, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    //out_Color = vec4((ambient + diffuse), 1.) * texture(texture_, coordTexture);
    out_Color = vec4(normal, 1.) * texture(texture_, coordTexture);
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
Alex
  • 79
  • 6
  • The lack of `layout(location=...)` in your vertex shader is suspicious, do you manually bind the attributes by hand in your shader loading code? –  Sep 13 '18 at 17:07
  • Thank you for the rapidity of your answer, Yes I bind it like this : glBindAttribLocation(programID_m, 0, "in_Vertex"); glBindAttribLocation(programID_m, 1, "in_TexCoord0"); glBindAttribLocation(programID_m, 2, "in_normal"); – Alex Sep 13 '18 at 17:10
  • Look at [this question](https://stackoverflow.com/q/16380005/3871028) about how to use "stride" in an interleaved buffer. It affects `glVertexAttribPointer` and `glBufferSubData` – Ripi2 Sep 13 '18 at 17:11
  • 1
    `glBufferData(GL_ARRAY_BUFFER, (vertices_m.size() + texture_m.size()) * sizeof(float), 0, GL_STATIC_DRAW);` isn't this too small? you probably want `vertices_m.size() + texture_m.size() + normals_m.size()` –  Sep 13 '18 at 17:11
  • Yes, but by changing it, it doesn't do the tricks – Alex Sep 13 '18 at 17:13
  • Also note that you are using normals in NDC space not in World space. And that all nomals are the same, despite of the vertices that form the faces. – Ripi2 Sep 13 '18 at 17:16
  • I have found one mistake : glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(vertices_m.size() * texture_m.size() * sizeof(float))); should be glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET((vertices_m.size() + texture_m.size()) * sizeof(float))); But now I get a black screen :\ – Alex Sep 13 '18 at 17:33
  • No `...GL_FALSE, 0, BUFFER_OFFSET..` That `0` is the *stride*. You have a wrong value here. – Ripi2 Sep 13 '18 at 17:42
  • I hardly struggled to write this but a _normal_ should've length 1. Your normals (1, 1, 1) have length sqrt(3). I doubt that it's relevant (may be I would more if you had a white screen...) – Scheff's Cat Sep 13 '18 at 17:46
  • @Ripi2 even with : glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), BUFFER_OFFSET((vertices_m.size() + texture_m.size()) * sizeof(float))); I still have a black screen – Alex Sep 13 '18 at 17:50
  • @Scheff If I change the fragment shader from vec4(normal, 1.) * texture(texture_, coordTexture); to vec4(1., 1., 1., 1.) * texture(texture_, coordTexture); I get my world randering correctly – Alex Sep 13 '18 at 17:50
  • @Ripi2 This is the funny special * operator which multiplies components-wise. So, `vec4(1., 1., 1., 1.) *` is an identity operation changing nothing. (May be, I sticked too much to the mathematical meaning of "normal".) ;-) Sorry. – Scheff's Cat Sep 13 '18 at 17:54
  • I found the second mistake, glBufferSubData(GL_ARRAY_BUFFER, (vertices_m.size() * texture_m.size()) * sizeof(float), normals_m.size() * sizeof(float), normals_m.data()); should be : glBufferSubData(GL_ARRAY_BUFFER, (vertices_m.size() + texture_m.size()) * sizeof(float), normals_m.size() * sizeof(float), normals_m.data()); now it works, thank you for your help ! – Alex Sep 13 '18 at 17:57
  • @Ripi2 Sorry, wrong recipient for previous comment. I meant Alex and didn't recognize my mistake as he got it also and replied. – Scheff's Cat Sep 13 '18 at 17:59

0 Answers0