Appliquer une texture sur deux triangles

Le problème exposé dans ce sujet a été résolu.

Bonjour,

J’essaye d’appliquer une texture sur deux triangles.

Pour se faire, j’ai suivi les tutoriels suivants :

Lors de l’affichage de mes deux triangles, si j’utilise glDrawArrays(GL_TRIANGLES, 0, 6) j’ai un seul triangle qui s’affiche et si j’utilise glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0) alors aucun triangle s’affiche.

Vous trouverez mon code complet ci-dessous, je suis à court d’idées alors merci de votre aide.

#!coding: utf-8
from __future__ import print_function, division

from OpenGL.GL import *
from OpenGL.GL import shaders
import ctypes
import pygame

from vecutils import * # téléchargez vecutils ici

vertexShader = """
#version 330 core
layout (location = 0) in vec3 attrPosition;
layout (location = 1) in vec3 attrColor;
layout (location = 2) in vec2 attrTexCoords;

out vec3 vsColor;
out vec2 vsTexCoords;

void main()
{
    gl_Position = vec4(attrPosition, 1.0);
    vsColor = attrColor;
    vsTexCoords = attrTexCoords;
}   
"""

fragmentShader = """
#version 330 core
uniform sampler2D texUniform;

in vec3 vsColor;
in vec2 vsTexCoords;

out vec4 FragColor;
void main()
{
    FragColor = vec4(texture(texUniform, vsTexCoords).rgb, 1);
}
"""


NB_POSITION_AXES = 3
NB_COLOR_AXES = 3
NB_TEX_COORDS_AXES = 2

vertices1 = farray([
    # positions        # colors         # texture coords
     0.5,  0.5, 0.0,   1.0, 0.0, 0.0,   1.0, 1.0,   # top right
     0.5, -0.5, 0.0,   0.0, 1.0, 0.0,   1.0, 0.0,   # bottom right
    -0.5, -0.5, 0.0,   0.0, 0.0, 1.0,   0.0, 0.0,   # bottom left
    -0.5,  0.5, 0.0,   1.0, 1.0, 0.0,   0.0, 1.0,   # top left 
])

indices1 = farray([
    0, 1, 3, # first triangle
    1, 2, 3,  # second triangle
])

def createObject(shaderProgram, vertices, indices):

    # Create a new VAO (Vertex Array Object) 
    VAO = glGenVertexArrays(1)
    VBO = glGenBuffers(1)
    EBO = glGenBuffers(1)

    # Bind the Vertex Array Object first
    glBindVertexArray(VAO)

    # Bind the Vertex Buffer
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertices), vertices, GL_STATIC_DRAW)

    # Bind the Entity Buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(indices), indices, GL_STATIC_DRAW)

    # Configure vertex attribute

    # - Position attribute
    glVertexAttribPointer(0, NB_POSITION_AXES, GL_FLOAT, GL_FALSE, 8 * ctypes.sizeof(ctypes.c_float), ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)

    # - Color attribute
    glVertexAttribPointer(1, NB_COLOR_AXES, GL_FLOAT, GL_FALSE, 8 * ctypes.sizeof(ctypes.c_float), ctypes.c_void_p(3 * ctypes.sizeof(ctypes.c_float)))
    glEnableVertexAttribArray(1)

    # - Texture coordinates attribute
    glVertexAttribPointer(2, NB_TEX_COORDS_AXES, GL_FLOAT, GL_FALSE, 8 * ctypes.sizeof(ctypes.c_float), ctypes.c_void_p(6 * ctypes.sizeof(ctypes.c_float)))
    glEnableVertexAttribArray(2)


    # Texture
    
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    # Set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) # Set texture wrapping to GL_REPEAT (default wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    # Set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    image = pygame.image.load('images/wall.jpg').convert_alpha()
    imageData = pygame.image.tostring(image, 'RGBA', 1)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.get_width(), image.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData)
    glGenerateMipmap(GL_TEXTURE_2D)

    # Unbind the VAO
    glBindVertexArray(0)

    # Unbind the VBO
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glDisableVertexAttribArray(0)
    glDisableVertexAttribArray(1)
    glDisableVertexAttribArray(2)
    
    # Unbind the EBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

    return VAO, texture

def initDisplay(shaderProgram):
    glEnable(GL_DEPTH_TEST)

    glUseProgram(shaderProgram)
    textureUniformIndex = glGetUniformLocation(shaderProgram, 'texUniform')
    glUniform1i(textureUniformIndex, 0)

def prepareDisplay():
    glClearColor(0.2, 0.3, 0.3, 1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

def drawObject(shaderProgram, VAO, texture):

    glActiveTexture(GL_TEXTURE0)
    glBindTexture(GL_TEXTURE_2D, texture)

    glUseProgram(shaderProgram)
    glBindVertexArray(VAO)
    #glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
    glDrawArrays(GL_TRIANGLES, 0, 6)

def display():
    glBindVertexArray(0)
    glUseProgram(0)

def main():
    pygame.init()
    screen = pygame.display.set_mode((800, 600), pygame.OPENGL|pygame.DOUBLEBUF)

    shaderProgram = shaders.compileProgram(
        shaders.compileShader(vertexShader, GL_VERTEX_SHADER),
        shaders.compileShader(fragmentShader, GL_FRAGMENT_SHADER))
    
    initDisplay(shaderProgram)

    VAO, texture = createObject(shaderProgram, vertices1, indices1)

    clock = pygame.time.Clock()

    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

        prepareDisplay()
        drawObject(shaderProgram, VAO, texture)
        display()
        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    try:
        main()
    finally:
        pygame.quit()
+0 -0

Salut,

Je suis toujours bloqué sur mon problème, et toujours ouvert aux idées :D

bonne fin de week-end

Edit :

Voici la version corrigé

#!coding: utf-8
from __future__ import print_function, division

from OpenGL.GL import *
from OpenGL.GL import shaders
import ctypes
import pygame
import numpy as np

from vecutils import * # téléchargez vecutils ici

vertexShader = """
#version 330 core
layout (location = 0) in vec3 attrPosition;
layout (location = 1) in vec3 attrColor;
layout (location = 2) in vec2 attrTexCoords;

out vec3 vsColor;
out vec2 vsTexCoords;

void main()
{
    gl_Position = vec4(attrPosition, 1.0);
    vsColor = attrColor;
    vsTexCoords = attrTexCoords;
}   
"""

fragmentShader = """
#version 330 core
uniform sampler2D texUniform;

in vec3 vsColor;
in vec2 vsTexCoords;

out vec4 FragColor;
void main()
{
    FragColor = vec4(texture(texUniform, vsTexCoords).rgb, 1);
}
"""


NB_POSITION_AXES = 3
NB_COLOR_AXES = 3
NB_TEX_COORDS_AXES = 2

vertices1 = farray([
    # positions        # colors         # texture coords
     0.5,  0.5, 0.0,   1.0, 0.0, 0.0,   1.0, 1.0,   # top right
     0.5, -0.5, 0.0,   0.0, 1.0, 0.0,   1.0, 0.0,   # bottom right
    -0.5, -0.5, 0.0,   0.0, 0.0, 1.0,   0.0, 0.0,   # bottom left
    -0.5,  0.5, 0.0,   1.0, 1.0, 0.0,   0.0, 1.0,   # top left 
])

indices1 = np.array([
    0, 1, 3, # first triangle
    1, 2, 3,  # second triangle
], dtype=np.uint32)

def createObject(shaderProgram, vertices, indices):

    # Create a new VAO (Vertex Array Object) 
    VAO = glGenVertexArrays(1)
    VBO = glGenBuffers(1)
    EBO = glGenBuffers(1)

    # Bind the Vertex Array Object first
    glBindVertexArray(VAO)

    # Bind the Vertex Buffer
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertices), vertices, GL_STATIC_DRAW)

    # Bind the Entity Buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(indices), indices, GL_STATIC_DRAW)

    # Configure vertex attribute

    # - Position attribute
    attrPositionIndex = glGetAttribLocation(shaderProgram, 'attrPosition')
    if (attrPositionIndex != -1):
        glVertexAttribPointer(attrPositionIndex, NB_POSITION_AXES, GL_FLOAT, GL_FALSE, 8 * ctypes.sizeof(ctypes.c_float), ctypes.c_void_p(0))
        glEnableVertexAttribArray(attrPositionIndex)

    # - Color attribute
    attrColorIndex = glGetAttribLocation(shaderProgram, 'attrColor') # doesn't work ?
    if (attrColorIndex != -1):
        glVertexAttribPointer(attrColorIndex, NB_COLOR_AXES, GL_FLOAT, GL_FALSE, 8 * ctypes.sizeof(ctypes.c_float), ctypes.c_void_p(3 * ctypes.sizeof(ctypes.c_float)))
        glEnableVertexAttribArray(attrColorIndex)

    # - Texture coordinates attribute
    attrTexCoordsIndex = glGetAttribLocation(shaderProgram, 'attrTexCoords')
    if (attrTexCoordsIndex != -1):
        glVertexAttribPointer(attrTexCoordsIndex, NB_TEX_COORDS_AXES, GL_FLOAT, GL_FALSE, 8 * ctypes.sizeof(ctypes.c_float), ctypes.c_void_p(6 * ctypes.sizeof(ctypes.c_float)))
        glEnableVertexAttribArray(attrTexCoordsIndex)


    # Texture
    
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    # Set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) # Set texture wrapping to GL_REPEAT (default wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    # Set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    image = pygame.image.load('images/wall.jpg').convert_alpha()
    imageData = pygame.image.tostring(image, 'RGBA', 1)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.get_width(), image.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData)
    glGenerateMipmap(GL_TEXTURE_2D)

    # Unbind the VAO
    glBindVertexArray(0)

    # Unbind the VBO
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    if (attrPositionIndex != -1):
        glDisableVertexAttribArray(attrPositionIndex)
    if (attrColorIndex != -1):
        glDisableVertexAttribArray(attrColorIndex)
    if (attrTexCoordsIndex != -1):
        glDisableVertexAttribArray(attrTexCoordsIndex)
    
    # Unbind the EBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

    return VAO, texture

def initDisplay(shaderProgram):
    glEnable(GL_DEPTH_TEST)

    glUseProgram(shaderProgram)
    textureUniformIndex = glGetUniformLocation(shaderProgram, 'texUniform')
    glUniform1i(textureUniformIndex, 0)

def prepareDisplay():
    glClearColor(0.2, 0.3, 0.3, 1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

def drawObject(shaderProgram, VAO, texture):

    glActiveTexture(GL_TEXTURE0)
    glBindTexture(GL_TEXTURE_2D, texture)

    glUseProgram(shaderProgram)
    glBindVertexArray(VAO)
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ctypes.c_void_p(0))
    #glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)

def display():
    glBindVertexArray(0)
    glUseProgram(0)

def main():
    pygame.init()
    screen = pygame.display.set_mode((800, 600), pygame.OPENGL|pygame.DOUBLEBUF)

    shaderProgram = shaders.compileProgram(
        shaders.compileShader(vertexShader, GL_VERTEX_SHADER),
        shaders.compileShader(fragmentShader, GL_FRAGMENT_SHADER))
    
    initDisplay(shaderProgram)

    VAO, texture = createObject(shaderProgram, vertices1, indices1)

    clock = pygame.time.Clock()

    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

        prepareDisplay()
        drawObject(shaderProgram, VAO, texture)
        display()
        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    try:
        main()
    finally:
        pygame.quit()
+0 -0

Si tu bind un vao, alors qu’il y a un buffer bindé sur GL_ARRAY_BUFFER, il ne se passe rien de spécial. Les commandes glDraw* se fichent de ce buffer, elles ne s’interessent qu’à l’état du vao pour l’input du vertex shader.

Par contre si tu utilises l’instruction glVertexAttribPointer, là ton nouveau VAO va maintenant avoir une référence vers ce VBO (ce qui peut être l’effet désiré ou pas). Mais de toute façon:

  • si tu unbind ce VBO puis fait un glVertexAttribPointer, cela ne fait rien du tout au mieux, ou génère au pire une GL_INVALID_OPERATION.
  • si tu unbind ce VBO, bind un VAO, puis bind un autre VBO avant de faire glVertexAttribPointer, le unbind du VBO est donc totalement superflu, comme un conducteur qui repasserait toujours par le point mort en s’y attardant pour changer de vitesse au lieu de faire une transition fluide.
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte