PyOpenGL 将变量传递给顶点着色器
PyOpenGL passing variable to the vertex shader
经过一些建议后,我决定通过困难的方式学习一点 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);
}
如果您使用属性,则必须定义一组通用顶点属性,每个顶点坐标有一个属性值(在您的例子中为 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
and set the value to the uniform by glUniform
:
获取制服("myUniform"
)的位置
myUniform = 0.3
# .....
glLinkProgram(shaderProgram)
myUniform_location = glGetUniformLocation(shaderProgram, "myUniform")
# .....
glUseProgram(shaderProgram)
glUniform1f(myUniform_location, myUniform)
glDrawArrays(GL_TRIANGLES, 0, 3)
经过一些建议后,我决定通过困难的方式学习一点 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);
}
如果您使用属性,则必须定义一组通用顶点属性,每个顶点坐标有一个属性值(在您的例子中为 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
and set the value to the uniform by glUniform
:
"myUniform"
)的位置
myUniform = 0.3
# .....
glLinkProgram(shaderProgram)
myUniform_location = glGetUniformLocation(shaderProgram, "myUniform")
# .....
glUseProgram(shaderProgram)
glUniform1f(myUniform_location, myUniform)
glDrawArrays(GL_TRIANGLES, 0, 3)