Сбой OpenGL при использовании EBO - PullRequest
1 голос
/ 06 мая 2020

Итак, это немного особенное, потому что я понятия не имею, откуда на самом деле возникает ошибка. У меня есть сценарий PyOpenGL, который должен рисовать текстурированный прямоугольник с использованием VBO, VAO и EBO. Когда я пытаюсь запустить программу в терминале (я использую Ubuntu 16.04), она создает пустое прозрачное окно, делает паузу на некоторое время, затем снова закрывает окно и просто отправляет в терминал сообщение «Прервано». Больше ничего.

Думаю, это, вероятно, ошибка с моей стороны, поэтому вот код:

import math
import ctypes
import numpy as np
import glfw
from packages import shaderUtils
from PIL import Image
from OpenGL.GL import *

vert_shader_file = 'somename.vs'
frag_shader_file = 'somename.fs'

def main():

    glfw.init()
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 5)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    window = glfw.create_window(800, 600, "helo wold", None, None)

    glfw.make_context_current(window)

    #----------TEXTURE STUFF-----------#

    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    textureFile = Image.open('container.jpg')
    textureWidth, textureHeight, textureData = textureFile.size[0], textureFile.size[1], np.array(list(textureFile.getdata()), np.int8) 

    if textureData.any():
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData)
        glGenerateMipmap(GL_TEXTURE_2D)
    else:
        print('Failed to load texture')
    del textureData

    vertices = np.array([
         0.5, 0.5, 0,  1, 0, 0,  1, 1,
         0.5,-0.5, 0,  0, 1, 0,  1, 0,
        -0.5,-0.5, 0,  0, 0, 1,  0, 0,
        -0.5, 0.5, 0,  1, 1, 0,  0, 1], dtype = 'float32')
    indices = np.array([0, 1, 3,
                        1, 2, 3], dtype = 'int8')

    shaderProgram = shaderUtils.shader(vert_shader_file, frag_shader_file)
    shaderProgram.compile()

    vbo, vao, ebo = glGenBuffers(1), glGenVertexArrays(1), glGenBuffers(1)

    glBindVertexArray(vao)

    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(1)

    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(2)

    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)

     while not glfw.window_should_close(window):

        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        shaderProgram.use()

        glBindTexture(GL_TEXTURE_2D, texture)
        glBindVertexArray(vao)

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glDeleteVertexArrays(1, vao)
    glDeleteBuffers(1, vbo)
    glDeleteBuffers(1, ebo)


    glfw.terminate()

if __name__ == '__main__':
    main()

А вот мои вершинные и фрагментные шейдеры:

#version 450 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main() {
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}
#version 450 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord);
}

Я хотел бы знать, что я делаю не так, потому что я впервые использую EBO. Спасибо!

1 Ответ

1 голос
/ 06 мая 2020

Последний параметр glDrawElements имеет тип const GLvoid *, поэтому он должен быть None, а не 0:

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

Кроме того, тип данных в массиве индексов должен соответствовать аргументу type к glDrawElements.

Либо 'int32' и GL_UNSIGNED_INT:

indices = np.array([0, 1, 3, 1, 2, 3], dtype = 'int32')
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None) 

или 'int8' и GL_UNSIGNED_BYTE:

indices = np.array([0, 1, 3, 1, 2, 3], dtype = 'int8')
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, None) 

Конечно 'int16' и GL_UNSIGNED_SHORT тоже будет работать:

indices = np.array([0, 1, 3, 1, 2, 3], dtype = 'int16')
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, None) 
...