OpenGL RAII рд╢реИрд▓реА рдХреА рдкреНрд░рдзрд╛рдирддрд╛

рд╢реБрдн рджреЛрдкрд╣рд░, рд╣рд╛рдмрд░рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВред рдореИрдВрдиреЗ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рдФрд░ рд╢рд╛рдпрдж рдХреЛрдИ рдореБрдЭрд╕реЗ рд▓реЗрдЦ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рдерд╛ - рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВред рдЪреВрдБрдХрд┐ рдореЗрд░рд╛ рдЦрд╛рд▓реА рд╕рдордп рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╣реЛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдореЗрд░рд╛ рдЧрд┐рдЯрд╣рдм рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЦрд╛рд▓реА рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдореИрдВрдиреЗ рдЕрдкрдирд╛ рдХреНрд▓реЛрди Mein kampf Minecraft рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ ред рдЙрдЪреНрдЪ рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде, рдореИрдВ рдЗрд╕реЗ рдкреНрд░рд▓реЗрдЦрд┐рдд рдХрд░реВрдВрдЧрд╛ - habr.com рдкрд░ рдореЗрд░реЗ рд▓реЗрдЦреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ ред рдЖрдЬ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рдореИрдВрдиреЗ RAGL рд╢реИрд▓реА рдореЗрдВ рдУрдкрдирдЬреАрдПрд▓ рдЖрджрд┐рдо рдХреЛ рд▓рдкреЗрдЯрд╛, рдЕрдЧрд░ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ - рдмрд┐рд▓реНрд▓реА рдХреЗ рдиреАрдЪреЗред

рдЙрди рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗрдВ рдЬрд┐рдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рдкрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдХреНрдпрд╛ рдореБрдЭреЗ рд╕реНрдХреНрд░реИрдЪ рд▓реЗрдЦреЛрдВ рд╕реЗ Minecraft рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП? рдЕрдм рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдмрдлрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ ред рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рд╣рдо рдХрд░реЗрдВрдЧреЗ, рд╡рд╣ рдореБрдЦреНрдп рдХреЙрд▓ ( glGenBuffers , glDeleteBuffers ) рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдореЗрдВ рдХрд░рдирд╛ рд╣реИред

рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

class buffer_object
{
public:
    buffer_object() noexcept {
        glGenBuffers(1, m_object);
    }
    
    ~buffer_object() noexcept {
        glDeleteBuffers(1, m_object);
    }
    
    uint32_t get_object() const noexcept {
        return m_object;
    }
private:
    uint32_t m_object;
};

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  • рдмрдлрд░ рд╣рдЯрд╛рдиреЗ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
  • OpenGL рд╣реЗрдбрд░ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рд╕реЗ рдЪрд┐рдкрдХреЗ рдирд╣реАрдВ рд░рд╣рддреЗ рд╣реИрдВ (рдпрджрд┐ рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ * .cpp рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ)ред

minuses:

  • рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХрд░рддреЗ рд╕рдордп рд╣рдо рдмрдлрд░ (рд╕рд░рдгреА, рддрддреНрд╡ ...) рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ
  • GlGenBuffers рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдХрдИ рдмрдлрд╝рд░реНрд╕ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ
  • рдпрджрд┐ рдмрдлрд░ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдИ рдЧрдИ рдереА, рддреЛ рджреВрд░рд╕реНрде рдСрдмреНрдЬреЗрдХреНрдЯ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ

рдирдХрд▓ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд╕ рдЗрд╕реЗ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ noncopyable рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рд▓реЗрдВред

рдЧреИрд░-рд╢реНрд░реЗрдгреАрдмрджреНрдз рдЙрджрд╛рд╣рд░рдг:

struct noncopyable
{
    noncopyable() = default;
            
    noncopyable(noncopyable&&) = default;
    noncopyable& operator = (noncopyable&&) = default;
            
    noncopyable(const noncopyable&) = delete;
    noncopyable& operator = (const noncopyable&) = delete;
};

рдорд╣рд╛рди, рд╢реВрдиреНрдп рд╕реЗ рдПрдХ рд╕рдорд╕реНрдпрд╛ред рд╣рдо рдЖрдЧреЗ рд╕реЛрдЪрддреЗ рд╣реИрдВ, рд╣рдо рдмрдВрдзрди рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд░реЗрдВрдЧреЗ ... рдмрд╛рдЗрдВрдб / рдЕрдирдмрдВрдб рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВ:

void bind(buffer_type type) noexcept {
    glBindBuffer(static_cast<GLenum>(type), m_object);
}
    
void unbind() noexcept {
    glBindBuffer(static_cast<GLenum>(type), 0);
}

рдмрдлрд░_рдЯрд╛рдЗрдк рдПрдХ рдПрдирдо рдХреНрд▓рд╛рд╕ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдПрдХреНрд╕рдЯрд░реНрдирд▓ рдХрд╛рдВрд╕реНрдЯ (* .hpp) рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ (* .cpp) рдХреБрдЫ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

const uint32_t array_buffer = GL_ARRAY_BUFFER;

рдлрд┐рд░, рдпрд╣ рдмрд╛рд╣рд░ рд░рд╣рдирд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛

#include <GL/glew.h>

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  • рдмрдлрд░ рд╣рдЯрд╛рдиреЗ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
  • OpenGL рд╣реЗрдбрд░ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рд╕реЗ рдЪрд┐рдкрдХреЗ рдирд╣реАрдВ рд░рд╣рддреЗ рд╣реИрдВ (рдпрджрд┐ рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ * .cpp рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ)ред
  • рдмрдВрдзрди рдХрд░рддреЗ рд╕рдордп рд╣рдо рдмрдлрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ (рд╕рд░рдгреА, рддрддреНрд╡ ...) рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
  • рдХреЛрдИ рдирдХрд▓ рдирд╣реАрдВ - рдХреЛрдИ рдирдХрд▓ рдХреА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ

minuses:

  • GlGenBuffers рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдХрдИ рдмрдлрд╝рд░реНрд╕ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ

рддреЛ, рд▓рдЧрднрдЧ рд╕рдм рдХреБрдЫ рд╕реБрдкрд░ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рднреА рдХрдИ рдмрдлрд╝рд░реНрд╕ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ ... рдЪрд▓реЛ рдЗрд╕реЗ рдареАрдХ рдХрд░реЗрдВред

glGenBuffers рдПрдХ рд╕рд░рдгреА рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЬреЗрдирд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдлрд╝рд░реНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ред
рд╣рдореЗрдВ рдПрдХ рд╕рд░рдгреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╣рдо std :: рд╡реЗрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдпрд╣рд╛рдВ std :: array рдХреЛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╣рдореЗрдВ рдЗрд╕рдХреА рд╡рдЬрд╣ рд╕реЗ рдПрдмреНрд╕реНрдЯреНрд░реИрдХреНрд╢рди рдХрд╛ рдПрдХ рдФрд░ рд╕реНрддрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рд╣рдо рдЕрдкрдиреА рдХрдХреНрд╖рд╛ рдХреЛ std :: array рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рдереЛрдбрд╝рд╛ рд╕рд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:

constexpr uint8_t default_object_count = 1;
constexpr size_t  default_index        = 0;

template <type::buffer_type type, uint32_t count = default_object_count>
class buffer_object : noncopyable
{
public:
    buffer_object() noexcept {
        glGenBuffers(count, m_object.data());
    }
    
    ~buffer_object() noexcept {
        glDeleteBuffers(count, m_object.data());
    }
    
    template <size_t index = default_index>
    void bind() noexcept
    {
        static_assert(index < count, "index larger than array size");
        glBindBuffer(static_cast<GLenum>(type), m_object[index]);
    }
    
    void unbind() noexcept {
        glBindBuffer(static_cast<GLenum>(type), 0);
    }
    
    buffer_object(buffer_object&&) = default;
    buffer_object& operator = (buffer_object&&) = default;
    
private:
    std::array<uint32_t, count> m_object;
};

рдФрд░ рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдорд┐рд▓рд╛ рд╣реИред

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  • рдмрдлрд░ рд╣рдЯрд╛рдиреЗ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
  • рдмрдВрдзрди рдХрд░рддреЗ рд╕рдордп рд╣рдо рдмрдлрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ (рд╕рд░рдгреА, рддрддреНрд╡ ...) рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
  • рдХреЛрдИ рдирдХрд▓ рдирд╣реАрдВ - рдХреЛрдИ рдирдХрд▓ рдХреА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ
  • рд╣рдо glGenBuffers рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдХрдИ рдмрдлрд╝рд░реНрд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ

minuses:

  • рдПрдХ рд╣реА рд╡рд╕реНрддреБ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рдмрдлрд╝рд░реНрд╕ рдмрд╛рдБрдз рдирд╣реАрдВ рд╕рдХрддреЗ
  • OpenGL рд╣реИрдбрд░ рд╕реНрдЯрд┐рдХ рдЖрдЙрдЯ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛

рдЕрдЪреНрдЫрд╛ ... рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╡рд┐рдкрдХреНрд╖, рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?

рдЖрдк GL / glew.h рдХреЗ рд╢рд╛рдорд┐рд▓ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдПрдмреНрд╕рдЯреНрд░реИрдХреНрд╢рди рдХрд╛ рдПрдХ рдФрд░ рд╕реНрддрд░ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ OpenGL рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрд╣ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрджрд┐ OpenGL + DirectX рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рд╣реИ)ред рд╡рд┐рднрд┐рдиреНрди рдмрдлрд╝рд░реНрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдереЛрдбрд╝реА рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд╕рд╛рде рдмрдлрд░ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рдФрд░ рд╕рд░рдгреА рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕реЗ рдмрдлрд░ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦреЗрдВред рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ; рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

рдмрдХреНрд╢реАрд╢


рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╕реНрдХреЙрдкреНрдб рдмрд╛рдЗрдВрдб рдХреНрд▓рд╛рд╕ рдмрдирд╛рдИред рд╡рд╣ рд╡рд╣рд╛рдБ рд╣реИ:

constexpr uint32_t default_bind_index = 0;
template <class T>
class binder : utils::noncopyable
{
public:
      template <uint32_t index = default_bind_index>
      binder(T& ref) : m_ref(ref) { m_ref.template bind<index>(); }
    ~binder()                            { m_ref.unbind();}
        
private:
    T& m_ref;
};

рдХреБрдЫ рдЗрд╕ рд▓рд╛рдЗрди рд╕реЗ рд╣реИрд░рд╛рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:

m_ref.template bind<index>();

рдпрджрд┐ рд╣рдо рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреАрд╡рд░реНрдб рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдирд┐рдореНрди рддреНрд░реБрдЯрд┐

рдкрдХрдбрд╝рддреЗ рд╣реИрдВ : binder.hpp: 22: 46 : рдбрд┐рдкреЗрдВрдбреЗрдВрдЯ рдЯреЗрдВрдкрд░реЗрдЪрд░ рдиреЗрдо 'рдмрд╛рдЗрдВрдб' рд╕реЗ рдкрд╣рд▓реЗ 'рдЯреЗрдВрдкрд▓реЗрдЯ' рдорд┐рд╕рд┐рдВрдЧ рдХрд╛
рдЕрд░реНрде рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЬрдм рдЯреА рдПрдХ рдирд┐рд░реНрднрд░ рдкреНрд░рдХрд╛рд░ рд╣реИред рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЕрднреА рддрдХ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ m_ref рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдЕрднреА рддрдХ рдХреЛрдИ рдмрдВрдзрди рдирд╣реАрдВ рдерд╛, рдЗрд╕рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рдЗрд╕реЗ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП <рдХреЛ рдСрдкрд░реЗрдЯрд░ рд╕реЗ рдХрдо рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рдВрдХрд▓рдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рдорд┐рд▓рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рд╕рджрд╕реНрдп рд╕рдорд╛рд░реЛрд╣ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛, рдЖрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреАрд╡рд░реНрдб рддреБрд░рдВрдд рдбреЙрдЯ рдСрдкрд░реЗрдЯрд░ рдХреЗ рдмрд╛рдж рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред

рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:

GLuint VAO;
    
primitive::buffer_object<type::buffer_type::array> vbo;
primitive::buffer_object<type::buffer_type::element> ebo;
    
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
    
{
    primitive::binder bind{vbo};
        
    glBufferData(GL_ARRAY_BUFFER, ...);
        
    glVertexAttribPointer(...);
    glEnableVertexAttribArray(...);
        
    glVertexAttribPointer(...);
    glEnableVertexAttribArray(...);
}
    
{
    primitive::binder bind{ebo};
        
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, ...);
        
    glBindVertexArray(0);
}

рдпрд╣ рдХреЛрдб рд╡рд░реНрдЯреЗрдХреНрд╕ рдРрд░реЗ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдХрд╛рд░рдгреЛрдВ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЬрд▓реНрдж рд╣реА рдЗрд╕рдХрд╛ рдкрддрд╛

рд▓рдЧрд╛рдКрдВрдЧрд╛ рдХрд┐ рдмрдлрд╝рд░ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП xD рд░реИрдкрд░реНрд╕ рдФрд░ OpenGL рдХреЙрд▓ рдЕрднреА рддреИрдпрд╛рд░ рдирд╣реАрдВ рд╣реИрдВ, рдХреЙрд▓ рдбреАрдПрд╕рдП (рдбрд╛рдпрд░реЗрдХреНрдЯ рд╕реНрдЯреЗрдЯ рдПрдХреНрд╕реЗрд╕) рдкрд░ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ ред

рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдЬреЛ рдЗрд╕реЗ рдЕрдВрдд рддрдХ рдкрдврд╝рддреЗ рд╣реИрдВред рдореБрдЭреЗ рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдкрд░ рдмрд╣реБрдд рдЦреБрд╢реА рд╣реЛрдЧреАред

All Articles