opengl - 如何更改一个顶点而不是所有顶点的颜色?

标签 opengl colors glsl vertex

我是OpenGL和GLSL的新手,正在通过http://open.gl/学习它。

我设法绘制了一个三角形,并使用以下命令更改了所有顶点的颜色:

glUniform3f(uniColor, red, 0.0, 0.0)

“红色”的值不断变化的地方,但这会更新三角形中所有顶点的颜色值,而我只想更改一个或两个顶点。

查看代码,我看不到在哪里可以实现任何逻辑来专注于一个顶点而不是全部顶点(代码几乎完全基于http://open.gl/content/code/c2_triangle_uniform.txt)

但是,在以下代码中:http://open.gl/content/code/c2_color_triangle.txt,每个顶点都有其自己的颜色,但似乎很难编码,随着程序的进行,我无法动态更改颜色。

我正在猜测
uniColor = glGetUniformLocation(shader.handle, "triangleColor")

给我一个可以更改的变量的位置,此变量用于更新所有顶点的颜色,也许我需要做的是创建3个变量,每个顶点一个,然后访问这些变量,但是我该怎么做?去做?

如果我查看GLSL,我会看到一个“均匀的vec3 triangleColor;”。然后用于
void main()
{
    outColor = vec4(triangleColor, 1.0);
}

但是,即使我创建了3个三角形颜色变量,我如何告诉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()

最佳答案

为每个顶点设置统一名称实际上并不是可扩展的。更好的方法是创建另一个顶点缓冲区对象来存储值。可以执行与您为头寸创建的操作类似的操作,不同之处在于此操作将包含3个GLfloat。您可以在数据更改时重新缓冲数据。

我的python很垃圾,因此我已经将您的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)

以后可以重新缓冲新的颜色:
## Upload new data to GPU
glBindBuffer(GL_ARRAY_BUFFER, vbocolors )
glBufferData(GL_ARRAY_BUFFER, sizeof(new_colors_gl), new_colors_gl, GL_STATIC_DRAW)

设置顶点属性指针:
colorAttrib = glGetAttribLocation(shader.handle, "color")
glEnableVertexAttribArray(colorAttrib )
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0)

然后在着色器中,您希望将此顶点颜色值从顶点着色器传递到片段着色器,片段着色器将在光栅化过程中相应地对其值进行插值。
# 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);
}
"""

关于opengl - 如何更改一个顶点而不是所有顶点的颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24788939/

相关文章:

java - JOGL OpenGL 只在奇怪的条件下渲染

opengl - 为什么 POT 和 NPOT 纹理的 GL_CLAMP_TO_EDGE 不同?

opencv - 有没有办法将颜色表示为单个值?

opengl - 在 GLSL 着色器中计算点投影

java - OpenGL slick-util 缺少类 : UnicodeFont not included in . jar

c++ - 使用GLUT中的按键旋转

opengl - 如何在GLSL程序中识别intel显卡?

c++ - OpenGL 实现多 channel

php - 用 LESS 反转所有颜色

Python:由数据点列表制作的 3D 绘图可以有渐变配色方案吗?