void TextureAtlas::setupVBOandVAO() { glGenVertexArrays(1, &_VAOname); ccGLBindVAO(_VAOname); #define kQuadSize sizeof(_quads[0].bl) glGenBuffers(2, &_buffersVBO[0]); glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * _capacity, _quads, GL_DYNAMIC_DRAW); // vertices glEnableVertexAttribArray(kVertexAttrib_Position); glVertexAttribPointer(kVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, vertices)); // colors glEnableVertexAttribArray(kVertexAttrib_Color); glVertexAttribPointer(kVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, colors)); // tex coords glEnableVertexAttribArray(kVertexAttrib_TexCoords); glVertexAttribPointer(kVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_indices[0]) * _capacity * 6, _indices, GL_STATIC_DRAW); // Must unbind the VAO before changing the element buffer. ccGLBindVAO(0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERROR_DEBUG(); }
void CCTextureAtlas::setupVBOandVAO ( KDvoid ) { glGenVertexArrays ( 1, &m_uVAOname ); ccGLBindVAO ( m_uVAOname ); #define kQuadSize sizeof(m_pQuads[0].bl) glGenBuffers ( 2, &m_pBuffersVBO[0] ); glBindBuffer ( GL_ARRAY_BUFFER, m_pBuffersVBO[0] ); glBufferData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW ); // vertices glEnableVertexAttribArray ( kCCVertexAttrib_Position ); glVertexAttribPointer ( kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices ) ); // colors glEnableVertexAttribArray ( kCCVertexAttrib_Color ); glVertexAttribPointer ( kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors ) ); // tex coords glEnableVertexAttribArray ( kCCVertexAttrib_TexCoords ); glVertexAttribPointer ( kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords ) ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1] ); glBufferData ( GL_ELEMENT_ARRAY_BUFFER, sizeof ( m_pIndices[0] ) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW ); ccGLBindVAO ( 0 ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); CHECK_GL_ERROR_DEBUG ( ); }
void CCParticleSystemQuad::setupVBOandVAO() { glGenVertexArrays(1, &m_uVAOname); ccGLBindVAO(m_uVAOname); #define kQuadSize sizeof(m_pQuads[0].bl) glGenBuffers(2, &m_pBuffersVBO[0]); glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uTotalParticles, m_pQuads, GL_DYNAMIC_DRAW); // vertices glEnableVertexAttribArray(kCCVertexAttrib_Position); glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); // colors glEnableVertexAttribArray(kCCVertexAttrib_Color); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); // tex coords glEnableVertexAttribArray(kCCVertexAttrib_TexCoords); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uTotalParticles * 6, m_pIndices, GL_STATIC_DRAW); // Must unbind the VAO before changing the element buffer. ccGLBindVAO(0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERROR_DEBUG(); }
void GLESDebugDraw::resetVertexBuffers() { #if CC_TEXTURE_ATLAS_USE_VAO ccGLBindVAO(0); #endif glBindBuffer(GL_ARRAY_BUFFER, 0); }
void CCDrawNode::render() { if (m_bDirty) { glBindBuffer(GL_ARRAY_BUFFER, m_uVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(ccV2F_C4B_T2F)*m_uBufferCapacity, m_pBuffer, GL_STREAM_DRAW); m_bDirty = false; } #if CC_TEXTURE_ATLAS_USE_VAO ccGLBindVAO(m_uVao); #else ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex); glBindBuffer(GL_ARRAY_BUFFER, m_uVbo); // vertex glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, vertices)); // color glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, colors)); // texcood glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, texCoords)); #endif glDrawArrays(GL_TRIANGLES, 0, m_nBufferCount); glBindBuffer(GL_ARRAY_BUFFER, 0); //CC_INCREMENT_GL_DRAWS(1); }
bool CCDrawNode::init() { m_sBlendFunc.src = CC_BLEND_SRC; m_sBlendFunc.dst = CC_BLEND_DST; setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionLengthTexureColor)); ensureCapacity(512); #if CC_TEXTURE_ATLAS_USE_VAO glGenVertexArrays(1, &m_uVao); ccGLBindVAO(m_uVao); #endif glGenBuffers(1, &m_uVbo); glBindBuffer(GL_ARRAY_BUFFER, m_uVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(ccV2F_C4B_T2F)* m_uBufferCapacity, m_pBuffer, GL_STREAM_DRAW); glEnableVertexAttribArray(kCCVertexAttrib_Position); glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, vertices)); glEnableVertexAttribArray(kCCVertexAttrib_Color); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, colors)); glEnableVertexAttribArray(kCCVertexAttrib_TexCoords); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, texCoords)); glBindBuffer(GL_ARRAY_BUFFER, 0); #if CC_TEXTURE_ATLAS_USE_VAO ccGLBindVAO(0); #endif CHECK_GL_ERROR_DEBUG(); m_bDirty = true; #if CC_ENABLE_CACHE_TEXTURE_DATA // Need to listen the event only when not use batchnode, because it will use VBO CCNotificationCenter::sharedNotificationCenter()->addObserver(this, callfuncO_selector(CCDrawNode::listenBackToForeground), EVENT_COME_TO_FOREGROUND, NULL); #endif return true; }
// overriding draw method void CCParticleSystemQuad::draw() { CCAssert(!m_pBatchNode,"draw should not be called when added to a particleBatchNode"); CC_NODE_DRAW_SETUP(); ccGLBindTexture2D( m_pTexture->getName() ); ccGLBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst ); CCAssert( m_uParticleIdx == m_uParticleCount, "Abnormal error in particle quad"); #if CC_TEXTURE_ATLAS_USE_VAO // // Using VBO and VAO // ccGLBindVAO(m_uVAOname); #if CC_REBIND_INDICES_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); #endif glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0); #if CC_REBIND_INDICES_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #endif #else // // Using VBO without VAO // #define kQuadSize sizeof(m_pQuads[0].bl) ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); // vertices glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); // colors glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); // tex coords glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #endif CC_INCREMENT_GL_DRAWS(1); CHECK_GL_ERROR_DEBUG(); }
bool DrawNode::init() { _blendFunc.src = CC_BLEND_SRC; _blendFunc.dst = CC_BLEND_DST; setShaderProgram(ShaderCache::sharedShaderCache()->programForKey(kShader_PositionLengthTexureColor)); ensureCapacity(512); #if CC_TEXTURE_ATLAS_USE_VAO glGenVertexArrays(1, &_vao); ccGLBindVAO(_vao); #endif glGenBuffers(1, &_vbo); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(ccV2F_C4B_T2F)* _bufferCapacity, _buffer, GL_STREAM_DRAW); glEnableVertexAttribArray(kVertexAttrib_Position); glVertexAttribPointer(kVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, vertices)); glEnableVertexAttribArray(kVertexAttrib_Color); glVertexAttribPointer(kVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, colors)); glEnableVertexAttribArray(kVertexAttrib_TexCoords); glVertexAttribPointer(kVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, texCoords)); glBindBuffer(GL_ARRAY_BUFFER, 0); #if CC_TEXTURE_ATLAS_USE_VAO ccGLBindVAO(0); #endif CHECK_GL_ERROR_DEBUG(); _dirty = true; return true; }
KDvoid CCTextureAtlas::mapBuffers ( KDvoid ) { ccGLBindVAO ( 0 ); glBindBuffer ( GL_ARRAY_BUFFER, m_pBuffersVBO [ 0 ] ); glBufferData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads [ 0 ] ) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO [ 1 ]); glBufferData ( GL_ELEMENT_ARRAY_BUFFER, sizeof ( m_pIndices [ 0 ] ) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 ); CHECK_GL_ERROR_DEBUG ( ); }
void CCTextureAtlas::mapBuffers() { // Avoid changing the element buffer for whatever VAO might be bound. ccGLBindVAO(0); glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); CHECK_GL_ERROR_DEBUG(); }
CADrawView::~CADrawView() { free(m_pBuffer); m_pBuffer = NULL; glDeleteBuffers(1, &m_uVbo); m_uVbo = 0; #if CC_TEXTURE_ATLAS_USE_VAO glDeleteVertexArrays(1, &m_uVao); ccGLBindVAO(0); m_uVao = 0; #endif }
CCTextureAtlas::~CCTextureAtlas() { CCLOGINFO("cocos2d: CCTextureAtlas deallocing %p.", this); CC_SAFE_FREE(m_pQuads); CC_SAFE_FREE(m_pIndices); glDeleteBuffers(2, m_pBuffersVBO); #if CC_TEXTURE_ATLAS_USE_VAO glDeleteVertexArrays(1, &m_uVAOname); ccGLBindVAO(0); #endif CC_SAFE_RELEASE(m_pTexture); CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVNET_COME_TO_FOREGROUND); }
CCParticleSystemQuad::~CCParticleSystemQuad() { if (NULL == m_pBatchNode) { CC_SAFE_FREE(m_pQuads); CC_SAFE_FREE(m_pIndices); glDeleteBuffers(2, &m_pBuffersVBO[0]); #if CC_TEXTURE_ATLAS_USE_VAO glDeleteVertexArrays(1, &m_uVAOname); ccGLBindVAO(0); #endif } #if CC_ENABLE_CACHE_TEXTURE_DATA CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVENT_COME_TO_FOREGROUND); #endif }
CCDrawNode::~CCDrawNode() { free(m_pBuffer); m_pBuffer = NULL; glDeleteBuffers(1, &m_uVbo); m_uVbo = 0; #if CC_TEXTURE_ATLAS_USE_VAO glDeleteVertexArrays(1, &m_uVao); ccGLBindVAO(0); m_uVao = 0; #endif #if CC_ENABLE_CACHE_TEXTURE_DATA CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVENT_COME_TO_FOREGROUND); #endif }
TextureAtlas::~TextureAtlas() { CCLOGINFO("cocos2d: TextureAtlas deallocing %p.", this); CC_SAFE_FREE(_quads); CC_SAFE_FREE(_indices); glDeleteBuffers(2, _buffersVBO); #if CC_TEXTURE_ATLAS_USE_VAO glDeleteVertexArrays(1, &_VAOname); ccGLBindVAO(0); #endif CC_SAFE_RELEASE(_texture); #if CC_ENABLE_CACHE_TEXTURE_DATA NotificationCenter::getInstance()->removeObserver(this, EVNET_COME_TO_FOREGROUND); #endif }
void CCParticleSystemQuad::setBatchNode(CCParticleBatchNode * batchNode) { if( m_pBatchNode != batchNode ) { CCParticleBatchNode* oldBatch = m_pBatchNode; CCParticleSystem::setBatchNode(batchNode); // NEW: is self render ? if( ! batchNode ) { allocMemory(); initIndices(); setTexture(oldBatch->getTexture()); #if CC_TEXTURE_ATLAS_USE_VAO setupVBOandVAO(); #else setupVBO(); #endif } // OLD: was it self render ? cleanup else if( !oldBatch ) { // copy current state to batch ccV3F_C4B_T2F_Quad *batchQuads = m_pBatchNode->getTextureAtlas()->getQuads(); ccV3F_C4B_T2F_Quad *quad = &(batchQuads[m_uAtlasIndex] ); memcpy( quad, m_pQuads, m_uTotalParticles * sizeof(m_pQuads[0]) ); CC_SAFE_FREE(m_pQuads); CC_SAFE_FREE(m_pIndices); glDeleteBuffers(2, &m_pBuffersVBO[0]); memset(m_pBuffersVBO, 0, sizeof(m_pBuffersVBO)); #if CC_TEXTURE_ATLAS_USE_VAO glDeleteVertexArrays(1, &m_uVAOname); ccGLBindVAO(0); m_uVAOname = 0; #endif } } }
void ccGLEnableVertexAttribs( unsigned int flags ) { ccGLBindVAO(0); /* Position */ bool enablePosition = flags & kCCVertexAttribFlag_Position; if( enablePosition != s_bVertexAttribPosition ) { if( enablePosition ) glEnableVertexAttribArray( kCCVertexAttrib_Position ); else glDisableVertexAttribArray( kCCVertexAttrib_Position ); s_bVertexAttribPosition = enablePosition; } /* Color */ bool enableColor = (flags & kCCVertexAttribFlag_Color) != 0 ? true : false; if( enableColor != s_bVertexAttribColor ) { if( enableColor ) glEnableVertexAttribArray( kCCVertexAttrib_Color ); else glDisableVertexAttribArray( kCCVertexAttrib_Color ); s_bVertexAttribColor = enableColor; } /* Tex Coords */ bool enableTexCoords = (flags & kCCVertexAttribFlag_TexCoords) != 0 ? true : false; if( enableTexCoords != s_bVertexAttribTexCoords ) { if( enableTexCoords ) glEnableVertexAttribArray( kCCVertexAttrib_TexCoords ); else glDisableVertexAttribArray( kCCVertexAttrib_TexCoords ); s_bVertexAttribTexCoords = enableTexCoords; } }
void TextureAtlas::drawNumberOfQuads(int numberOfQuads, int start) { CCASSERT(numberOfQuads>=0 && start>=0, "numberOfQuads and start must be >= 0"); if(!numberOfQuads) return; ccGLBindTexture2D(_texture->getName()); #if CC_TEXTURE_ATLAS_USE_VAO // // Using VBO and VAO // // XXX: update is done in draw... perhaps it should be done in a timer if (_dirty) { glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); // option 1: subdata //glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] ); // option 2: data // glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW); // option 3: orphaning + glMapBuffer glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (numberOfQuads-start), NULL, GL_DYNAMIC_DRAW); void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); memcpy(buf, _quads, sizeof(_quads[0])* (numberOfQuads-start)); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); _dirty = false; } ccGLBindVAO(_VAOname); #if CC_REBIND_INDICES_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); #endif #if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) ); #else glDrawElements(GL_TRIANGLES, (GLsizei) numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) ); #endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #if CC_REBIND_INDICES_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #endif // glBindVertexArray(0); #else // ! CC_TEXTURE_ATLAS_USE_VAO // // Using VBO without VAO // #define kQuadSize sizeof(_quads[0].bl) glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); // XXX: update is done in draw... perhaps it should be done in a timer if (_dirty) { glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * numberOfQuads , &_quads[start] ); _dirty = false; } ccGLEnableVertexAttribs(kVertexAttribFlag_PosColorTex); // vertices glVertexAttribPointer(kVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices)); // colors glVertexAttribPointer(kVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors)); // tex coords glVertexAttribPointer(kVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); #if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP glDrawElements(GL_TRIANGLE_STRIP, (GLsizei)numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0]))); #else glDrawElements(GL_TRIANGLES, (GLsizei)numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0]))); #endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #endif // CC_TEXTURE_ATLAS_USE_VAO CC_INCREMENT_GL_DRAWS(1); CHECK_GL_ERROR_DEBUG(); }
KDvoid CCTextureAtlas::drawNumberOfQuads ( KDuint uNumber, KDuint uStart ) { if ( 0 == uNumber ) { return; } ccGLBindTexture2D ( m_pTexture->getName ( ) ); #if CC_TEXTURE_ATLAS_USE_VAO // // Using VBO and VAO // // XXX: update is done in draw... perhaps it should be done in a timer if ( m_bDirty ) { glBindBuffer ( GL_ARRAY_BUFFER, m_pBuffersVBO[0] ); // option 1: subdata // glBufferSubData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * uStart, sizeof ( m_pQuads[0] ) * uNumber , &m_pQuads [ uStart ] ); // option 2: data // glBufferData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * ( n - uStart ), &m_pQuads [ uStart ], GL_DYNAMIC_DRAW ); // option 3: orphaning + glMapBuffer glBufferData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * ( n - uStart ), KD_NULL, GL_DYNAMIC_DRAW ); KDvoid* pBuff = glMapBuffer ( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); kdMemcpy ( pBuff, m_pQuads, sizeof ( m_pQuads [ 0 ] ) * ( n - uStart ) ); glUnmapBuffer ( GL_ARRAY_BUFFER ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); m_bDirty = KD_FALSE; } ccGLBindVAO ( m_uVAOname ); #if CC_REBIND_INDICES_BUFFER glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1] ); #endif glDrawElements ( GL_TRIANGLES, (GLsizei) uNumber * 6, GL_UNSIGNED_SHORT, (GLvoid*) ( uStart * 6 * sizeof ( m_pIndices[0] ) ) ); #if CC_REBIND_INDICES_BUFFER glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 ); #endif // glBindVertexArray ( 0 ); #else // CC_TEXTURE_ATLAS_USE_VAO // // Using VBO without VAO // #define kQuadSize sizeof(m_pQuads[0].bl) glBindBuffer ( GL_ARRAY_BUFFER, m_pBuffersVBO[0] ); // XXX: update is done in draw... perhaps it should be done in a timer if ( m_bDirty ) { glBufferSubData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * uStart, sizeof ( m_pQuads[0] ) * uNumber , &m_pQuads[ uStart ] ); m_bDirty = KD_FALSE; } ccGLEnableVertexAttribs ( kCCVertexAttribFlag_PosColorTex ); ccGLVertexAttribPointer ( kCCVertexAttrib_Position , 3, GL_FLOAT , GL_FALSE, kQuadSize, (GLvoid*) offsetof ( ccV3F_C4B_T2F, vertices ) ); ccGLVertexAttribPointer ( kCCVertexAttrib_Color , 4, GL_UNSIGNED_BYTE, GL_TRUE , kQuadSize, (GLvoid*) offsetof ( ccV3F_C4B_T2F, colors ) ); ccGLVertexAttribPointer ( kCCVertexAttrib_TexCoords, 2, GL_FLOAT , GL_FALSE, kQuadSize, (GLvoid*) offsetof ( ccV3F_C4B_T2F, texCoords ) ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1] ); glDrawElements ( GL_TRIANGLES, (GLsizei) uNumber * 6, GL_UNSIGNED_SHORT, (GLvoid*) ( uStart * 6 * sizeof ( m_pIndices[0] ) ) ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 ); #endif // CC_TEXTURE_ATLAS_USE_VAO CC_INCREMENT_GL_DRAWS ( 1 ); CHECK_GL_ERROR_DEBUG ( ); }