src/3D/InstancedRenderer.cpp
// create VAO for the Gouraud shader
create VAO for the Gouraud shader
create VAO for the Gouraud shader
gl::VertexArray createGouraudVAO(
            MeshData const& mesh,
            gl::ArrayBuffer<GLubyte>& data,
            gl::ElementArrayBuffer<uint32_t>& ebo,
            gl::ArrayBuffer<GPUMeshInstance, GL_DYNAMIC_DRAW>& instances) {
        static_assert(offsetof(GPUUntexturedMeshdata, pos) == offsetof(GPUTexturedMeshdata, pos));
        static_assert(offsetof(GPUUntexturedMeshdata, norm) == offsetof(GPUTexturedMeshdata, norm));
        static constexpr size_t offsetPos = offsetof(GPUUntexturedMeshdata, pos);
        static constexpr size_t offsetNorm = offsetof(GPUUntexturedMeshdata, norm);
        using GMS = GouraudMrtShader;
        size_t stride = mesh.texcoords.empty() ? sizeof(GPUUntexturedMeshdata) : sizeof(GPUTexturedMeshdata);
        gl::VertexArray vao;
        gl::BindVertexArray(vao);
        gl::BindBuffer(data);
        gl::VertexAttribPointer(GMS::aPos, false, stride, offsetPos);
        gl::EnableVertexAttribArray(GMS::aPos);
        gl::VertexAttribPointer(GMS::aNormal, false, stride, offsetNorm);
        gl::EnableVertexAttribArray(GMS::aNormal);
        if (!mesh.texcoords.empty()) {
            gl::VertexAttribPointer(GMS::aTexCoord, false, stride, offsetof(GPUTexturedMeshdata, uv));
            gl::EnableVertexAttribArray(GMS::aTexCoord);
        }
        gl::BindBuffer(ebo);
        gl::BindBuffer(instances);
        gl::VertexAttribPointer(GMS::aModelMat, false, sizeof(GPUMeshInstance), offsetof(GPUMeshInstance, modelMtx));
        gl::VertexAttribDivisor(GMS::aModelMat, 1);
        gl::EnableVertexAttribArray(GMS::aModelMat);
        gl::VertexAttribPointer(GMS::aNormalMat, false, sizeof(GPUMeshInstance), offsetof(GPUMeshInstance, normalMtx));
        gl::VertexAttribDivisor(GMS::aNormalMat, 1);
        gl::EnableVertexAttribArray(GMS::aNormalMat);
        gl::VertexAttribPointer<gl::glsl::vec4, GL_UNSIGNED_BYTE>(GMS::aDiffuseColor, true, sizeof(GPUMeshInstance), offsetof(GPUMeshInstance, rgba));
        gl::VertexAttribDivisor(GMS::aDiffuseColor, 1);
        gl::EnableVertexAttribArray(GMS::aDiffuseColor);
        gl::VertexAttribPointer<gl::glsl::float_, GL_UNSIGNED_BYTE>(GMS::aRimIntensity, true, sizeof(GPUMeshInstance), offsetof(GPUMeshInstance, rimIntensity));
        gl::VertexAttribDivisor(GMS::aRimIntensity, 1);
        gl::EnableVertexAttribArray(GMS::aRimIntensity);
        gl::BindVertexArray();
        return vao;
    }
gl :: VertexArray createGouraudVAO ( MeshData const & mesh , gl :: ArrayBuffer < GLubyte > & data , gl :: ElementArrayBuffer < uint32_t > & ebo , gl :: ArrayBuffer < GPUMeshInstance , GL_DYNAMIC_DRAW > & instances ) { static_assert ( offsetof ( GPUUntexturedMeshdata , pos ) == offsetof ( GPUTexturedMeshdata , pos ) ) ; static_assert ( offsetof ( GPUUntexturedMeshdata , norm ) == offsetof ( GPUTexturedMeshdata , norm ) ) ; static constexpr size_t offsetPos = offsetof ( GPUUntexturedMeshdata , pos ) ; static constexpr size_t offsetNorm = offsetof ( GPUUntexturedMeshdata , norm ) ; using GMS = GouraudMrtShader ; size_t stride = mesh . texcoords . empty ( ) ? sizeof ( GPUUntexturedMeshdata ) : sizeof ( GPUTexturedMeshdata ) ; gl :: VertexArray vao ; gl :: BindVertexArray ( vao ) ; gl :: BindBuffer ( data ) ; gl :: VertexAttribPointer ( GMS :: aPos , false , stride , offsetPos ) ; gl :: EnableVertexAttribArray ( GMS :: aPos ) ; gl :: VertexAttribPointer ( GMS :: aNormal , false , stride , offsetNorm ) ; gl :: EnableVertexAttribArray ( GMS :: aNormal ) ; if ( ! mesh . texcoords . empty ( ) ) { gl :: VertexAttribPointer ( GMS :: aTexCoord , false , stride , offsetof ( GPUTexturedMeshdata , uv ) ) ; gl :: EnableVertexAttribArray ( GMS :: aTexCoord ) ; } gl :: BindBuffer ( ebo ) ; gl :: BindBuffer ( instances ) ; gl :: VertexAttribPointer ( GMS :: aModelMat , false , sizeof ( GPUMeshInstance ) , offsetof ( GPUMeshInstance , modelMtx ) ) ; gl :: VertexAttribDivisor ( GMS :: aModelMat , 1 ) ; gl :: EnableVertexAttribArray ( GMS :: aModelMat ) ; gl :: VertexAttribPointer ( GMS :: aNormalMat , false , sizeof ( GPUMeshInstance ) , offsetof ( GPUMeshInstance , normalMtx ) ) ; gl :: VertexAttribDivisor ( GMS :: aNormalMat , 1 ) ; gl :: EnableVertexAttribArray ( GMS :: aNormalMat ) ; gl :: VertexAttribPointer < gl :: glsl :: vec4 , GL_UNSIGNED_BYTE > ( GMS :: aDiffuseColor , true , sizeof ( GPUMeshInstance ) , offsetof ( GPUMeshInstance , rgba ) ) ; gl :: VertexAttribDivisor ( GMS :: aDiffuseColor , 1 ) ; gl :: EnableVertexAttribArray ( GMS :: aDiffuseColor ) ; gl :: VertexAttribPointer < gl :: glsl :: float_ , GL_UNSIGNED_BYTE > ( GMS :: aRimIntensity , true , sizeof ( GPUMeshInstance ) , offsetof ( GPUMeshInstance , rimIntensity ) ) ; gl :: VertexAttribDivisor ( GMS :: aRimIntensity , 1 ) ; gl :: EnableVertexAttribArray ( GMS :: aRimIntensity ) ; gl :: BindVertexArray ( ) ; return vao ; }
create VAO for the Gouraud shader
create VAO for the Gouraud shader
// bind vertex data to (non-instanced) attrs // bind EBO // bind instance data // note: RGB is normalized CPU side ([0x00, 0xff]) and needs to be unpacked // into a float // note: RimIntensity is normalized from its CPU byte value into a float