/// Draw a vertex array void RendererOpenGL::draw(const VertexArray2D& varray, const RenderState& state) { const char* data = reinterpret_cast<const char*>(&varray.m_vertices[0]); if(m_activeShader) { enableVertexAttribArray(0); enableVertexAttribArray(1); enableVertexAttribArray(2); setVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(VertexArray2D::Vertex), data + 0); setVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(VertexArray2D::Vertex), data + 8); setVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(VertexArray2D::Vertex), data + 12); drawArrays(varray.geometryType, 0, varray.m_vertices.size()); disableVertexAttribArray(0); disableVertexAttribArray(1); disableVertexAttribArray(2); } else { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, sizeof(VertexArray2D::Vertex), data + 0); glColorPointer(4, GL_UNSIGNED_BYTE,sizeof(VertexArray2D::Vertex), data + 8); glTexCoordPointer(2, GL_FLOAT, sizeof(VertexArray2D::Vertex), data + 12); drawArrays(varray.geometryType, 0, varray.m_vertices.size()); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } }
// Leaves mVAO bound void VertBatch::setupBuffers() { auto ctx = gl::context(); auto glslProg = ctx->getGlslProg(); if( ! glslProg ) return; const size_t verticesSizeBytes = mVertices.size() * sizeof(vec4); const size_t normalsSizeBytes = mNormals.size() * sizeof(vec3); const size_t colorsSizeBytes = mColors.size() * sizeof(ColorAf); const size_t texCoordsSizeBytes = mTexCoords.size() * sizeof(vec4); size_t totalSizeBytes = verticesSizeBytes + normalsSizeBytes + colorsSizeBytes + texCoordsSizeBytes; // allocate the VBO if we don't have one yet (which implies we're not using the context defaults) bool forceUpload = false; if( ! mVbo ) { // allocate the VBO and upload the data mVbo = gl::Vbo::create( GL_ARRAY_BUFFER, totalSizeBytes ); forceUpload = true; } ScopedBuffer ScopedBuffer( mVbo ); // if this VBO was freshly made, or we don't own the buffer because we use the context defaults if( ( forceUpload || ( ! mOwnsBuffers ) ) && ( ! mVertices.empty() ) ) { mVbo->ensureMinimumSize( totalSizeBytes ); // upload positions GLintptr offset = 0; mVbo->bufferSubData( offset, verticesSizeBytes, &mVertices[0] ); offset += verticesSizeBytes; // upload normals if( ! mNormals.empty() ) { mVbo->bufferSubData( offset, normalsSizeBytes, &mNormals[0] ); offset += normalsSizeBytes; } // upload colors if( ! mColors.empty() ) { mVbo->bufferSubData( offset, colorsSizeBytes, &mColors[0] ); offset += colorsSizeBytes; } // upload texCoords if( ! mTexCoords.empty() ) { mVbo->bufferSubData( offset, texCoordsSizeBytes, &mTexCoords[0] ); offset += texCoordsSizeBytes; } } // Setup the VAO ctx->pushVao(); // this will be popped by draw() if( ! mOwnsBuffers ) mVao->replacementBindBegin(); else { mVaoStorage = gl::Vao::create(); mVao = mVaoStorage.get(); mVao->bind(); } gl::ScopedBuffer vboScope( mVbo ); size_t offset = 0; if( glslProg->hasAttribSemantic( geom::Attrib::POSITION ) ) { int loc = glslProg->getAttribSemanticLocation( geom::Attrib::POSITION ); ctx->enableVertexAttribArray( loc ); ctx->vertexAttribPointer( loc, 4, GL_FLOAT, false, 0, (const GLvoid*)offset ); offset += verticesSizeBytes; } if( glslProg->hasAttribSemantic( geom::Attrib::NORMAL ) && ( ! mNormals.empty() ) ) { int loc = glslProg->getAttribSemanticLocation( geom::Attrib::NORMAL ); ctx->enableVertexAttribArray( loc ); ctx->vertexAttribPointer( loc, 3, GL_FLOAT, false, 0, (const GLvoid*)offset ); offset += normalsSizeBytes; } if( glslProg->hasAttribSemantic( geom::Attrib::COLOR ) && ( ! mColors.empty() ) ) { int loc = glslProg->getAttribSemanticLocation( geom::Attrib::COLOR ); ctx->enableVertexAttribArray( loc ); ctx->vertexAttribPointer( loc, 4, GL_FLOAT, false, 0, (const GLvoid*)offset ); offset += colorsSizeBytes; } if( glslProg->hasAttribSemantic( geom::Attrib::TEX_COORD_0 ) && ( ! mTexCoords.empty() ) ) { int loc = glslProg->getAttribSemanticLocation( geom::Attrib::TEX_COORD_0 ); ctx->enableVertexAttribArray( loc ); ctx->vertexAttribPointer( loc, 4, GL_FLOAT, false, 0, (const GLvoid*)offset ); } if( ! mOwnsBuffers ) mVao->replacementBindEnd(); ctx->popVao(); }