【问题标题】:PyOpenGL passing variable to the vertex shaderPyOpenGL 将变量传递给顶点着色器
【发布时间】:2018-11-27 05:09:36
【问题描述】:

经过一些建议后,我决定以艰苦的方式学习一点 OpenGL。我试图将一个 (float - 名为 myAttrib) 变量传递给顶点着色器,它似乎工作(第 33 行),但显然没有。稍后我想将代码分成更多部分。

代码:

from OpenGL.GL import *
from OpenGL.GL.shaders import *

import pygame
from pygame.locals import *
import numpy, time

def getFileContent(file):
    content = open(file, 'r').read()
    return content

def initDraw():
    pygame.init()
    pygame.display.set_mode((640, 480), HWSURFACE | OPENGL | DOUBLEBUF)

    vertices = [0.0, 0.5,
                0.5, -0.5,
                -0.5, -0.5,]

    vertices = numpy.array(vertices, dtype = numpy.float32)

    myAttrib = 0.3

    vertexShader = compileShader(getFileContent("helloTriangle.vert"), GL_VERTEX_SHADER)
    fragmentShader = compileShader(getFileContent("helloTriangle.frag"), GL_FRAGMENT_SHADER)

    shaderProgram = glCreateProgram()
    glAttachShader(shaderProgram, vertexShader)
    glAttachShader(shaderProgram, fragmentShader)
    glBindAttribLocation(shaderProgram, 1, "myAttrib")
    glLinkProgram(shaderProgram)

    print(glGetAttribLocation(shaderProgram, "myAttrib"))

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices)
    glEnableVertexAttribArray(0)

    glClearColor(0, 0, 0, 1)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

    glUseProgram(shaderProgram)
    glDrawArrays(GL_TRIANGLES, 0, 3)

    pygame.display.flip()
    time.sleep(2)

initDraw()

顶点着色器:

#version 130

attribute vec2 vPosition;
attribute float myAttrib;

void main()
{
    gl_Position = vec4(vPosition.x, vPosition.y + myAttrib, 0.0, 1.0);
}

片段着色器:

#version 130

void main()
{
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);            
}

【问题讨论】:

    标签: python opengl glsl shader pyopengl


    【解决方案1】:

    如果您使用属性,则必须定义一组通用顶点属性,每个顶点坐标有一个属性值(在您的情况下为 3)。见Vertex Specification
    如果您要使用统一,那么您可以为存储在默认统一块中的统一变量中的程序设置一个值(您可以想象这有点像全局变量)。见Uniform (GLSL):

    案例 1 - 属性 myAttrib

    顶点着色器

    #version 130
    
    attribute vec2 vPosition;
    attribute float myAttrib;
    
    void main()
    {
        gl_Position = vec4(vPosition.x, vPosition.y + myAttrib, 0.0, 1.0);
    }
    

    您必须像为顶点坐标定义一个通用顶点属性数组:

    attrib = [-0.2, 0.2, 0.0]
    myAttrib  = numpy.array(attrib, dtype = numpy.float32)
    
    # .....
    
    glLinkProgram(shaderProgram)
    myAttrib_location = glGetAttribLocation(shaderProgram, "myAttrib")
    
    # .....
    
    glVertexAttribPointer(myAttrib_location, 1, GL_FLOAT, GL_FALSE, 0, myAttrib)
    glEnableVertexAttribArray(myAttrib_location)
    

    glBindAttribLocation(shaderProgram, 1, "myAttrib")
    glLinkProgram(shaderProgram)
    
    # .....
    
    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, myAttrib)
    glEnableVertexAttribArray(1)
    

    案例 2 - 制服myUniform

    顶点着色器

    #version 130
    
    attribute vec2 vPosition;
    uniform float myUniform;
    
    void main()
    {
        gl_Position = vec4(vPosition.x, vPosition.y + myUniform, 0.0, 1.0);
    }
    

    通过glGetUniformLocation获取制服("myUniform")的位置,并通过glUniform将值设置为制服:

    myUniform = 0.3
    
    # .....
    
    glLinkProgram(shaderProgram)
    myUniform_location = glGetUniformLocation(shaderProgram, "myUniform")
    
    # .....
    
    glUseProgram(shaderProgram)
    glUniform1f(myUniform_location, myUniform)
    
    glDrawArrays(GL_TRIANGLES, 0, 3)
    

    【讨论】:

    • 使用我认为适合我需要的第二种方法后,我得到了这个:glUniform1f(myUniform_location, "myUniform") File "latebind.pyx", line 32, in OpenGL_accelerate.latebind.LateBind.__call__ ( src/latebind.c:989) ctypes.ArgumentError: 参数 2: : wrong type
    • @tenjohn 不是 "myUniform" 它是 myUniform => myUniform=0.3 glUniform1f(myUniform_location, myUniform)glUniform1f(myUniform_location, 0.3) 注意,glUniform1f 将值 (0.3) 分配给位置 @987654341 的制服@.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2014-11-02
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    相关资源
    最近更新 更多