Простой блендер Повреждение вершин OpenGL Triangle - PullRequest
0 голосов
/ 30 апреля 2019

Попытка научиться рисовать в окне просмотра blender, используя bgl.Однако независимо от того, какие позиции вершин я передаю в bgl.Buffer и, следовательно, в вершинный шейдер, я получаю только одну вершину в левом нижнем углу области просмотра.

Я пытался жестко кодировать позиции вершин вВершинный шейдер, тогда я получаю свой треугольник. Но как только я изменяю жестко закодированные позиции на layout(location = 0)in vec3 vPos; и передаю данные через VBO, я не получаю тот же результат.

import bpy
import numpy as np
from bgl import *

draw_handler = None

print(f'{" Program Compile Start ":=^40}')
vertex_shader_source = """
#version 330

layout(location = 0) in vec3 vPos;

void main()
{
    gl_Position = vec4(vPos.xy,0,1);
}
"""
fragment_shader_source = """
#version 330

out vec4 FragColor;

void main()
{
    FragColor = vec4(0,1,0,1);
}
"""
statusVert = Buffer(GL_INT, [1])
statusFrag = Buffer(GL_INT, [1])
statusProgram = Buffer(GL_INT, [1])
program    = glCreateProgram()
shaderVert = glCreateShader(GL_VERTEX_SHADER)
shaderFrag = glCreateShader(GL_FRAGMENT_SHADER)

glShaderSource(shaderVert,vertex_shader_source)
glShaderSource(shaderFrag,fragment_shader_source)

glCompileShader(shaderVert)
glCompileShader(shaderFrag)
glGetShaderiv(shaderVert,GL_COMPILE_STATUS,statusVert)
glGetShaderiv(shaderFrag,GL_COMPILE_STATUS,statusFrag)

if   statusVert[0] == GL_TRUE   : print('Vertex Shader compilation successfull')
if statusFrag[0]   == GL_TRUE   : print('Fragment Shader compilation successfull')
if statusVert[0]   == GL_FALSE  : print('Vertex Shader compilation failed')
if statusFrag[0]   == GL_FALSE  : print('Fragment Shader compilation failed')


glAttachShader(program,shaderVert)
glAttachShader(program,shaderFrag)
glLinkProgram(program)

glGetProgramiv(program, GL_LINK_STATUS, statusProgram)
if   statusProgram[0] == GL_TRUE  : print('Program Linking Successfull')
elif statusProgram[0] == GL_FALSE : print('Program Linking Failed')
else: print('Program Linking unknown')
print(f'{" Program Compile end ":=^40}')

# Data

vertex_pos = [-0.5,-0.5, 0,
               0.5,-0.5, 0,
               0.0, 0.5, 0]
vertex_pos = np.array(vertex_pos,dtype=np.float64)
print(vertex_pos.itemsize)
vertex_buff = Buffer(GL_DOUBLE,[9],vertex_pos)
vertex_buff_size = len(vertex_pos)*8
print(vertex_buff_size)
print(vertex_buff)

VAO,VBO = Buffer(GL_INT,1),Buffer(GL_INT,1)
glGenVertexArrays(1,VAO)
glGenBuffers(1,VBO)
print(f'VAO:{VAO[0]} || VBO:{VBO[0]}')

glBindVertexArray(VAO[0])
glBindBuffer(GL_ARRAY_BUFFER,VBO[0])
glBufferData(GL_ARRAY_BUFFER, 9*8,vertex_buff,GL_STATIC_DRAW)

glEnableVertexAttribArray(0)
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*8,0)

glBindBuffer(GL_ARRAY_BUFFER,0)
glBindVertexArray(0)

def draw():
    glUseProgram(program)
    glBindVertexArray(VAO[0])

    glPointSize(30)
    glDrawArrays(GL_POINTS,0,3)

    glBindVertexArray(0)
    glUseProgram(0)



draw_handler = bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
def in_5_seconds():
    print(f'{" Ending ":=^40}')
    glDeleteBuffers(1,VBO)
    glDeleteVertexArrays(1,VAO)
    glDeleteShader(shaderVert)
    glDeleteShader(shaderFrag)
    glDeleteProgram(program)
    bpy.types.SpaceView3D.draw_handler_remove(draw_handler,'WINDOW')
bpy.app.timers.register(in_5_seconds, first_interval=5)

ЕслиЯ использую оболочку pyOpenGL с GLFW.Я бы получил треугольник или, в моем случае, точки один. Однако оболочка блендера отображает только одну точку.

1 Ответ

0 голосов
/ 20 июня 2019

Решение состояло в том, что Blender использует много контекстов для рисования различных битов пользовательского интерфейса. Программы, шейдеры, VBO и другие разделены между контекстами. Но ВАО нет. Поэтому вы должны создать его в цикле отрисовки.

В конце я решил ее с помощью простой switch внутри функции рисования, которая передается в обработчик View3D: если он запускается первый раз, вы запускаете этап инициализации, если нет, затем продолжаете рисовать.

...