//----------------------------------------------------------------------------------------------- void ShipBlueprint::BuildShipVertexData() { static const float DIST_FROM_CENTER_TO_ENGINE_X = 2.5f; static const float DIST_FROM_CENTER_TO_ENGINE_Y = 2.5f; static const float DIST_FROM_CENTER_TO_FRONT = 10.f; static const float DIST_FROM_CENTER_TO_WINGTIP_X = 7.5f; static const float DIST_FROM_CENTER_TO_WINGTIP_Y = 7.5f; static const Color SHIP_COLOR( 154, 196, 237, 255 ); Simple2DVertex* shipVertexArray = reinterpret_cast< Simple2DVertex* >( m_vertices.data ); shipVertexArray[ 0] = Simple2DVertex( -DIST_FROM_CENTER_TO_ENGINE_Y , -DIST_FROM_CENTER_TO_ENGINE_X , SHIP_COLOR ); shipVertexArray[ 1] = Simple2DVertex( -DIST_FROM_CENTER_TO_WINGTIP_Y , -DIST_FROM_CENTER_TO_WINGTIP_X , SHIP_COLOR ); shipVertexArray[ 2] = shipVertexArray[ 1 ]; shipVertexArray[ 3] = Simple2DVertex( DIST_FROM_CENTER_TO_FRONT , 0.f , SHIP_COLOR ); shipVertexArray[ 4] = shipVertexArray[ 3 ]; shipVertexArray[ 5] = Simple2DVertex( -DIST_FROM_CENTER_TO_WINGTIP_Y , DIST_FROM_CENTER_TO_WINGTIP_X , SHIP_COLOR ); shipVertexArray[ 6] = shipVertexArray[ 5 ]; shipVertexArray[ 7] = Simple2DVertex( -DIST_FROM_CENTER_TO_ENGINE_Y , DIST_FROM_CENTER_TO_ENGINE_X , SHIP_COLOR ); shipVertexArray[ 8] = shipVertexArray[ 5 ]; shipVertexArray[ 9] = shipVertexArray[ 0 ]; m_vertices.data = &shipVertexArray[0]; m_vertices.vertexSizeBytes = sizeof( Simple2DVertex ); m_vertices.numberOfVertices = NUM_SHIP_VERTICES; m_vertices.attributes.push_back( VertexAttribute( RendererInterface::DEFAULT_NAME_Vertex, 2, RendererInterface::TYPE_FLOAT, false, sizeof( Simple2DVertex ), offsetof( Simple2DVertex, position.x ) ) ); m_vertices.attributes.push_back( VertexAttribute( RendererInterface::DEFAULT_NAME_Color, 4, RendererInterface::TYPE_UNSIGNED_BYTE, true, sizeof( Simple2DVertex ), offsetof( Simple2DVertex, color.r ) ) ); m_vertices.shape = RendererInterface::LINES; RendererInterface::GenerateBuffer( 1, &m_vertices.bufferID ); RendererInterface::BufferVertexData( &m_vertices ); }
VertexFormat::VertexFormat( const char* def ) { int begin = 0; int i = 0; bool wasSpace = true; for(; def[i] != '\0'; ++i) { char ch = def[i]; bool isSpace = std::isspace(ch); // Wechsel von WS if(wasSpace && !isSpace) { begin = i; } // Wechsel zu WS else if(!wasSpace && isSpace) { assert((i-begin) >= 0); appendAttribute(VertexAttribute(&def[begin], i-begin)); begin = -1; } wasSpace = isSpace; } if(begin >= 0) { assert((i-begin) >= 0); appendAttribute(VertexAttribute(&def[begin], i-begin)); } }
bool DrawNode::init() { setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR)); _vbTriangles = VertexBuffer::create(sizeof(V2F_C4B_T2F), 2048, VertexBuffer::ArrayType::All, VertexBuffer::ArrayMode::Dynamic); _vdTriangles = VertexData::create(VertexData::Primitive::Triangles); _vdTriangles->addStream(_vbTriangles, VertexAttribute(offsetof(V2F_C4B_T2F, vertices), GLProgram::VERTEX_ATTRIB_POSITION, DataType::Float, 2)); _vdTriangles->addStream(_vbTriangles, VertexAttribute(offsetof(V2F_C4B_T2F, colors), GLProgram::VERTEX_ATTRIB_COLOR, DataType::UByte, 4, true)); _vdTriangles->addStream(_vbTriangles, VertexAttribute(offsetof(V2F_C4B_T2F, texCoords), GLProgram::VERTEX_ATTRIB_TEX_COORD, DataType::Float, 2)); CC_SAFE_RETAIN(_vdTriangles); CC_SAFE_RETAIN(_vbTriangles); _vbLines = VertexBuffer::create(sizeof(V2F_C4B_T2F), 2048, VertexBuffer::ArrayType::All, VertexBuffer::ArrayMode::Dynamic); _vdLines = VertexData::create(VertexData::Primitive::Lines); _vdLines->addStream(_vbLines, VertexAttribute(offsetof(V2F_C4B_T2F, vertices), GLProgram::VERTEX_ATTRIB_POSITION, DataType::Float, 2)); _vdLines->addStream(_vbLines, VertexAttribute(offsetof(V2F_C4B_T2F, colors), GLProgram::VERTEX_ATTRIB_COLOR, DataType::UByte, 4, true)); _vdLines->addStream(_vbLines, VertexAttribute(offsetof(V2F_C4B_T2F, texCoords), GLProgram::VERTEX_ATTRIB_TEX_COORD, DataType::Float, 2)); CC_SAFE_RETAIN(_vdLines); CC_SAFE_RETAIN(_vbLines); _vbPoints = VertexBuffer::create(sizeof(V2F_C4B_PF), 2048, VertexBuffer::ArrayType::All, VertexBuffer::ArrayMode::Dynamic); _vdPoints = VertexData::create(VertexData::Primitive::Points); _vdPoints->addStream(_vbPoints, VertexAttribute(offsetof(V2F_C4B_PF, vertices), GLProgram::VERTEX_ATTRIB_POSITION, DataType::Float, 2)); _vdPoints->addStream(_vbPoints, VertexAttribute(offsetof(V2F_C4B_PF, colors), GLProgram::VERTEX_ATTRIB_COLOR, DataType::UByte, 4, true)); _vdPoints->addStream(_vbPoints, VertexAttribute(offsetof(V2F_C4B_PF, pointSize), GLProgram::VERTEX_ATTRIB_POINTSIZE, DataType::Float, 1)); CC_SAFE_RETAIN(_vdPoints); CC_SAFE_RETAIN(_vbPoints); return true; }
GLuint Mesh::addVertexAttribute(const GLfloat& data, int sizeBytes, int elementsPerVertex, BufferUsage usage) { int attributeIndex = m_vertexAttributes.size(); m_vertexAttributes.push_back(VertexAttribute(attributeIndex, elementsPerVertex)); GLuint buffer = m_vertexAttributes.back().createBuffer(&data, sizeBytes, usage); return buffer; }
APG::VertexAttributeList::VertexAttributeList(std::vector<VertexAttribute> &attVec) { for (const auto &att : attVec) { attributes.emplace_back(VertexAttribute(att)); } calculateOffsets(); }
APG::VertexAttributeList::VertexAttributeList(std::initializer_list<VertexAttribute> initList) { for (const auto &att : initList) { attributes.emplace_back(VertexAttribute(att)); } calculateOffsets(); }
void Vertex::print() { for(int i = 0; i < VERTEX_ATTRIB_MAX; i++) { VertexAttribute attrib = VertexAttribute(i); if(m_format.isAttributeEnabled(attrib)) { LOG("Attrib: %i", attrib); stringstream ss; for(int j = 0; j < m_format.getElementCount(attrib); j++) { switch(m_format.getDataType(attrib)) { case XD_FLOAT: ss << ((float*)(m_data + m_format.getAttributeOffset(attrib)))[j]; break; case XD_UINT: case XD_INT: ss << ((int*)(m_data + m_format.getAttributeOffset(attrib)))[j]; break; case XD_USHORT: case XD_SHORT: ss << ((short*)(m_data + m_format.getAttributeOffset(attrib)))[j]; break; case XD_UBYTE: case XD_BYTE: ss << (int)((char*)(m_data + m_format.getAttributeOffset(attrib)))[j]; break; } ss << " "; } LOG("%s", ss.str().c_str()); } } }
VertexAttribute VertexBuffer::GetAttribute(string name) { map<string, VertexAttribute>::iterator found_name = attributes.find(name); if(found_name != attributes.end()) return found_name->second; else return VertexAttribute(); }
Billboard::Billboard ( const Texture * texture ) : _drawCall ( GL_POINTS ), _texture ( texture ), _scale ( 1, 1 ) { _pointBuffer.loadData ( glm::value_ptr ( _pos ), 3*sizeof ( GLfloat ) ); _drawCall.setElements ( 1 ); _drawCall.addAttribute ( VertexAttribute ( &_pointBuffer, GL_FLOAT, 3 ) ); }
//----------------------------------------------------------------------------------------------- void MissileBlueprint::BuildMissileVertexData() { static const Color MISSILE_COLOR( 242, 126, 126, 255 ); Simple2DVertex* shipVertexArray = reinterpret_cast< Simple2DVertex* >( m_vertices.data ); shipVertexArray[ 0] = Simple2DVertex( 0.f , 0.f , MISSILE_COLOR ); shipVertexArray[ 1] = Simple2DVertex( -8.f , 0.f , MISSILE_COLOR ); m_vertices.data = &shipVertexArray[0]; m_vertices.vertexSizeBytes = sizeof( Simple2DVertex ); m_vertices.numberOfVertices = NUM_MISSILE_VERTICES; m_vertices.attributes.push_back( VertexAttribute( RendererInterface::DEFAULT_NAME_Vertex, 2, RendererInterface::TYPE_FLOAT, false, sizeof( Simple2DVertex ), offsetof( Simple2DVertex, position.x ) ) ); m_vertices.attributes.push_back( VertexAttribute( RendererInterface::DEFAULT_NAME_Color, 4, RendererInterface::TYPE_UNSIGNED_BYTE, true, sizeof( Simple2DVertex ), offsetof( Simple2DVertex, color.r ) ) ); m_vertices.shape = RendererInterface::LINES; RendererInterface::GenerateBuffer( 1, &m_vertices.bufferID ); RendererInterface::BufferVertexData( &m_vertices ); }
//---------------------------------------------------------------------------------- static bool Initialise() { if (!Device::Initialise()) { return false; } static const VertexAttribute attrs[] = { VertexAttribute("Position", GL_FLOAT, 3, offsetof(Vertex, position)), VertexAttribute("TexCoord0", GL_FLOAT, 2, offsetof(Vertex, textureCoord)) }; static const Vertex vertices[] = { { glm::vec3(-0.75f, 0.75f, 0.0f), glm::vec2(0.0f, 1.0f) }, { glm::vec3(-0.75f, -0.75f, 0.0f), glm::vec2(0.0f, 0.0f) }, { glm::vec3( 0.75f, -0.75f, 0.0f), glm::vec2(1.0f, 0.0f) }, { glm::vec3( 0.75f, 0.75f, 0.0f), glm::vec2(1.0f, 1.0f) } }; static const unsigned short indices[] = { 0, 1, 2, 2, 3, 0 }; // Create a vertex array of 1 buffer of 3 vertices of 2 attributes... boost::shared_ptr<VertexBuffer> vb = CreateVertexBuffer(sizeof(vertices), GL_STATIC_DRAW); vb->Enable(); vb->SetData(vertices, sizeof(vertices), 0); VertexBuffer::Disable(); VertexDeclarationPtr decl(new VertexDeclaration(sizeof(Vertex), vb, attrs, 2)); renderState.vertexArray = boost::make_shared<VertexArray>(&decl, 1); renderState.indexBuffer = CreateIndexBuffer(sizeof(indices), GL_UNSIGNED_SHORT, GL_STATIC_DRAW); renderState.indexBuffer->Enable(); renderState.indexBuffer->SetData(indices, sizeof(indices), 0); renderState.indexBuffer->Disable(); renderState.shader = boost::make_shared<Shader>("shaders/bricks"); if (!renderState.shader->Build()) { return false; } oldKeyState = Keyboard::GetState(); return true; }
void VertexBuffer::AddAttribute(string name, VertexAttributeType type, int n_per_vertex) { RemoveAttribute(name); // in case it already exists! VertexAttribute attribute = VertexAttribute(name, type, n_per_vertex); attributes[name] = attribute; int num_elements = n_per_vertex * allocated_size; if(type == Float) attribute_data[name].floats = num_elements > 0 ? new float[num_elements] : NULL; }
MeshFactory::MeshFactory() { mesh_3d_vertex_specification.addAttribute(VertexAttribute("position", 3, 0)); mesh_3d_vertex_specification.addAttribute(VertexAttribute("normal", 3, 3)); mesh_3d_vertex_specification.addAttribute(VertexAttribute("texture_coordinates", 2, 6)); billboard_mesh_vertex_specification.addAttribute(VertexAttribute("position", 3, 0)); billboard_mesh_vertex_specification.addAttribute(VertexAttribute("texture_coordinates", 2, 3)); flat_mesh_vertex_specification.addAttribute(VertexAttribute("position", 2, 0)); flat_mesh_vertex_specification.addAttribute(VertexAttribute("texture_coordinates", 2, 2)); }
void SpriteBatch::initialize(uint a_size) { m_size = a_size; const VertexAttribute attributes[] = { VertexAttribute(0, VertexAttribute::EFormat::FLOAT, 2), // Position VertexAttribute(1, VertexAttribute::EFormat::FLOAT, 2), // Texcoords }; eastl::vector<ushort> indices; indices.reserve(m_size * 6); for (uint i = 0, j = 0; i < m_size * 6; i += 6, j += 4) { indices.push_back(j + 0); indices.push_back(j + 1); indices.push_back(j + 2); indices.push_back(j + 0); indices.push_back(j + 2); indices.push_back(j + 3); } m_shader.initialize(VERT_SHADER_FILE, FRAG_SHADER_FILE); m_vertexBuffer.initialize(GLVertexBuffer::EBufferType::ARRAY, GLVertexBuffer::EDrawUsage::STREAM); m_indiceBuffer.initialize(GLVertexBuffer::EBufferType::ELEMENT_ARRAY, GLVertexBuffer::EDrawUsage::STATIC); m_stateBuffer.initialize(); m_shader.begin(); m_mvpUniform.initialize(m_shader, "u_mvp"); m_shader.end(); m_stateBuffer.begin(); m_vertexBuffer.setVertexAttributes(as_span(attributes, ARRAY_SIZE(attributes))); m_indiceBuffer.upload(as_span(rcast<const byte*>(&indices[0]), indices.size_bytes())); m_stateBuffer.end(); m_initialzied = true; }
/** This method sets up all the graphics related stuff like the Meshes, the camera and the Font */ void Pong::setupGraphics() { // // We first construct the paddle mesh which consists of // four 2D vertices forming a vertically elongated rectangle // constructed around the origin. We don't use colors, normals // texture coordinates or indices. Note that we use a fixed // point Mesh here. The paddle has dimensions (10, 60). // paddleMesh = new Mesh(true, VertexAttribute(VertexAttributes::Position, 2, "a_position")); float vertices[] = {-5, -30, 5, -30, 5, 30, -5, 30}; paddleMesh->setVertices(vertices, 8); // // We do the same for the ball which has dimensions (10,10) // ballMesh = new Mesh(true, VertexAttribute(VertexAttributes::Position, 2, "a_position")); float ballVerts[] = {-5, -5, 5, -5, 5, 5, -5, 5}; ballMesh->setVertices(ballVerts, 8); // // We construct a new font from a system font. We assume // Arial is installed on both the desktop and Android. // // font = Gdx.graphics.newFont("Arial", 30, FontStyle.Plain); score = "0 : 0"; spriteBatch = new SpriteBatch(); // // Finally we construct an {@link OrthographicCamera} which // will scale our scene to 480x320 pixels no matter what the // real screen dimensions. This will of course squish the scene // on devices like the Droid. The screen center will be at (0,0) // so that's the reference frame for our scene. // camera = new OrthographicCamera(480, 320); }
void VertexFormat::set(const VertexAttribute attrib, const int size, const DataType dataType) { if(size >= 0 && size <= 4) { m_attributes[attrib].elementCount = size; m_attributes[attrib].dataType = dataType; m_vertexByteSize = 0; for(int i = 0; i < VERTEX_ATTRIB_MAX; i++) { VertexAttribute at = VertexAttribute(i); if(isAttributeEnabled(at)) { m_attributes[at].offset = m_vertexByteSize; switch(getDataType(at)) { case XD_FLOAT: m_vertexByteSize += sizeof(float)*getElementCount(at); break; case XD_UINT: case XD_INT: m_vertexByteSize += sizeof(int)*getElementCount(at); break; case XD_USHORT: case XD_SHORT: m_vertexByteSize += sizeof(short)*getElementCount(at); break; case XD_UBYTE: case XD_BYTE: m_vertexByteSize += sizeof(char)*getElementCount(at); break; } } } } else { LOG("VertexFormat::set(): Size must be in the range [0, 4]."); } }
//-------------------------------------------------------------- void ofVbo::clearVertices(){ positionAttribute = VertexAttribute(); bUsingVerts = false; totalVerts = 0; }
/** Add a vertex attribute to the buffer. */ void VertexBufferBuilder::addAttribute(const string &name, int size) { attributes.push_back(VertexAttribute(name, size)); }
//-------------------------------------------------------------- void ofVbo::clearColors(){ colorAttribute = VertexAttribute(); bUsingColors = false; }
//-------------------------------------------------------------- void ofVbo::clearVertices(){ positionAttribute = VertexAttribute(); positionAttribute.location = ofShader::POSITION_ATTRIBUTE; bUsingVerts = false; totalVerts = 0; }
//-------------------------------------------------------------- void ofVbo::clearTexCoords(){ texCoordAttribute = VertexAttribute(); bUsingTexCoords = false; }
//-------------------------------------------------------------- void ofVbo::clearColors(){ colorAttribute = VertexAttribute(); colorAttribute.location = ofShader::COLOR_ATTRIBUTE; bUsingColors = false; }
//-------------------------------------------------------------- void ofVbo::clearNormals(){ normalAttribute = VertexAttribute(); normalAttribute.location = ofShader::NORMAL_ATTRIBUTE; bUsingNormals = false; }
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) { if (!mStreamingBuffer) { return GL_OUT_OF_MEMORY; } const VertexAttributeArray &attribs = mContext->getVertexAttributes(); Program *program = mContext->getCurrentProgram(); ProgramBinary *programBinary = program->getProgramBinary(); for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) { translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1); } // Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active && attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; if (staticBuffer) { if (staticBuffer->size() == 0) { int totalCount = elementsInBuffer(attribs[i], buffer->size()); staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount, 0)); } else if (staticBuffer->lookupAttribute(attribs[i]) == -1) { // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer // Add the space of all previous attributes belonging to the invalidated static buffer to the streaming buffer for (int previous = 0; previous < i; previous++) { if (translated[previous].active && attribs[previous].mArrayEnabled) { Buffer *previousBuffer = attribs[previous].mBoundBuffer.get(); StaticVertexBuffer *previousStaticBuffer = previousBuffer ? previousBuffer->getStaticVertexBuffer() : NULL; if (staticBuffer == previousStaticBuffer) { mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances)); } } } mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); buffer->invalidateStaticData(); } } else { mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); } } } // Reserve the required space per used buffer for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active && attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); ArrayVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer; if (vertexBuffer) { vertexBuffer->reserveRequiredSpace(); } } } // Perform the vertex data translations for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active) { if (attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); if (!buffer && attribs[i].mPointer == NULL) { // This is an application error that would normally result in a crash, but we catch it and return an error ERR("An enabled vertex array has no buffer and no pointer."); return GL_INVALID_OPERATION; } const FormatConverter &converter = formatConverter(attribs[i]); StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer); std::size_t streamOffset = -1; if (staticBuffer) { streamOffset = staticBuffer->lookupAttribute(attribs[i]); if (streamOffset == -1) { // Convert the entire buffer int totalCount = elementsInBuffer(attribs[i], buffer->size()); int startIndex = attribs[i].mOffset / attribs[i].stride(); streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i], 0); } if (streamOffset != -1) { streamOffset += (attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize; if (instances == 0 || attribs[i].mDivisor == 0) { streamOffset += start * converter.outputElementSize; } } } else { streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i], instances); } if (streamOffset == -1) { return GL_OUT_OF_MEMORY; } translated[i].vertexBuffer = vertexBuffer->getBuffer(); translated[i].serial = vertexBuffer->getSerial(); translated[i].divisor = attribs[i].mDivisor; translated[i].type = converter.d3dDeclType; translated[i].stride = converter.outputElementSize; translated[i].offset = streamOffset; } else { if (!mCurrentValueBuffer[i]) { mCurrentValueBuffer[i] = new StreamingVertexBuffer(mDevice, CONSTANT_VERTEX_BUFFER_SIZE); } StreamingVertexBuffer *buffer = mCurrentValueBuffer[i]; if (mDirtyCurrentValue[i]) { const int requiredSpace = 4 * sizeof(float); buffer->addRequiredSpace(requiredSpace); buffer->reserveRequiredSpace(); float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i])); if (data) { data[0] = attribs[i].mCurrentValue[0]; data[1] = attribs[i].mCurrentValue[1]; data[2] = attribs[i].mCurrentValue[2]; data[3] = attribs[i].mCurrentValue[3]; buffer->unmap(); mDirtyCurrentValue[i] = false; } } translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer(); translated[i].serial = mCurrentValueBuffer[i]->getSerial(); translated[i].divisor = 0; translated[i].type = D3DDECLTYPE_FLOAT4; translated[i].stride = 0; translated[i].offset = mCurrentValueOffsets[i]; } } } for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active && attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); if (buffer) { buffer->promoteStaticUsage(count * attribs[i].typeSize()); } } } return GL_NO_ERROR; }
//-------------------------------------------------------------- void ofVbo::clearTexCoords(){ texCoordAttribute = VertexAttribute(); texCoordAttribute.location = ofShader::TEXCOORD_ATTRIBUTE; bUsingTexCoords = false; }
void APG::VertexAttributeList::addAttribute(const APG::VertexAttribute &attribute) { attributes.emplace_back(VertexAttribute(attribute)); }
//-------------------------------------------------------------- void ofVbo::clearNormals(){ normalAttribute = VertexAttribute(); bUsingNormals = false; }
OverlayBatch::OverlayBatch(GraphicsContext* graphicsContext, std::size_t maxOverlayCount): maxOverlayCount(maxOverlayCount), overlayCount(0), vertexBuffer(nullptr), indexBuffer(nullptr), image(nullptr) { std::size_t vertexCount = maxOverlayCount * 4; std::size_t indexCount = maxOverlayCount * 6; // Create vertex buffer VertexAttribute attributes[] = { VertexAttribute(VertexAttributeFormat::VECTOR_3, 0), VertexAttribute(VertexAttributeFormat::VECTOR_2, 1), VertexAttribute(VertexAttributeFormat::VECTOR_4, 5) }; VertexFormat vertexFormat(0, attributes, 3); vertexBuffer = graphicsContext->createVertexBuffer(vertexFormat, vertexCount, BufferUsage::DYNAMIC_DRAW); // Create index buffer IndexFormat indexFormat = (vertexCount > 65536) ? IndexFormat::UINT32 : IndexFormat::UINT16; indexBuffer = graphicsContext->createIndexBuffer(indexFormat, indexCount, BufferUsage::STATIC_DRAW); // Calculate indices switch (indexFormat) { case IndexFormat::UINT16: { std::uint16_t indices[indexCount]; std::uint16_t* index = indices; for (std::uint16_t i = 0; i < vertexCount; i += 4) { *(index++) = i; *(index++) = i + 1; *(index++) = i + 2; *(index++) = i; *(index++) = i + 2; *(index++) = i + 3; } indexBuffer->setData(indices); break; } case IndexFormat::UINT32: { std::uint32_t indices[indexCount]; std::uint32_t* index = indices; for (std::uint32_t i = 0; i < vertexCount; ++i) { *(index++) = i; *(index++) = i + 1; *(index++) = i + 2; *(index++) = i; *(index++) = i + 2; *(index++) = i + 3; } indexBuffer->setData(indices); break; } } }