2014-07-16 4 views
6

मैं ओपनजीएल और जीएलएसएल के लिए नया हूं, और इसे http://open.gl/ के माध्यम से सीख रहा हूं।मैं उन सभी के बजाय एक वर्टेक्स का रंग कैसे बदलूं?

मैं एक त्रिकोण आकर्षित और उपयोग करने वाले सभी vertexes का रंग बदलने में कामयाब रहे है:

glUniform3f(uniColor, red, 0.0, 0.0) 

के "लाल" मूल्य कहाँ लगातार बदल रहा है, लेकिन यह सब vertexes का रंग मूल्य अद्यतन करता है त्रिकोण में, जबकि मैं केवल एक या दो कशेरुक बदलना चाहता हूं।

कोड पर देख रहे हैं मैं नहीं दिख रहा है जहां मैं किसी भी तर्क लागू कर सकते हैं (कोड लगभग पूरी तरह से http://open.gl/content/code/c2_triangle_uniform.txt पर आधारित है) उन सब के बजाय एक शीर्ष

इस कोड तथापि में पर ध्यान केंद्रित करने: http://open.gl/content/code/c2_color_triangle.txt, प्रत्येक वर्टेक्स को अपना रंग मिलता है, लेकिन ऐसा लगता है कि यह कठिन कोडित है, मैं प्रोग्राम की प्रगति के रूप में रंगों को गतिशील रूप से बदल नहीं सकता।

मैं

uniColor = glGetUniformLocation(shader.handle, "triangleColor") 

अनुमान लगा रहा हूँ मुझे एक चर के स्थान मैं बदल सकते हैं देता है और इस चर सभी vertexes के रंग अद्यतन करने के लिए प्रयोग किया जाता है, और कहा कि शायद मैं क्या करने की जरूरत 3 बनाने है चर, प्रत्येक चरम के लिए एक और फिर उन तक पहुंच, लेकिन मैं यह कैसे करूँ?

यदि मैं जीएलएसएल देखता हूं तो मेरे पास "वर्दी वीसी 3 त्रिकोण रंग" होता है; जो तब

void main() 
{ 
    outColor = vec4(triangleColor, 1.0); 
} 

में प्रयोग किया जाता है, लेकिन यहां तक ​​कि अगर मैं 3 तरह के triangleColor चर बनाने मैं कैसे बता होगा शून्य मुख्य() जो शिखर हो जाता है क्या चर भेद करने के लिए?

कोड:

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() 
+0

रंगों वाला दूसरा बफर बनाते हैं, यह आपकी स्थिति की तरह होना चाहिए, लेकिन इसे कशेरुक शेडर में उपयोग करने के बजाय, आप उन्हें टुकड़े टुकड़े –

उत्तर

5

प्रत्येक शिखर के लिए एक समान स्थापना वास्तव में स्केलेबल नहीं है। मूल्यों को स्टोर करने के लिए एक और वर्टेक्स बफर ऑब्जेक्ट बनाना बेहतर तरीका होगा। यह आपके द्वारा पदों के लिए बनाए गए एक के समान किया जा सकता है, सिवाय इसके कि इसमें 3 जीएलफ्लोएट होंगे। आप डेटा को फिर से बफर कर सकते हैं क्योंकि यह बदलता है।

मेरे अजगर बकवास है, तो मैं एक वाक्य रचना गाइड के रूप में तुम्हारा का उपयोग किया है, लेकिन यह की तर्ज पर कुछ होना चाहिए: फिर से बफ़र जा सकती है

## 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); 
} 
""" 
+2

में उपयोग करते हैं वास्तव में ऐसा करने का मूर्खतापूर्ण तरीका सभी वर्टेक्स विशेषताओं को रखना है एक आम वीबीओ, अक्सर एक अंतःस्थापित प्रारूप में, यानी '[(x, y, z, r, g, b, ...), ...]' – datenwolf

+0

मैं सहमत हूं, लेकिन मुझे लगता है कि शुरुआत के लिए दो अलग-अलग वीबीओ सुझाव देना आसान था इंटरलैशिंग और पॉइंटर ऑफ़सेट का उपयोग करने और विशेषता पॉइंटर्स के लिए आगे बढ़ने के बजाय। – kbirk

+0

इस मामले में, मुझे लगता है कि 'glBufferData()' में 'GL_DYNAMIC_DRAW' निर्दिष्ट करना बेहतर होगा, और उसके बाद रंग मान को अपडेट करने के लिए' glbufferSubData() 'का उपयोग करें। –

1

@ पांडवाटर के उत्तर में प्रस्तावित दृष्टिकोण पूरी तरह से मान्य और उचित है। क्योंकि विकल्प हमेशा मूल्यवान होते हैं, यहां थोड़ा अलग दृष्टिकोण है।

यहां विचार यह है कि आपके पास दो अलग-अलग रंगों के साथ दो वर्दी हैं। यह निर्दिष्ट करने के लिए कि कौन सा वर्टेक्स दो रंगों में से कौन सा उपयोग करता है, आप एक अतिरिक्त वर्टेक्स विशेषता प्रस्तुत करते हैं।यह अतिरिक्त विशेषता एक एकल फ्लोट है, जहां मूल्य 0.0 का अर्थ है कि आप पहले रंग का उपयोग करना चाहते हैं, और 1.0 जिसे आप दूसरे रंग का उपयोग करना चाहते हैं।

अपने त्रिकोण उदाहरण के लिए, कहें कि आप पहले और तीसरे कशेरुक नीले रंग और दूसरे चरम लाल रंग को रंगना चाहते हैं। इस तरह शिखर डेटा बढ़ाएँ:

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

तो फिर तुम, एक दूसरे शिखर विशेषता (नीचे दिए गए कोड में colorWeight नाम) की स्थापना की एक ही पैटर्न आप position के लिए इस्तेमाल किया गया था। आपके पास glEnableVertexAttribArray(), glVertexAttribPointer() आदि का दूसरा सेट होगा, इस नई विशेषता के लिए कॉल करें।

अपने शिखर शेडर में, आप नए colorWeight विशेषता जोड़ने, और यह टुकड़ा शेडर के माध्यम से पारित:

in vec2 position; 
in float colorWeight; 
out float fragColorWeight; 

void main() 
{ 
    gl_Position = vec4(position, 0.0, 1.0); 
    fragColorWeight = colorWeight; 
} 

फिर टुकड़ा शेडर में, अब आप दो समान रंग है, और उन पर आधारित मिश्रण रिश्तेदार रंग वजन:

uniform vec3 triangleColor; 
uniform vec3 secondaryColor; 
in float fragColorWeight; 
out vec4 outColor; 

void main() 
{ 
    vec3 mixedColor = mix(triangleColor, secondaryColor, fragColorWeight); 
    outColor = vec4(mixedColor, 1.0); 
} 

अब आप secondaryColor वर्दी चर के स्थान मिलता है, और यह triangleColor की स्वतंत्र रूप से सेट त्रिकोण का सिर्फ दूसरा शिखर का रंग बदलने के लिए कर सकते हैं।

संबंधित मुद्दे