Appearance of a triangle strip. Surface normals? O

2019-08-23 09:42发布

问题:

Below is a picture of what my outcome is.

I am using flat shading and have put each vertex in their respectable triangle objects. Then I use these vertices to calculate the surface normals. I have been reading that because my triangles share similar vertices that calculating the normals may be an issue? But to me this looks like a windings problem given that every other one is off.

I provided some of my code below to anyone who wants to look through it and get a better idea what the issue could be.

Triangle currentTri = new Triangle();
int triPointIndex = 0;
List<Triangle> triList = new ArrayList<Triangle>()                               

GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
        int counter1 = 0;               
        float stripZ = 1.0f;
        float randY;
        for (float x=0.0f; x<20.0f; x+=2.0f) {
            if (stripZ == 1.0f) {
                stripZ = -1.0f;
            } else { stripZ = 1.0f; }

            randY = (Float) randYList.get(counter1);
            counter1 += 1;

            GL11.glVertex3f(x, randY, stripZ);

            Vert currentVert = currentTri.triVerts[triPointIndex];
            currentVert.x = x;
            currentVert.y = randY;
            currentVert.z = stripZ;

            triPointIndex++;

            System.out.println(triList);

            Vector3f normal = new Vector3f();
            float Ux = currentTri.triVerts[1].x - currentTri.triVerts[0].x;
            float Uy = currentTri.triVerts[1].y - currentTri.triVerts[0].y;
            float Uz = currentTri.triVerts[1].z - currentTri.triVerts[0].z;

            float Vx = currentTri.triVerts[2].x - currentTri.triVerts[0].x;
            float Vy = currentTri.triVerts[2].y - currentTri.triVerts[0].y;
            float Vz = currentTri.triVerts[2].z - currentTri.triVerts[0].z;

            normal.x = (Uy * Vz) - (Uz * Vy);
            normal.y = (Uz * Vx) - (Ux * Vz);
            normal.z = (Ux * Vy) - (Uy * Vx);

            GL11.glNormal3f(normal.x, normal.y, normal.z);

            if (triPointIndex == 3) {
                triList.add(currentTri);
                Triangle nextTri = new Triangle();

                nextTri.triVerts[0] = currentTri.triVerts[1];
                nextTri.triVerts[1] = currentTri.triVerts[2];
                currentTri = nextTri;
                triPointIndex = 2;
            }           

        }
 GL11.glEnd();

回答1:

You should be setting the normal before calling glVertex3f (...). A call to glVertex* is basically what finalizes a vertex, it associates the current color, normal, texture coordinates, etc... with the vertex at the position you pass and emits a new vertex.


glVertex — specify a vertex

Description

glVertex commands are used within glBegin / glEnd pairs to specify point, line, and polygon vertices. The current color, normal, texture coordinates, and fog coordinate are associated with the vertex when glVertex is called.

When only x and y are specified, z defaults to 0.0 and w defaults to 1.0. When x, y, and z are specified, w defaults to 1.0.


Chances are very good that this is a large part of your problem. Triangle strips are designed to workaround implicit winding issues. You have to reverse the winding of every triangle when you use a strip, but the rasterizer compensates for this by flipping the winding order used for front/back internally on each alternate triangle.

Update:

Understand of course that the rasterizer is smart enough to flip the front/back winding for each alternate triangle when using a strip but your code is not (at least not currently). You need to compensate for the alternately reversed winding when you calculate the normals yourself on the CPU side.



回答2:

Actually it's both in one. The direction of the normal depends on the winding used to calculate it. However ultimately it boils down to a normals problem, since that's what determines lighting calculations.

Winding is also important for OpenGL, but you can't change anything about that in a striped primitive.