简单混合器OpenGL三角形顶点位置损坏

时间:2019-04-30 01:35:09

标签: python blender pyopengl

尝试学习使用bgl在Blender视口中绘制。但是,无论我传递到bgl.Buffer以及传递到顶点着色器的哪个顶点位置,在视口的左下角都只会得到一个顶点。

我尝试在顶点着色器中对顶点位置进行硬编码,然后得到我的三角形。但是,一旦我在vec3 vPos中将硬编码的位置更改为layout(location = 0),就可以了。 ,并通过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 :(得分:0)

解决方案是Blender使用许多上下文来绘制UI的各个位。 程序,着色器,VBO等在上下文之间共享。但VAO并非如此。 因此,您必须在绘制循环中创建它。

最后,我在传递给View3D处理程序的draw函数中使用了一个简单的switch解决了这个问题:如果是第一次运行,请运行init阶段,然后继续进行绘制。