2013-05-04 5 views
8

मैं एक समस्या मेरी शीर्ष सरणी हो रही हो रहा है करने के लिए ठीक से कहा:ओपन 3/4 glVertexAttribPointer कदम और ऑफसेट गलती

const float vertices[] = { 
/* position */ 0.75f, 0.75f, 0.0f, 1.0f, /* color */ 1.0f, 0.0f, 0.0f, 1.0f, 
/* position */ 0.75f, -0.75f, 0.0f, 1.0f, /* color */ 0.0f, 1.0f, 0.0f, 1.0f, 
/* position */ -0.75f, -0.75f, 0.0f, 1.0f, /* color */ 0.0f, 0.0f, 1.0f, 1.0f, }; 

... 

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); 
glEnableVertexAttribArray(0); 
glEnableVertexAttribArray(1); 
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)16); 

glDrawArrays(GL_TRIANGLES, 0, 3); 

glDisableVertexAttribArray(0); 
glDisableVertexAttribArray(1); 

मुझे समझ नहीं आता कि कैसे कदम और ऑफसेट काम करते हैं। मेरी स्थिति में glVertexAttribPointer() का उपयोग करने के बारे में क्या सही तरीका है?

उत्तर

21

बाइट्स में स्ट्रॉइड और ऑफ़सेट निर्दिष्ट हैं। आप 4 फ्लोट्स के रूप में स्थिति और रंग के साथ एक इंटरलेव्ड वर्टेक्स सरणी का उपयोग कर रहे हैं। किसी विशेष विशेषता सरणी में वें i-th तत्व से अगले तक पहुंचने के लिए, 8 फ्लोट्स की दूरी होती है, इसलिए चरण 8 * आकार (GLfloat) होना चाहिए। ऑफ़सेट बफर में प्रत्येक विशेषता सरणी के पहले तत्व की बाइट स्थिति है, इसलिए स्थिति के लिए आपके उदाहरण में यह 0 है, और रंग के लिए, यह 4 * आकार (GLfloat)

+0

क्या मेरे दो glVertexAttribPointer कदमों और मूल्यों होना ऑफसेट चाहिए? – user2350858

+0

user2350858 @: मैं पहले से ही इस सवाल का जवाब में लिखा: कदम 8 * sizeof (GLfloat) (ताकि आम तौर पर 32) और रंग के लिए स्थिति और 4 * sizeof (GLfloat) के लिए ऑफसेट 0 (आप पहले से ही करते हैं) है – derhass

15

चूंकि glVertexAttribPointer अक्सर परेशानी करता है, मैं इसे और समझाने की कोशिश करता हूं।

सूत्र विशेषताओं सरणी में आई-वें विशेषता के शुरू होने से स्थिति की गणना करने के लिए है:

startPos(i) = offset + i * stride (derhass' another answer से)

और नीचे ग्राफ में विस्तार से बताया: tightly packed arrtibute array


यदि आपको कोड उदाहरण की आवश्यकता है, तो पढ़ना जारी रखें।

Formatting VBO Data से, हम हम तीन प्रारूप में हमारे शीर्ष डेटा प्रबंधन कर सकते हैं पता है।


# way1 प्रत्येक विशेषता एक VBO: एक त्रिकोण ड्राइंग, Vert रंग और बनावट रंग मिलाया साथ का एक उदाहरण है, यहाँ Vert विशेषता डेटा तैयार करने के लिए तरीका है।

की तरह इस प्रारूप: (xyzxyz ...) (rgbrgb ...) (STST ....), और हम दोनों sride = 0 है और ऑफसेट = 0.

void prepareVertData_moreVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec) 
{ 
    GLfloat vertPos[] = { 
     -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, // positon 
    }; 
    GLfloat vertColor[] = { 
     1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // color 
    }; 
    GLfloat vertTextCoord[] = { 
     0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f  // texture coordinate 
    }; 

    GLuint VBOId[3]; 

    glGenVertexArrays(1, &VAOId); 
    glBindVertexArray(VAOId); 
    glGenBuffers(3, VBOId); 
    // specify position attribute 
    glBindBuffer(GL_ARRAY_BUFFER, VBOId[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertPos), vertPos, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
    glEnableVertexAttribArray(0); 
    // specify color attribute 
    glBindBuffer(GL_ARRAY_BUFFER, VBOId[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertColor), vertColor, GL_STATIC_DRAW); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
    glEnableVertexAttribArray(1); 
    // specify texture coordinate attribute 
    glBindBuffer(GL_ARRAY_BUFFER, VBOId[2]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertTextCoord), vertTextCoord, GL_STATIC_DRAW); 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, NULL); 
    glEnableVertexAttribArray(2); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 

    VBOIdVec.push_back(VBOId[0]); 
    VBOIdVec.push_back(VBOId[1]); 
    VBOIdVec.push_back(VBOId[2]); 
} 
कर सकते हैं

# way2: प्रत्येक विशेषता अनुक्रमिक है, एक एकल VBO में बैच किया गया है।

यह प्रारूप इस प्रकार है: (xyzxyzxyz ... rgbrgb ... ststst ...), हम stride = 0 को छोड़ सकते हैं लेकिन ऑफ़सेट निर्दिष्ट किया जाना चाहिए।

void prepareVertData_seqBatchVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec) 
{ 

    GLfloat vertices[] = { 
    -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, // position 
    1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // color 
    0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f  // texture coordinate 
    }; 

    GLuint VBOId; 
    glGenVertexArrays(1, &VAOId); 
    glBindVertexArray(VAOId); 

    glGenBuffers(1, &VBOId); 
    glBindBuffer(GL_ARRAY_BUFFER, VBOId); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    // specifiy position attribute 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); // stride can aslo be 3 * sizeof(GL_FLOAT) 
    glEnableVertexAttribArray(0); 
    // specify color attribute 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(9 * sizeof(GL_FLOAT))); 
    glEnableVertexAttribArray(1); 
    // specify texture coordinate 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(18 * sizeof(GL_FLOAT))); 
    glEnableVertexAttribArray(2); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 

    VBOIdVec.push_back(VBOId); 
} 

# way3: एक ही VBO

इस प्रारूप में इंटरलीव्ड विशेषता की तरह है: (xyzrgbstxyzrgbst ...), हम स्वयं ऑफसेट और डगों निर्दिष्ट करना होगा।

void prepareVertData_interleavedBatchVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec) 
{ 
    // interleaved data 
    GLfloat vertices[] = { 
     -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0 
     0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 1 
     0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // 2 
    }; 

    GLuint VBOId; 
    glGenVertexArrays(1, &VAOId); 
    glBindVertexArray(VAOId); 
    glGenBuffers(1, &VBOId); 
    glBindBuffer(GL_ARRAY_BUFFER, VBOId); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    // specify position attribute 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,8 * sizeof(GL_FLOAT), (GLvoid*)0); 
    glEnableVertexAttribArray(0); 
    // specify color attribute 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 
     8 * sizeof(GL_FLOAT),(GLvoid*)(3 * sizeof(GL_FLOAT))); 
    glEnableVertexAttribArray(1); 
    // specify texture coordinate 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 
     8 * sizeof(GL_FLOAT), (GLvoid*)(6 * sizeof(GL_FLOAT))); 
    glEnableVertexAttribArray(2); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 

    VBOIdVec.push_back(VBOId); 
} 

और डेरहास के उत्तर के लिए धन्यवाद।

+0

वाह, मैं था एक दिन (ज्यादातर बनाम दूसरों interleaving, और कैसे उपयोग करने के लिए ठीक से ऑफसेट) के बेहतर भाग के लिए 3 तरीकों में से मतभेद के आसपास मेरे मस्तिष्क रैप करने के लिए कोशिश कर रहा है, तो मैं कंधे से यह पक्ष को देखा, और यह सब स्पष्ट हो गया। धन्यवाद। ;) किसी भी विचार जो आम तौर पर तेजी से होता है? –

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