示例#1
0
void InstanceBuffer::Bind() {
	assert(m_written);
	glBindBuffer(GL_ARRAY_BUFFER, m_buffer);

	// used to pass a matrix4x4f in, however each attrib array is max size of (GLSL) vec4 so must enable 4 arrays
	const size_t sizeVec4 = (sizeof(float)*4);
	glEnableVertexAttribArray(INSTOFFS_MAT0);
	glVertexAttribPointer(INSTOFFS_MAT0, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast<const GLvoid*>(0));
	glEnableVertexAttribArray(INSTOFFS_MAT1);
	glVertexAttribPointer(INSTOFFS_MAT1, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast<const GLvoid*>(sizeVec4));
	glEnableVertexAttribArray(INSTOFFS_MAT2);
	glVertexAttribPointer(INSTOFFS_MAT2, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast<const GLvoid*>(2 * sizeVec4));
	glEnableVertexAttribArray(INSTOFFS_MAT3);
	glVertexAttribPointer(INSTOFFS_MAT3, 4, GL_FLOAT, GL_FALSE, 4 * sizeVec4, reinterpret_cast<const GLvoid*>(3 * sizeVec4));

	glVertexAttribDivisor(INSTOFFS_MAT0, 1);
	glVertexAttribDivisor(INSTOFFS_MAT1, 1);
	glVertexAttribDivisor(INSTOFFS_MAT2, 1);
	glVertexAttribDivisor(INSTOFFS_MAT3, 1);
}
示例#2
0
void VaoImplSoftware::vertexAttribDivisorImpl( GLuint index, GLuint divisor )
{
	mLayout.vertexAttribDivisor( index, divisor );
	glVertexAttribDivisor( index, divisor );

/*
#if ! defined( CINDER_GL_ES )
	glVertexAttribDivisor( index, divisor );
#endif
*/
}
示例#3
0
文件: render.c 项目: youka2/template
void use_text(const text_data *t)
{
	if(t!=NULL)
	{
		use_buf(t->v);
		glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,NULL);
		glVertexAttribDivisor(2,1); /* needed here every time? */
	}

	_active_text=(text_data*)t;
}
示例#4
0
DrawLineShader::DrawLineShader()
    : OpenGLShaderProgram("drawline")
{
    GetLocations();

    glGenBuffers(1, &_vbo);
    glGenBuffers(1, &_vboInstances);
    glGenVertexArrays(1, &_vao);

    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);

    glBindVertexArray(_vao);
    glVertexAttribPointer(vVertMat + 0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*)offsetof(VDStruct, mat[0]));
    glVertexAttribPointer(vVertMat + 1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*)offsetof(VDStruct, mat[1]));
    glVertexAttribPointer(vVertMat + 2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*)offsetof(VDStruct, mat[2]));
    glVertexAttribPointer(vVertMat + 3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*)offsetof(VDStruct, mat[3]));

    glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
    glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawLineCommand), (void*)offsetof(DrawLineCommand, clip));
    glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawLineCommand), (void*)offsetof(DrawLineCommand, bounds));
    glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawLineCommand), (void*)offsetof(DrawLineCommand, colour));
    glVertexAttribIPointer(vDepth, 1, GL_INT, sizeof(DrawLineCommand), (void*)offsetof(DrawLineCommand, depth));

    glEnableVertexAttribArray(vVertMat + 0);
    glEnableVertexAttribArray(vVertMat + 1);
    glEnableVertexAttribArray(vVertMat + 2);
    glEnableVertexAttribArray(vVertMat + 3);

    glEnableVertexAttribArray(vClip);
    glEnableVertexAttribArray(vBounds);
    glEnableVertexAttribArray(vColour);
    glEnableVertexAttribArray(vDepth);

    glVertexAttribDivisor(vClip, 1);
    glVertexAttribDivisor(vBounds, 1);
    glVertexAttribDivisor(vColour, 1);
    glVertexAttribDivisor(vDepth, 1);

    Use();
}
示例#5
0
// setting instance data
void set_instance_data(const GLuint vbo) {
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat),
            (GLvoid*)0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // inform OpenGL about instanced vertex attribute
    glVertexAttribDivisor(2, 1);

    glBindVertexArray(0);
}
示例#6
0
void MeshRenderer::AttachInstanceData(GLuint location, GLuint instanceVBO) {
    GL_CHECK( glBindVertexArray(VAO) );
    GL_CHECK( glBindBuffer(GL_ARRAY_BUFFER, instanceVBO) );
    
    for (unsigned i = 0; i < 4; ++i) {
        GL_CHECK( glEnableVertexAttribArray(location + i) );
        GL_CHECK( glVertexAttribPointer    (location + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const GLvoid*)(sizeof(glm::vec4) * i)) );
        GL_CHECK( glVertexAttribDivisor    (location + i, 1) );
    }

    GL_CHECK( glBindVertexArray(0) );
}
示例#7
0
// --------------------------------------------------------------------------------------------------------------------
bool UntexturedObjectsGLDrawLoop::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices,
                                       const std::vector<UntexturedObjectsProblem::Index>& _indices,
                                       size_t _objectCount)
{
    if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) {
        return false;
    }

    // Program
    const char* kUniformNames[] = { "ViewProjection", nullptr };

    m_prog = CreateProgramT("cubes_gl_multi_draw_vs.glsl",
                            "cubes_gl_multi_draw_fs.glsl",
                            kUniformNames, &mUniformLocation);

    if (m_prog == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    glGenVertexArrays(1, &m_varray);
    glBindVertexArray(m_varray);

    // Buffers
    glGenBuffers(1, &m_vb);
    glBindBuffer(GL_ARRAY_BUFFER, m_vb);
    glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, pos));
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, color));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    std::vector<uint32_t> drawids(_objectCount);
    for (uint32_t i = 0; i < _objectCount; ++i) {
        drawids[i] = i;
    }

    glGenBuffers(1, &m_drawid);
    glBindBuffer(GL_ARRAY_BUFFER, m_drawid);
    glBufferData(GL_ARRAY_BUFFER, drawids.size() * sizeof(uint32_t), drawids.data(), GL_STATIC_DRAW);
    glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0);
    glVertexAttribDivisor(2, 1);
    glEnableVertexAttribArray(2);

    glGenBuffers(1, &m_ib);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), GL_STATIC_DRAW);

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);

    return glGetError() == GL_NO_ERROR;
}
 void VertexFormatBinder::Deactivate()
 {
     // Clear out the vertex attribute bindings
     AttribSet::iterator attribIt = m_instanceAttributes.begin();
     AttribSet::const_iterator attribEnd = m_instanceAttributes.end();
     for (; attribIt != attribEnd; ++attribIt)
     {
         const InstanceAttribDesc& desc = attribIt->second;
         glDisableVertexAttribArray(desc.m_attribIndex);
         glVertexAttribDivisor(desc.m_attribIndex, 0);
     }
 }
示例#9
0
			void OBJMesh::OBJShape::allocateResources(GLuint instanceAttributesBuffer, const std::vector<tinyobj::material_t>& objMaterials)
			{
				assert(sizeof(TriangleMeshData::VertexAttributes) == 48);
				if ((shape.mesh.positions.size() % 3) != 0)
					throw std::runtime_error("PGA::Rendering::GL::OBJMesh::OBJShape::allocateResources(): OBJMesh doesn't support non-triangle meshes");
				auto numVertices = shape.mesh.positions.size() / 3;
				std::vector<TriangleMeshData::VertexAttributes> verticesAttributes;
				for (auto v = 0, p = 0, n = 0, t = 0; v < numVertices; v++, p += 3, n += 3, t += 2)
				{
					verticesAttributes.push_back({
						{ shape.mesh.positions[p], shape.mesh.positions[p + 1], shape.mesh.positions[p + 2], 1.0f},
						{ shape.mesh.normals[n], shape.mesh.normals[n + 1], shape.mesh.normals[n + 2] },
						{ shape.mesh.texcoords[t], shape.mesh.texcoords[t + 1] }
					});
				}
				glGenVertexArrays(1, &vao);
				glGenBuffers(1, &vertexAttributesBuffer);
				glGenBuffers(1, &indexBuffer);
				PGA_Rendering_GL_checkError();
				size_t vertexAttributesBufferSize = numVertices * sizeof(TriangleMeshData::VertexAttributes);
				size_t indexBufferSize = shape.mesh.indices.size() * sizeof(unsigned int);
				glBindVertexArray(vao);
				glBindBuffer(GL_ARRAY_BUFFER, vertexAttributesBuffer);
				glBufferData(GL_ARRAY_BUFFER, vertexAttributesBufferSize, &verticesAttributes[0], GL_STATIC_DRAW);
				glEnableVertexAttribArray(0);
				glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TriangleMeshData::VertexAttributes), (void*)0);
				size_t offset = sizeof(math::float4);
				glEnableVertexAttribArray(1);
				glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TriangleMeshData::VertexAttributes), (void*)offset);
				offset += sizeof(math::float3);
				glEnableVertexAttribArray(2);
				glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(TriangleMeshData::VertexAttributes), (void*)offset);
				glBindBuffer(GL_ARRAY_BUFFER, instanceAttributesBuffer);
				/*glEnableVertexAttribArray(3);
				glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(TriangleMeshData::VertexAttributes), (void*)0);
				glVertexAttribDivisor(3, 1);
				offset += sizeof(float);*/
				offset = 0;
				assert(sizeof(InstancedTriangleMeshData::InstanceAttributes) % sizeof(math::float4) == 0);
				auto numFloat4Chunks = sizeof(InstancedTriangleMeshData::InstanceAttributes) / sizeof(math::float4);
				for (auto i = 0u; i < numFloat4Chunks; i++)
				{
					glEnableVertexAttribArray(Constants::InstanceAttributesLocation + i);
					glVertexAttribPointer(Constants::InstanceAttributesLocation + i, 4, GL_FLOAT, GL_FALSE, sizeof(InstancedTriangleMeshData::InstanceAttributes), (void*)offset);
					glVertexAttribDivisor(Constants::InstanceAttributesLocation + i, 1);
					offset += sizeof(math::float4);
				}
				glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
				glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, &shape.mesh.indices[0], GL_STATIC_DRAW);
				glBindVertexArray(0);
				PGA_Rendering_GL_checkError();
			}
示例#10
0
void DecalEngine::Draw()
{
    UpdateBuffers();
    if( mDecals.empty() )
    {
        return;
    }
    mVAO.Bind();
    ShaderManager& ShaderMgr( ShaderManager::Get() );
    ShaderMgr.ActivateShader( "decals" );
    glActiveTexture( GL_TEXTURE0 + 3 );
    for( render::Counts_t::const_iterator i = mCounts.begin(), e = mCounts.end(); i != e; ++i )
    {
        render::CountByTexId const& Part = *i;
        GLuint CurrentAttribIndex = 0;
        glVertexAttribPointer( CurrentAttribIndex, 4, GL_FLOAT, GL_FALSE, 0, ( GLvoid* )( mTexIndex + sizeof( glm::vec4 )*Part.Start ) );
        glVertexAttribDivisor( CurrentAttribIndex, 1 );
        ++CurrentAttribIndex;
        glVertexAttribPointer( CurrentAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid* )( mPosIndex + sizeof( glm::vec2 )*Part.Start ) );
        glVertexAttribDivisor( CurrentAttribIndex, 1 );
        ++CurrentAttribIndex;
        glVertexAttribPointer( CurrentAttribIndex, 1, GL_FLOAT, GL_FALSE, 0, ( GLvoid* )( mHeadingIndex + sizeof( GLfloat )*Part.Start ) );
        glVertexAttribDivisor( CurrentAttribIndex, 1 );
        ++CurrentAttribIndex;
        glVertexAttribPointer( CurrentAttribIndex, 1, GL_FLOAT, GL_FALSE, 0, ( GLvoid* )( mAlphaIndex + sizeof( GLfloat )*Part.Start ) );
        glVertexAttribDivisor( CurrentAttribIndex, 1 );
        ++CurrentAttribIndex;
        glVertexAttribPointer( CurrentAttribIndex, 1, GL_FLOAT, GL_FALSE, 0, ( GLvoid* )( mRadiusIndex + sizeof( GLfloat )*Part.Start ) );
        glVertexAttribDivisor( CurrentAttribIndex, 1 );
        if( Part.TexId != GLuint( -1 ) )
        {
            glBindTexture( GL_TEXTURE_2D, Part.TexId );
        }
        glDrawArraysInstanced( GL_TRIANGLE_STRIP, 0, 4, Part.Count );
    }

    glActiveTexture( GL_TEXTURE0 );
    mVAO.Unbind();
}
示例#11
0
void CreateInstancedTransformMatrices(std::vector<Coordinate> coordinates)
{
	// Create VBO with matrices from coordinates
	std::vector<glm::mat4> matrices;
	matrices.resize(coordinates.size());

	for (int i = 0; i < coordinates.size(); i++)
	{
		matrices[i] = glm::translate(glm::mat4(1.0f), glm::vec3(coordinates[i].x, 0.0f, coordinates[i].y));
	}


	// Vertex buffer
	glGenBuffers(1, &MatricesBufferId);
	glBindBuffer(GL_ARRAY_BUFFER, MatricesBufferId);
	glBufferData(GL_ARRAY_BUFFER, matrices.size() * sizeof(glm::mat4), &matrices[0], GL_STATIC_DRAW);


	// Bind VBO
	int pos = glGetAttribLocation(ShaderModelProgramId, "TransformMatrix");
	int pos1 = pos + 0;
	int pos2 = pos + 1;
	int pos3 = pos + 2;
	int pos4 = pos + 3;
	glEnableVertexAttribArray(pos1);
	glEnableVertexAttribArray(pos2);
	glEnableVertexAttribArray(pos3);
	glEnableVertexAttribArray(pos4);
	glBindBuffer(GL_ARRAY_BUFFER, MatricesBufferId);
	glVertexAttribPointer(pos1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 4 * 4, (void*)(0));
	glVertexAttribPointer(pos2, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 4 * 4, (void*)(sizeof(float)* 4));
	glVertexAttribPointer(pos3, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 4 * 4, (void*)(sizeof(float)* 8));
	glVertexAttribPointer(pos4, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 4 * 4, (void*)(sizeof(float)* 12));
	glVertexAttribDivisor(pos1, 1);
	glVertexAttribDivisor(pos2, 1);
	glVertexAttribDivisor(pos3, 1);
	glVertexAttribDivisor(pos4, 1);
}
示例#12
0
// set transformation matrices as an instance vertex attribute
void bind_mat4(Model& m, const std::vector<glm::mat4>& v) {
    for (GLuint i {0}; i < m.num_meshes(); ++i) {
        glBindVertexArray(m.mesh_vao(i));

        GLuint buf;
        glGenBuffers(1, &buf);

        glBindBuffer(GL_ARRAY_BUFFER, buf);
        glBufferData(GL_ARRAY_BUFFER, size_in_bytes(v), v.data(),
                GL_STATIC_DRAW);

        const auto mat4_size = sizeof(glm::mat4);
        const auto vec4_size = sizeof(glm::vec4);

        glEnableVertexAttribArray(3);
        glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, mat4_size,
                (GLvoid*)(0));

        glEnableVertexAttribArray(4);
        glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, mat4_size,
                (GLvoid*)(vec4_size));

        glEnableVertexAttribArray(5);
        glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, mat4_size,
                (GLvoid*)(vec4_size << 1));

        glEnableVertexAttribArray(6);
        glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, mat4_size,
                (GLvoid*)(3 * vec4_size));

        glVertexAttribDivisor(3, 1);
        glVertexAttribDivisor(4, 1);
        glVertexAttribDivisor(5, 1);
        glVertexAttribDivisor(6, 1);

        glBindVertexArray(0);
    }
}
void drawModelInstanced(Model *m, GLuint texture, mat4 cameraTransform, mat4 modelTransform, struct Light* light) {
	double time = glutGet(GLUT_ELAPSED_TIME) / 1000.0;

	// Generate data.
	mat4 instanceTransforms[count * count * count];
	createInstanceTransforms(instanceTransforms, (float)time);

	glUseProgram(instancingProgram);

	// Bind textures
	glActiveTexture(GL_TEXTURE0 + 0);
	glBindTexture(GL_TEXTURE_2D, texture);

	glUniformMatrix4fv(cameraLocation, 1, GL_TRUE, cameraTransform.m);
	glUniformMatrix4fv(modelLocation, 1, GL_TRUE, modelTransform.m);

	// Set light uniform
	struct ShaderLight shaderLight = getShaderLight(light);
	setLightUniform(&shaderLight);

	// Vertex positions.
	glBindVertexArray(m->vao);
	glBindBuffer(GL_ARRAY_BUFFER, m->vb);
	glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(positionLocation);

	// Normals
	glBindBuffer(GL_ARRAY_BUFFER, m->nb);
	glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(normalLocation);

	// Texture coordinates.
	glBindBuffer(GL_ARRAY_BUFFER, m->tb);
	glVertexAttribPointer(textureLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(textureLocation);

	// Upload instance transforms
	glBindBuffer(GL_ARRAY_BUFFER, instanceTransBuffer);
	for (int i = 0; i < 4; i++) {
		glEnableVertexAttribArray(instanceLocation + i);
		glVertexAttribPointer(instanceLocation + i,       // Location
							  4, GL_FLOAT, GL_FALSE,      // vec4
							  sizeof(mat4),               // Stride
							  (void*)(sizeof(vec4) * i)); // Start offset
		glVertexAttribDivisor(instanceLocation + i, 1);
	}
	glBufferData(GL_ARRAY_BUFFER, sizeof(instanceTransforms), &instanceTransforms, GL_STATIC_DRAW);

	glDrawElementsInstanced(GL_TRIANGLES, m->numIndices, GL_UNSIGNED_INT, 0L, count * count * count);
}
示例#14
0
void InstSphereRenderer::Load(const glm::vec4 *positions, size_t num_particles, ShaderMgr &sm)
{
    m_num_particles = num_particles;

    std::string model_s = ReadFile(ModelPath, m_success);
    if (!m_success)
    {
        m_log += "[FAIL] Error reading model file\n";
        return;
    }

    Model<3> model = Model<3>::FromString(model_s);

    std::unique_ptr<ParticleShader> shader = std::make_unique<ParticleShader>();

    shader->Load(sm);

    if (!shader->Success())
    {
        m_success = false;
        m_log += "Error loading particle shader: \n    " + shader->ErrorText();
        return;
    }

    Renderer::Load(model, std::move(shader));

    glGenBuffers(1, &m_instance);

    glBindVertexArray(m_vao);

    // borrow shader
    const ParticleShader *shader_ = static_cast<ParticleShader*>(m_shader.get());

    glBindBuffer(GL_ARRAY_BUFFER, m_instance);
    glBufferData(GL_ARRAY_BUFFER, m_num_particles * sizeof(glm::vec4), positions, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(shader_->PositionLoc());
    glVertexAttribPointer(shader_->PositionLoc(), 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void*)0);
    glVertexAttribDivisor(shader_->PositionLoc(), 1);

    glEnableVertexAttribArray(shader_->NormalLoc());
    glBindBuffer(GL_ARRAY_BUFFER, m_normals);
    glVertexAttribPointer(shader_->NormalLoc(), 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);

    glEnableVertexAttribArray(shader_->ModelPosLoc());
    glBindBuffer(GL_ARRAY_BUFFER, m_vertices);
    glVertexAttribPointer(shader_->ModelPosLoc(), 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void*)0);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
示例#15
0
  void SpriteMesh::CreateSprite (Shader* shader)
  {
    m_vao = new VAO ();
    ShapeData data = ShapeGenerator::Generate_Quad ();
    Load (&data, shader);

    m_vao->Bind ();
    m_matrixVbo = new VBO ();

    GLuint location = shader->attribLocation ("modelMatrix");
    GLint components = 4;
    GLenum type = GL_FLOAT;
    GLboolean normalized = GL_FALSE;
    GLsizei datasize = sizeof(Matrix4x4);
    char* pointer = 0;
    GLuint divisor = 1;

    /**
    Matrix:
    float mat[16] =
    {
    1, 0, 0, 0, //first column:  location at 0 + 0 * sizeof( vec4 ) bytes into the matrix
    0, 1, 0, 0, //second column: location at 0 + 1 * sizeof( vec4 ) bytes into the matrix
    0, 0, 1, 0, //third column:  location at 0 + 2 * sizeof( vec4 ) bytes into the matrix
    0, 0, 0, 1  //fourth column  location at 0 + 3 * sizeof( vec4 ) bytes into the matrix
    };
    /**/

    for (int c = 0; c < 4; ++c)
    {
      shader->enableVertexAttribArray (location + c);
      shader->vertexAttribPtr (location + c, components, datasize, c * sizeof (glm::vec4));
      //glEnableVertexAttribArray (location + c); //location of each column
      //glVertexAttribPointer (location + c, components, type, normalized, datasize, pointer + c * sizeof(glm::vec4)); //tell other data
      glVertexAttribDivisor (location + c, divisor); //is it instanced?
    }

    m_texVbo = new VBO ();
    location = shader->attribLocation ("texcoord");
    shader->enableVertexAttribArray (location);
    shader->vertexAttribPtr (location, 2, 2 * sizeof (GLfloat), 0);

    m_colVbo = new VBO ();
    location = shader->attribLocation ("color");
    shader->enableVertexAttribArray (location);
    shader->vertexAttribPtr (location, 4, 4 * sizeof (GLfloat), 0);

    shader->uniMat4 ("mvp", glm::value_ptr (Matrix4x4 (1)));
    shader->uni4f ("overrideColor", 1.0f, 1.0f, 1.0f, 1.0f);
  }
示例#16
0
void histogram_impl::bindResources(const int pWindowId)
{
    if (mVAOMap.find(pWindowId) == mVAOMap.end()) {
        CheckGL("Begin histogram_impl::bindResources");
        GLuint vao = 0;
        /* create a vertex array object
         * with appropriate bindings */
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
        // attach histogram bar vertices
        glEnableVertexAttribArray(mPointIndex);
        glBindBuffer(GL_ARRAY_BUFFER, screenQuadVBO(pWindowId));
        glVertexAttribPointer(mPointIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
        // attach histogram frequencies
        glEnableVertexAttribArray(mFreqIndex);
        glBindBuffer(GL_ARRAY_BUFFER, mVBO);
        glVertexAttribPointer(mFreqIndex, 1, mGLType, GL_FALSE, 0, 0);
        glVertexAttribDivisor(mFreqIndex, 1);
        // attach histogram bar colors
        glEnableVertexAttribArray(mColorIndex);
        glBindBuffer(GL_ARRAY_BUFFER, mCBO);
        glVertexAttribPointer(mColorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glVertexAttribDivisor(mColorIndex, 1);
        // attach histogram bar alphas
        glEnableVertexAttribArray(mAlphaIndex);
        glBindBuffer(GL_ARRAY_BUFFER, mABO);
        glVertexAttribPointer(mAlphaIndex, 1, GL_FLOAT, GL_FALSE, 0, 0);
        glVertexAttribDivisor(mAlphaIndex, 1);
        glBindVertexArray(0);
        /* store the vertex array object corresponding to
         * the window instance in the map */
        mVAOMap[pWindowId] = vao;
        CheckGL("End histogram_impl::bindResources");
    }

    glBindVertexArray(mVAOMap[pWindowId]);
}
示例#17
0
void draw_grid(mat4 transform)
{
    glUseProgram(grid_program.handle);

    glEnableVertexAttribArray(grid_vertex_attrib);
    glBindBuffer(GL_ARRAY_BUFFER, grid_buffer);
    glVertexAttribPointer(grid_vertex_attrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    checkGLError();

    glEnableVertexAttribArray(grid_position_attrib);
    glBindBuffer(GL_ARRAY_BUFFER, grid_position_buffer);
    glVertexAttribPointer(grid_position_attrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glEnableVertexAttribArray(grid_horizontal_attrib);
    glBindBuffer(GL_ARRAY_BUFFER, grid_horiz_buffer);
    glVertexAttribIPointer(grid_horizontal_attrib, 1, GL_UNSIGNED_INT, 0, (void*)0);

    bind_texture_to_program(grid_program, "texture", grid_dash_texture, GL_TEXTURE0);

    mat4 tt = ident;
    mat4_translate(&tt, 0, 0, -10);
    mat4 camera = get_camera();
    glUniformMatrix4fv(grid_transform_uniform, 1, GL_FALSE, camera.data);

    glVertexAttribDivisor(grid_vertex_attrib, 0);
    glVertexAttribDivisor(grid_position_attrib, 1);
    glVertexAttribDivisor(grid_horizontal_attrib, 1);
    checkGLError();

    glDrawArraysInstanced(GL_LINES, 0, 2, TILEMAP_DIMS * 2);

    glDisableVertexAttribArray(grid_vertex_attrib);
    glVertexAttribDivisor(grid_position_attrib, 0);
    glVertexAttribDivisor(grid_horizontal_attrib, 0);

}
示例#18
0
void ParticleSystemProxy::drawNotFlip()
{
	glDepthMask(GL_FALSE);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);

	if (m_alpha_additive)
		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
	else
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glUseProgram(SimpleParticleRender::Program);
	glEnableVertexAttribArray(SimpleParticleRender::attrib_pos);
	glEnableVertexAttribArray(SimpleParticleRender::attrib_lf);
	glEnableVertexAttribArray(SimpleParticleRender::attrib_quadcorner);
	glEnableVertexAttribArray(SimpleParticleRender::attrib_texcoord);
	glEnableVertexAttribArray(SimpleParticleRender::attrib_sz);

	float screen[2] = {
		(float)UserConfigParams::m_width,
		(float)UserConfigParams::m_height
	};

	bindUniformToTextureUnit(SimpleParticleRender::uniform_texture, texture, 0);
	bindUniformToTextureUnit(SimpleParticleRender::uniform_normal_and_depths, normal_and_depth, 1);

	glUniformMatrix4fv(SimpleParticleRender::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer());
	glUniform2f(SimpleParticleRender::uniform_screen, screen[0], screen[1]);
	glUniformMatrix4fv(SimpleParticleRender::uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer());
	glUniformMatrix4fv(SimpleParticleRender::uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer());

	glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
	glVertexAttribPointer(SimpleParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
	glVertexAttribPointer(SimpleParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
	glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]);
	glVertexAttribPointer(SimpleParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
	glVertexAttribPointer(SimpleParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
	glVertexAttribPointer(SimpleParticleRender::attrib_sz, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float)));

	glVertexAttribDivisor(SimpleParticleRender::attrib_lf, 1);
	glVertexAttribDivisor(SimpleParticleRender::attrib_pos, 1);
	glVertexAttribDivisor(SimpleParticleRender::attrib_sz, 1);

	glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
	glVertexAttribDivisor(SimpleParticleRender::attrib_lf, 0);
	glVertexAttribDivisor(SimpleParticleRender::attrib_pos, 0);
	glVertexAttribDivisor(SimpleParticleRender::attrib_sz, 0);
	glDisableVertexAttribArray(SimpleParticleRender::attrib_pos);
	glDisableVertexAttribArray(SimpleParticleRender::attrib_lf);
	glDisableVertexAttribArray(SimpleParticleRender::attrib_quadcorner);
	glDisableVertexAttribArray(SimpleParticleRender::attrib_texcoord);
	glDisableVertexAttribArray(SimpleParticleRender::attrib_sz);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glActiveTexture(GL_TEXTURE0);
	glDisable(GL_BLEND);

}
示例#19
0
		void VertexArray::PushBuffer(VertexBuffer* buffer)
		{
			m_Buffers.push_back(buffer);

			const std::vector<BufferLayoutElement>& layout = buffer->GetLayout().GetElements();
			for (uint i = 0; i < layout.size(); i++, m_AttribCount++)
			{
				glEnableVertexAttribArray(m_AttribCount);
				glVertexAttribPointer(m_AttribCount, layout[i].Count, layout[i].Type, (uint)layout[i].Normalized, buffer->GetLayout().GetStride(), (const GLvoid*)layout[i].Offset);
				if (layout[i].PerInstance)
				{
					glVertexAttribDivisor(m_AttribCount, 1);
				}
			}
		}
PIGLIT_GL_TEST_CONFIG_END

void
piglit_init(int argc, char **argv)
{
	bool pass = true;

	if(piglit_get_gl_version() < 33)
		piglit_require_extension("GL_ARB_instanced_arrays");

	glVertexAttribDivisor(GL_MAX_VERTEX_ATTRIBS, 0);
	pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
示例#21
0
	void VertexArrayObject::InstancesAttribPointer(GLuint index,GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer, GLuint divisor) {
		if(!glIsVertexArray(this->ID)) {
			throw Exception(DSGL_VAO_DOESNT_EXIST, "DSGL: VAO doesn't exist.");			
		}
		glBindVertexArray(this->ID); {
			glBindBuffer(GL_ARRAY_BUFFER, this->instances);
			if(!glIsBuffer(this->instances)) {
				throw Exception(DSGL_INSTANCES_DOESNT_EXIST, "DSGL: instances buffer doesn't exist.");
			}
			glEnableVertexAttribArray(index);
			glVertexAttribPointer(index, size, type, normalized, stride, pointer);
			glVertexAttribDivisor(index, divisor);
		}
		glBindVertexArray(0);
	}
示例#22
0
void Quads::setupTransformFormat(GLuint location) const
{
    glBindBuffer(GL_ARRAY_BUFFER, transformBuf);
    for(unsigned i = 0; i < 4; i++) {
        glVertexAttribPointer(
            location + i,
            4,
            GL_FLOAT,
            GL_FALSE,
            sizeof(Quads::MatrixType),
            (GLvoid*) (i * sizeof(glm::vec4))
        );
        glEnableVertexAttribArray(location + i);
        glVertexAttribDivisor(location + i, 1);
    }
}
示例#23
0
void initGeometry()
{
  // sphere for instancing

  float radius = 0.0025f;
  std::vector<float> Vertices;
  std::vector<float> Normals;  
  std::vector<unsigned int> Indices;
  
  Vertices.clear();
  Normals.clear();
  Indices.clear();
  createSphere(radius, Vertices, Indices, Normals);
  
  glGenVertexArrays(1, &vaoSphere);
  glBindVertexArray(vaoSphere);

  glGenBuffers(1, &vboSphereVertex);
  glBindBuffer(GL_ARRAY_BUFFER, vboSphereVertex);
  glBufferData(GL_ARRAY_BUFFER, sizeof(float)*Vertices.size(), Vertices.data(), 
	       GL_STATIC_DRAW);
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);

  glGenBuffers(1, &vboSphereNormal);
  glBindBuffer(GL_ARRAY_BUFFER, vboSphereNormal);
  glBufferData(GL_ARRAY_BUFFER, sizeof(float)*Normals.size(), Normals.data(), 
	       GL_STATIC_DRAW);
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);

  glGenBuffers(1, &vboSphereIndex);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboSphereIndex);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*Indices.size(), 
	       Indices.data(), GL_STATIC_DRAW);

  numIndicesSphere = Indices.size();

  glGenBuffers(1, &vboPositions);
  glBindBuffer(GL_ARRAY_BUFFER, vboPositions);

  glEnableVertexAttribArray(2);
  glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, (GLubyte*)NULL);
  glVertexAttribDivisor(2, 1);

  glBindVertexArray(0);
}
void OpenGLVertexDeclaration::CreateVertexArrayOGL( const RenderOperation& operation, const Shader& vertexShader )
{
	glGenVertexArrays(1, &mVertexArrayOGL);
	glBindVertexArray(mVertexArrayOGL);

	OpenGLVertexDeclaration* vertexDeclOGL = static_cast_checked<OpenGLVertexDeclaration*>(operation.VertexDecl.get());

	GLuint vertexSlotBind = -1;
	for (GLuint attribIndex = 0; attribIndex < vertexDeclOGL->mVertexElemets.size(); ++attribIndex)
	{
		const VertexElement& attribute = vertexDeclOGL->mVertexElemets[attribIndex];

		// Bind vertex stream to slot
		if (attribute.InputSlot != vertexSlotBind)
		{
			OpenGLBuffer* bufferOGL = static_cast_checked<OpenGLBuffer*>(operation.VertexStreams[attribute.InputSlot].get());
			glBindBuffer(GL_ARRAY_BUFFER, bufferOGL->GetBufferOGL());

			vertexSlotBind = attribute.InputSlot;
		}

		GLenum type = OpenGLMapping::Mapping(attribute.Type);
		uint32_t size = VertexElementUtil::GetElementComponentCount(attribute);
		uint32_t stride =  vertexDeclOGL->GetStreamStride(attribute.InputSlot);
		uint32_t offset = attribute.Offset;
			
		bool isMatchVertexShader = true;
		
		if (isMatchVertexShader)
		{
			glEnableVertexAttribArray(attribIndex);

			if (OpenGLMapping::IsIntegerType(type))
				glVertexAttribIPointer(attribIndex, size, type, stride, BUFFER_OFFSET(offset));	
			else
				glVertexAttribPointer(attribIndex, size, type, false, stride, BUFFER_OFFSET(offset));	

			if (attribute.InstanceStepRate > 0)
				glVertexAttribDivisor(attribIndex, attribute.InstanceStepRate);
		}
		else 
			glDisableVertexAttribArray(attribIndex);
	}

	glBindVertexArray(0);
}
示例#25
0
文件: Grid.cpp 项目: filu005/SPH
void Grid::setup_buffers(void)
{
	int index = 0;

	for(float z = c::zmin; z < c::zmax; z += c::dz)
		for(float y = c::ymin; y < c::ymax; y += c::dy)
			for(float x = c::xmin; x < c::xmax; x += c::dx)
				translations[index++] = glm::vec3(x, y, z);// post-increment

	// Create buffers/arrays
	glGenVertexArrays(1, &this->VAO);

	glBindVertexArray(this->VAO);

	// Store instance data in an array buffer
	glGenBuffers(1, &this->instance_VBO);
	glBindBuffer(GL_ARRAY_BUFFER, this->instance_VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * c::C, &this->translations[0], GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glGenBuffers(1, &this->VBO);
	glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(this->cube_vertices), &this->cube_vertices[0], GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glGenBuffers(1, &this->EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(this->cube_indices), &this->cube_indices[0], GL_STATIC_DRAW);
	//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);// - no no no!

	// Set the vertex attribute pointers
	// Vertex Positions
	glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*) 0);

	// Also set instance data
	glBindBuffer(GL_ARRAY_BUFFER, this->instance_VBO);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*) 0);
	glVertexAttribDivisor(1, 1); // Tell OpenGL this is an instanced vertex attribute.

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
}
示例#26
0
void SmokeSource::configureTextureAttribute()
{
  GLuint error;

  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer);

  // enable texture data as attribute 2
  // (index, size, type, normalized, stride, pointer)
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
  if ((error = glGetError()) != GL_NO_ERROR)
    std::cerr << "init buffer error, attrib pointer: " << error << std::endl;

  // set attribute divisor
  glVertexAttribDivisor(1, 0);
  if ((error = glGetError()) != GL_NO_ERROR)
    std::cerr << "init buffer error, attribute divisor: " << error << std::endl;
}
示例#27
0
	void Asteroid::init_buffer()
	{
		object.load("../../../media/objects/asteroids.sbm");

		//We load the command use vertex buffer 
		glGenBuffers(1, &indirect_vbo);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirect_vbo);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, NUM_DRAWS * sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW);

		//We map the data the buffer
		DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER,
			0, NUM_DRAWS * sizeof(DrawArraysIndirectCommand),
			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

		for (int i = 0; i < NUM_DRAWS; i++)
		{
			object.get_sub_object_info(i % object.get_sub_object_count(),
				cmd[i].first,
				cmd[i].count);
			    cmd[i].primCount = 1;
			    cmd[i].baseInstance = i;
		}

		glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);

		glBindVertexArray(object.get_vao());
		glGenBuffers(1, &draw_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, draw_vbo);
		glBufferData(GL_ARRAY_BUFFER, NUM_DRAWS * sizeof(GLuint), NULL, GL_STATIC_DRAW);

		GLuint * draw_index = (GLuint *)glMapBufferRange(GL_ARRAY_BUFFER,
			0, NUM_DRAWS * sizeof(GLuint),
			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
		for (int i = 0; i < NUM_DRAWS; i++)
		{
			draw_index[i] = i;
		}
		glUnmapBuffer(GL_ARRAY_BUFFER);

		glVertexAttribIPointer(10, 1, GL_UNSIGNED_INT, 0, NULL);
		glVertexAttribDivisor(10, 1);
		glEnableVertexAttribArray(10);

	}
示例#28
0
void SmokeSource::configurePositionAttribute(GLfloat* position_data)
{
  GLuint error;

  glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
  glBufferSubData(GL_ARRAY_BUFFER, 0, particles * 3 * sizeof(GLfloat), position_data);

  // enable position data as attribute 3
  // (index, size, type, normalized, stride, pointer)
  glEnableVertexAttribArray(2);
  glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
  if ((error = glGetError()) != GL_NO_ERROR)
    std::cerr << "init buffer error, attrib pointer: " << error << std::endl;

  // set attribute divisor
  glVertexAttribDivisor(2, 1);
  if ((error = glGetError()) != GL_NO_ERROR)
    std::cerr << "init buffer error, attribute divisor: " << error << std::endl;
}
示例#29
0
static void SetAttributeFormat( const VertexAttribute* pAttr, unsigned int numAttr, unsigned int v_offset)
{
	GLenum type = GL_FLOAT;		
	unsigned int currentVBO = GetCurrentBuffer(GL_ARRAY_BUFFER_BINDING);
	unsigned int i;

	TransferAndDraw();

	if(vtx.n_vertices != 0){
		printf("ermergerd");
	}

	BindVAO();

	for(i=0;i<10;i++)glDisableVertexAttribArray(i);

	for(i=0; i<numAttr; i++)
	{
		if(pAttr[i].vbo != 0)
			BindBuffer(GL_ARRAY_BUFFER, pAttr[i].vbo);

		glEnableVertexAttribArray(pAttr[i].idx);
		glVertexAttribDivisor(pAttr[i].idx, pAttr[i].divisor);
		
		switch(pAttr[i].type)
		{
		default:
		case STREAM_FLOAT:			
		case STREAM_UCHAR:
			glVertexAttribPointer(pAttr[i].idx, pAttr[i].size, enumToGLAttribType[ pAttr[i].type ], pAttr[i].normalized, pAttr[i].stride, BUFFER_OFFSET(v_offset + pAttr[i].offset));
			break;		
		case STREAM_CHAR:		
		case STREAM_SHORT:
		case STREAM_INT:
			glVertexAttribIPointer(pAttr[i].idx, pAttr[i].size, enumToGLAttribType[ pAttr[i].type ], pAttr[i].stride, BUFFER_OFFSET(v_offset + pAttr[i].offset));
			break;
		}
		if(pAttr[i].vbo != 0)
			BindBuffer(GL_ARRAY_BUFFER, currentVBO);
	}
	UnbindVAO();
}
void InstanceWrapper::setup()
{
    shaderProgram = loadShaderProgram("assets/shaders/instanced.vert", "assets/shaders/instanced.frag", { "in_sPos", "in_pos" });

    float posVertices[]{
        -0.25f, -0.25f, 0.f,
        0.25f, -0.25f, 0.f,
        -0.25f, 0.25f, 0.f,
        0.25f, 0.25f, 0.f
    };

    constexpr size_t vertexSize = sizeof(float) * 3;
    constexpr uint8_t vertexCount = 4;
    mesh.renderMode = GL_TRIANGLE_STRIP;

    glGenVertexArrays(1, &mesh.vao);
    glBindVertexArray(mesh.vao);

    // Instanced
    constexpr size_t instanceSize = sizeof(float) * 3;
    glGenBuffers(1, &mesh.instanceVBO);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.instanceVBO);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, instanceSize, 0);
    glVertexAttribDivisor(0, 1);

    // Normal
    glGenBuffers(1, &mesh.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);
    glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, &posVertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertexSize, 0);

    mesh.vertexCount = vertexCount;

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    GL_ERROR_CHECK();
}