Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

How do I properly render a quad in OpenGL using a GL_TRIANGLE_STRIP primitive?

+1
−1

I am currently working with LWJGL and the obstacle I face right now on my project is rendering textures to a cube, e.x a set of 8 vertices with position, color, and UV information. For now, I am starting off simple with a single 2D face however it's not exactly correctly rendered. I believe I am close but after playing around with it a bunch I'm not sure how to manipulate the code in a way that resembles a full, correctly oriented texture. Allow me to show you what I have so far:

This is the 16x16 texture (scaled to 256x256 so its visible in this post) I am trying to render, red lines for debugging purposes. The diagonal separates the 2 triangles that make up the GL_TRIANGLE_STRIP my code is trying to draw:

block texture that should be rendering

But this is how my code displays it right now:

texture not rendering correctly

But after a lot of tweaking and guessing as to what could be the issue, I am just not sure. As far as I can tell at least, the code looks right:

 private void renderMenu() {
        // Define the vertices and colors of the cube

        //TODO: Figure out how tf to render a cube with GL_TRIANGLE_STRIP preferably
        float[] vertices = {
                //Position (X, Y, Z)    Color (R, G, B, A)          Texture (U, V)

                // Front face
                -0.5f, -0.5f, 0.5f,     1.0f, 0.0f, 0.0f, 1.0f,     0.0f, 0.0f,
                0.5f, -0.5f,  0.5f,     0.0f, 1.0f, 0.0f, 1.0f,     1.0f, 0.0f,
                -0.5f, 0.5f,  0.5f,     0.0f, 0.0f, 1.0f, 1.0f,     0.0f, 1.0f,
                0.5f,  0.5f,  0.5f,     1.0f, 1.0f, 1.0f, 1.0f,     1.0f, 1.0f,
               
        };



        // Declares the Elements Array, where the indices to be drawn are stored
        int[] elementArray = {
                // Front face
                0, 1, 2, 3

        };

        //Loading texture image
        String path = "src/main/resources/textures/test_texture16.png";
        IntBuffer width = BufferUtils.createIntBuffer(1);
        IntBuffer height = BufferUtils.createIntBuffer(1);
        IntBuffer channels = BufferUtils.createIntBuffer(1);
        ByteBuffer image = stbi_load(path, width, height, channels, 0);

        //Binding texture ID
        int texId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, texId);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glGenerateMipmap(GL_TEXTURE_2D);


        if (image != null) {
            //Loads image to GPU
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.get(0), height.get(0),
                    0, GL_RGBA, GL_UNSIGNED_BYTE, image);

            //Frees memory containing image
            stbi_image_free(image);
        } else {
            logger.warning("Texture could not be loaded from " + path);
        }

        /*==================================
        Buffer binding and loading
        ====================================*/

        // Create VAO
        int vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);

        // Create a float buffer of vertices
        FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertices.length);
        vertexBuffer.put(vertices).flip();

        // Create VBO upload the vertex buffer
        int vboID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);

        // Create the indices and upload
        IntBuffer elementBuffer = BufferUtils.createIntBuffer(elementArray.length);
        elementBuffer.put(elementArray).flip();

        // Create EBO upload the element buffer
        int eboID = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);

        // Bind the VAO that we're using
        glBindVertexArray(vaoID);

        /*=====================================
        Vertex attribute definitions for shader
        ======================================*/
        int posSize = 3;
        int colorSize = 4;
        int uvSize = 2;
        int floatSizeBytes = 4;
        int vertexSizeBytes = (posSize + colorSize) * floatSizeBytes;


        //Position
        glVertexAttribPointer(0, posSize, GL_FLOAT, false, vertexSizeBytes, 0);
        glEnableVertexAttribArray(0);

        //Color
        glVertexAttribPointer(1, colorSize, GL_FLOAT, false, vertexSizeBytes, posSize * Float.BYTES);
        glEnableVertexAttribArray(1);

        //Texture
        glVertexAttribPointer(2, uvSize, GL_FLOAT, false, vertexSizeBytes, (posSize + colorSize) * Float.BYTES);
        glEnableVertexAttribArray(2);

        /*==================================
        View Matrix setup
        ====================================*/

        // Set up the model-view matrix for rotation
        modelViewMatrix = new Matrix4f();
        modelViewMatrix.translate(new Vector3f(0.0f, 0.0f, -2.0f));
        modelViewMatrix.rotate(180, new Vector3f(0.0f, 1.0f, 0.0f));


        // Set up the model-view-projection matrix
        Matrix4f modelViewProjectionMatrix = new Matrix4f(projectionMatrix).mul(modelViewMatrix);

        // Pass the model-view-projection matrix to the shader as a uniform
        int mvpMatrixLocation = glGetUniformLocation(shaderProgram.getProgramId(), "modelViewProjectionMatrix");
        glUniformMatrix4fv(mvpMatrixLocation, false, modelViewProjectionMatrix.get(new float[16]));


        // Enable the vertex attribute pointers
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);


        /*==================================
        Drawing
        ====================================*/
        glDrawElements(GL_TRIANGLE_STRIP, elementArray.length, GL_UNSIGNED_INT, 0);

        //Unbind everything
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glBindVertexArray(0);
        glBindTexture(GL_TEXTURE_2D, 0);
    }

Vertex Shader

#version 330 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec4 aColor;
layout (location = 2) in vec2 aTexCoords;

uniform mat4 modelViewProjectionMatrix;


out vec4 fColor;
out vec2 fTexCoords;



void main() {
    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
    fColor = aColor;
    fTexCoords = aTexCoords;
}

Drawing a picture helped me to visualize it, but it did not spark any "ah ha" moments like I had hoped:

Visual representation of face

History
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+6
−0

It looks like your vertexSizeBytes stride variable doesn't include uvSize.

To figure things like this out, use this kind of logic:

The shape of the image isn't a square, so something is wrong with the position coordinates. Possible problems: bad offset, bad stride, bad size, bad order of values (e.g. transposed matrix of values). The offset and size look fine, but the stride doesn't.

If that hadn't found the issue, I would have modified entries in vertices one at a time to see the effect on the output.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

No way that was actually the problem. Changeing `int vertexSizeBytes = (posSize + colorSize) * flo... (1 comment)

Sign up to answer this question »