01A*_*key 8 opengl colors glsl vertex
我是OpenGL和GLSL的新手,我正在通过http://open.gl/学习它.
我已设法绘制一个三角形并使用以下方法更改所有顶点的颜色:
glUniform3f(uniColor, red, 0.0, 0.0)
Run Code Online (Sandbox Code Playgroud)
其中"红色"的值不断变化,但这会更新三角形中所有顶点的颜色值,而我只想更改一个或两个顶点.
查看代码我没看到我可以在哪里实现任何逻辑来关注一个顶点而不是全部(代码几乎完全基于http://open.gl/content/code/c2_triangle_uniform.txt)
但是在这段代码中:http://open.gl/content/code/c2_color_triangle.txt,每个顶点都有它自己的颜色,但它似乎是硬编码的,我不能随着程序的进展动态地改变颜色.
我正在猜测
uniColor = glGetUniformLocation(shader.handle, "triangleColor")
Run Code Online (Sandbox Code Playgroud)
给我一个变量的位置,我可以改变,这个变量用于更新所有顶点的颜色,也许我需要做的是创建3个变量,每个顶点一个,然后访问那些,但我怎么做去做?
如果我看一下GLSL我有一个"统一的vec3 triangleColor"; 然后用于
void main()
{
outColor = vec4(triangleColor, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
但即使我创建3个这样的triangleColor变量,我怎么能告诉void main()来区分哪个顶点获得什么变量?
代码:
import pyglet
from pyglet.gl import *
from shader import Shader
from ctypes import pointer, sizeof
import math
import time
window = pyglet.window.Window(800, 600, "OpenGL")
window.set_location(100, 100)
# Vertex Input
## Vertex Array Objects
vao = GLuint()
glGenVertexArrays(1, pointer(vao))
glBindVertexArray(vao)
## Vertex Buffer Object
vbo = GLuint()
glGenBuffers(1, pointer(vbo)) # Generate 1 buffer
vertices = [0.0, 0.5,
0.5, -0.5,
-0.5, -0.5]
## Convert the verteces array to a GLfloat array, usable by glBufferData
vertices_gl = (GLfloat * len(vertices))(*vertices)
## Upload data to GPU
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_gl), vertices_gl, GL_STATIC_DRAW)
# Shaders (Vertex and Fragment shaders)
vertex = """
#version 150
in vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
"""
fragment = """
#version 150
uniform vec3 triangleColor;
out vec4 outColor;
void main()
{
outColor = vec4(triangleColor, 1.0);
}
"""
## Compiling shaders and combining them into a program
shader = Shader(vertex, fragment)
shader.bind() #glUseProgram
# Making the link between vertex data and attributes
## shader.handle holds the value of glCreateProgram()
posAttrib = glGetAttribLocation(shader.handle, "position")
glEnableVertexAttribArray(posAttrib)
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0)
uniColor = glGetUniformLocation(shader.handle, "triangleColor")
# Set clear color
glClearColor(0.0, 0.0, 0.0, 1.0)
@window.event
def on_draw():
# Set the color of the triangle
red = (math.sin(time.clock() * 4.0) + 1.0) / 2.0
glUniform3f(uniColor, red, 0.0, 0.0)
# Clear the screen to black
glClear(GL_COLOR_BUFFER_BIT)
# Draw a triangle from the 3 vertices
glDrawArrays(GL_TRIANGLES, 0, 3)
@window.event
def on_key_press(symbol, modifiers):
pass
@window.event
def on_key_release(symbol, modifiers):
pass
def update(dt):
pass
pyglet.clock.schedule(update)
pyglet.app.run()
Run Code Online (Sandbox Code Playgroud)
为每个顶点设置一个统一体并不是真正可扩展的.更好的方法是创建另一个顶点缓冲区对象来存储值.这可以类似于您为位置创建的那个,除了这个将包含3个GLfloats.您可以在数据更改时重新缓冲数据.
我的python是垃圾,所以我用你的语法指南,但它应该是这样的:
## Vertex Buffer Object
vbocolors = GLuint()
glGenBuffers(1, pointer(vbocolors ))
colors = [1.0, 0.0, 0.0, # red vertex
0.0, 1.0, 0.0, # green vertex
0.0, 0.0, 1.0] # blue vertex
## Convert the verteces array to a GLfloat array, usable by glBufferData
colors_gl = (GLfloat * len(colors))(*colors)
## Upload data to GPU
glBindBuffer(GL_ARRAY_BUFFER, vbocolors )
glBufferData(GL_ARRAY_BUFFER, sizeof(colors_gl), colors_gl, GL_STATIC_DRAW)
Run Code Online (Sandbox Code Playgroud)
以后可以重新缓冲新颜色:
## Upload new data to GPU
glBindBuffer(GL_ARRAY_BUFFER, vbocolors )
glBufferData(GL_ARRAY_BUFFER, sizeof(new_colors_gl), new_colors_gl, GL_STATIC_DRAW)
Run Code Online (Sandbox Code Playgroud)
设置顶点属性指针:
colorAttrib = glGetAttribLocation(shader.handle, "color")
glEnableVertexAttribArray(colorAttrib )
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0)
Run Code Online (Sandbox Code Playgroud)
然后在着色器中,您希望将此顶点颜色值从顶点着色器传递到片段着色器,片段着色器将在光栅化过程中相应地插值其值.
# Shaders (Vertex and Fragment shaders)
vertex = """
#version 150
in vec2 position;
in vec3 color;
out vec3 interpColor;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
interpColor= color;
}
"""
fragment = """
#version 150
in vec3 interpColor;
out vec4 outColor;
void main()
{
outColor = vec4(interpColor, 1.0);
}
"""
Run Code Online (Sandbox Code Playgroud)