Appliquer une texture sur deux triangles

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

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()

Édité par obedient

+0 -0

Salut,

glDrawArrays n’a que 3 arguments. Pour drawObject, essaye :

def drawObject(shaderProgram, VAO, texture):
    glUseProgram(shaderProgram)
    glBindVertexArray(VAO)

    glActiveTexture(GL_TEXTURE0)
    glBindTexture(GL_TEXTURE_2D, texture)

    glDrawArrays(GL_TRIANGLES, 0, 6)

Édité par anonyme

+0 -0

Parce que tu essayes de l’utiliser avec 4 :

glDrawElements(GL_TRIANGLES,
6,
GL_UNSIGNED_INT,
0)

EDIT : J’ai mal lu le nom de la fonction X/

Édité par anonyme

+0 -0
Auteur du sujet

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()

Édité par obedient

+0 -0

Je vois que tu as trouvé la solution à ton pb.

Juste une remarque par rapport à ton code: évite les unbind (et les glDisableVertexAttribArray alors qu’aucun vao n’est bindé), c’est totalement inutile, quoi qu’en disent tes tutos.

+0 -0
Auteur du sujet

Salut, merci pour le conseil.

A ce sujet j’ai une question, que se passe t-il si on ne unbind pas le VBO et que l’on bind plus loin un autre VAO, ne risque t-il pas d’y avoir un petit risque d’utilisation du VBO précédent ?

+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.

Édité par Pataques

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

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