<commit_before>//https://code.google.com/p/nya-engine/

/*
    ToDo:
          is_valid function
          log
*/

#include "vbo.h"
#include "render.h"
#include "texture.h"
#include "shader.h"
#include "platform_specific_gl.h"
#include "statistics.h"

#include "memory/tmp_buffer.h"

#ifdef DIRECTX11
    #include "shader.h"
#endif

#ifdef __APPLE__
    #define USE_VAO
#endif

#ifdef OPENGL_ES
    #define glGenVertexArrays glGenVertexArraysOES
    #define glBindVertexArray glBindVertexArrayOES
    #define glDeleteVertexArrays glDeleteVertexArraysOES
#elif __APPLE__
    #define glGenVertexArrays glGenVertexArraysAPPLE
    #define glBindVertexArray glBindVertexArrayAPPLE
    #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
#endif

namespace nya_render
{

namespace
{
    int current_verts=-1;
    int active_verts=-1;
    int current_inds=-1;
    int active_inds=-1;

    struct vbo_obj_atributes
    {
        struct attribute
        {
            bool has;
            vbo::vertex_atrib_type type:CHAR_BIT;
            short dimension;
            unsigned int offset;

            bool compare(const attribute &a) const { return a.offset==offset && a.dimension==dimension && a.type==type; }

            attribute(): has(false),type(vbo::float32),dimension(0),offset(0) {}
        };

        attribute vertices;
        attribute colors;
        attribute normals;
        attribute tcs[vbo::max_tex_coord];

        unsigned int vertex_stride;

        vbo_obj_atributes(): vertex_stride(0) {}
    };

    OPENGL_ONLY(vbo_obj_atributes active_attributes);

    struct vbo_obj: public vbo_obj_atributes
    {
        vbo::element_type element_type;
        vbo::index_size element_size;
        unsigned int element_count;
        vbo::usage_hint elements_usage;
        unsigned int allocated_elements_count;

        unsigned int verts_count;
        unsigned int allocated_verts_count;

#ifdef USE_VAO
        unsigned int vertex_array_object;
        unsigned int active_vao_ibuf;
#endif
        vbo::usage_hint vertex_usage;

        DIRECTX11_ONLY(ID3D11Buffer *vertex_loc,*index_loc);
        OPENGL_ONLY(unsigned int vertex_loc,index_loc);

        vbo_obj(): vertex_loc(0),index_loc(0),element_type(vbo::triangles),element_count(0),allocated_elements_count(0),
                   verts_count(0),allocated_verts_count(0)
        {
#ifdef USE_VAO
            vertex_array_object=0;
            active_vao_ibuf=0;
#endif
        }

    public:
        static int add() { return get_vbo_objs().add(); }
        static vbo_obj &get(int idx) { return get_vbo_objs().get(idx); }
        static void remove(int idx) { return get_vbo_objs().remove(idx); }
        static void invalidate_all() { return get_vbo_objs().invalidate_all(); }
        static void release_all() { return get_vbo_objs().release_all(); }

    public:
        void release();

#ifdef USE_VAO
        void release_vao()
        {
            if(vertex_array_object==0)
                return;

            glDeleteVertexArrays(1,&vertex_array_object);
            vertex_array_object=active_vao_ibuf=0;
        }
#endif

    public:
        typedef render_objects<vbo_obj> vbo_objs;
        static vbo_objs &get_vbo_objs()
        {
            static vbo_objs objs;
            return objs;
        }
    };

#ifdef DIRECTX11
DXGI_FORMAT get_dx_format(int dimension,vbo::vertex_atrib_type type)
{
    if(type==vbo::float16)
    {
        switch(dimension)
        {
            case 1: case 2: return DXGI_FORMAT_R16G16_FLOAT;
            case 3: case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT;
        }
    }

    switch(dimension)
    {
        case 1: return DXGI_FORMAT_R32_FLOAT;
        case 2: return DXGI_FORMAT_R32G32_FLOAT;
        case 3: return DXGI_FORMAT_R32G32B32_FLOAT;
        case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
    }

    return DXGI_FORMAT_UNKNOWN;
}

bool set_dx_topology(vbo::element_type type)
{
    switch(type)
    {
        case vbo::triangles: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); return true;
        case vbo::triangle_strip: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); return true;
        case vbo::points: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); return true;
        case vbo::lines: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); return true;
        case vbo::line_strip: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); return true;
        default: return false;
    }

    return false;
}

#else
int get_gl_element_type(vbo::element_type type)
{
    switch(type)
    {
        case vbo::triangles: return GL_TRIANGLES;;
        case vbo::triangle_strip: return GL_TRIANGLE_STRIP;
        case vbo::points: return GL_POINTS;
        case vbo::lines: return GL_LINES;
        case vbo::line_strip: return GL_LINE_STRIP;
        default: return -1;
    }

    return -1;
}

int get_gl_element_type(vbo::vertex_atrib_type type)
{
    switch(type)
    {
        case vbo::float32: return GL_FLOAT;
#ifdef OPENGL_ES
        case vbo::float16: return GL_HALF_FLOAT_OES;
#else
        case vbo::float16: return GL_HALF_FLOAT_ARB;
#endif
    }

    return GL_FLOAT;
}

  #ifndef NO_EXTENSIONS_INIT
    PFNGLGENBUFFERSARBPROC glGenBuffers;
    PFNGLBINDBUFFERARBPROC glBindBuffer;
    PFNGLBUFFERDATAARBPROC glBufferData;
    PFNGLBUFFERSUBDATAARBPROC glBufferSubData;
    PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubData;
    PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
    PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture;
  #endif

  #ifndef GL_ARRAY_BUFFER
    #define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
  #endif

  #ifndef GL_DYNAMIC_DRAW
    #define GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW_ARB
  #endif

  #ifndef GL_STATIC_DRAW<commit_msg>opengl3 vbo<commit_after>//https://code.google.com/p/nya-engine/

/*
    ToDo:
          is_valid function
          log
*/

#include "vbo.h"
#include "render.h"
#include "texture.h"
#include "shader.h"
#include "platform_specific_gl.h"
#include "statistics.h"

#include "memory/tmp_buffer.h"

#ifdef DIRECTX11
    #include "shader.h"
#endif

#ifdef __APPLE__
    #define USE_VAO
#endif

#ifdef OPENGL_ES
    #define glGenVertexArrays glGenVertexArraysOES
    #define glBindVertexArray glBindVertexArrayOES
    #define glDeleteVertexArrays glDeleteVertexArraysOES
#elif defined __APPLE__ && !defined OPENGL3
    #define glGenVertexArrays glGenVertexArraysAPPLE
    #define glBindVertexArray glBindVertexArrayAPPLE
    #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
#endif

#ifdef OPENGL_ES
    #define GL_HALF_FLOAT GL_HALF_FLOAT_OES
#endif

#ifndef GL_HALF_FLOAT
    #define GL_HALF_FLOAT GL_HALF_FLOAT_ARB
#endif

namespace nya_render
{

namespace
{
    int current_verts=-1;
    int active_verts=-1;
    int current_inds=-1;
    int active_inds=-1;

    struct vbo_obj_atributes
    {
        struct attribute
        {
            bool has;
            vbo::vertex_atrib_type type:CHAR_BIT;
            short dimension;
            unsigned int offset;

            bool compare(const attribute &a) const { return a.offset==offset && a.dimension==dimension && a.type==type; }

            attribute(): has(false),type(vbo::float32),dimension(0),offset(0) {}
        };

        attribute vertices;
        attribute colors;
        attribute normals;
        attribute tcs[vbo::max_tex_coord];

        unsigned int vertex_stride;

        vbo_obj_atributes(): vertex_stride(0) {}
    };

    OPENGL_ONLY(vbo_obj_atributes active_attributes);

    struct vbo_obj: public vbo_obj_atributes
    {
        vbo::element_type element_type;
        vbo::index_size element_size;
        unsigned int element_count;
        vbo::usage_hint elements_usage;
        unsigned int allocated_elements_count;

        unsigned int verts_count;
        unsigned int allocated_verts_count;

#ifdef USE_VAO
        unsigned int vertex_array_object;
        unsigned int active_vao_ibuf;
#endif
        vbo::usage_hint vertex_usage;

        DIRECTX11_ONLY(ID3D11Buffer *vertex_loc,*index_loc);
        OPENGL_ONLY(unsigned int vertex_loc,index_loc);

        vbo_obj(): vertex_loc(0),index_loc(0),element_type(vbo::triangles),element_count(0),allocated_elements_count(0),
                   verts_count(0),allocated_verts_count(0)
        {
#ifdef USE_VAO
            vertex_array_object=0;
            active_vao_ibuf=0;
#endif
        }

    public:
        static int add() { return get_vbo_objs().add(); }
        static vbo_obj &get(int idx) { return get_vbo_objs().get(idx); }
        static void remove(int idx) { return get_vbo_objs().remove(idx); }
        static void invalidate_all() { return get_vbo_objs().invalidate_all(); }
        static void release_all() { return get_vbo_objs().release_all(); }

    public:
        void release();

#ifdef USE_VAO
        void release_vao()
        {
            if(vertex_array_object==0)
                return;

            glDeleteVertexArrays(1,&vertex_array_object);
            vertex_array_object=active_vao_ibuf=0;
        }
#endif

    public:
        typedef render_objects<vbo_obj> vbo_objs;
        static vbo_objs &get_vbo_objs()
        {
            static vbo_objs objs;
            return objs;
        }
    };

#ifdef DIRECTX11
DXGI_FORMAT get_dx_format(int dimension,vbo::vertex_atrib_type type)
{
    if(type==vbo::float16)
    {
        switch(dimension)
        {
            case 1: case 2: return DXGI_FORMAT_R16G16_FLOAT;
            case 3: case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT;
        }
    }

    switch(dimension)
    {
        case 1: return DXGI_FORMAT_R32_FLOAT;
        case 2: return DXGI_FORMAT_R32G32_FLOAT;
        case 3: return DXGI_FORMAT_R32G32B32_FLOAT;
        case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
    }

    return DXGI_FORMAT_UNKNOWN;
}

bool set_dx_topology(vbo::element_type type)
{
    switch(type)
    {
        case vbo::triangles: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); return true;
        case vbo::triangle_strip: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); return true;
        case vbo::points: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); return true;
        case vbo::lines: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); return true;
        case vbo::line_strip: get_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); return true;
        default: return false;
    }

    return false;
}

#else
int get_gl_element_type(vbo::element_type type)
{
    switch(type)
    {
        case vbo::triangles: return GL_TRIANGLES;;
        case vbo::triangle_strip: return GL_TRIANGLE_STRIP;
        case vbo::points: return GL_POINTS;
        case vbo::lines: return GL_LINES;
        case vbo::line_strip: return GL_LINE_STRIP;
        default: return -1;
    }

    return -1;
}

int get_gl_element_type(vbo::vertex_atrib_type type)
{
    switch(type)
    {
        case vbo::float32: return GL_FLOAT;
        case vbo::float16: return GL_HALF_FLOAT;
    }

    return GL_FLOAT;
}

  #ifndef NO_EXTENSIONS_INIT
    PFNGLGENBUFFERSARBPROC glGenBuffers;
    PFNGLBINDBUFFERARBPROC glBindBuffer;
    PFNGLBUFFERDATAARBPROC glBufferData;
    PFNGLBUFFERSUBDATAARBPROC glBufferSubData;
    PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubData;
    PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
    PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture;
  #endif

  #ifndef GL_ARRAY_BUFFER
    #define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
  #endif

  #ifndef GL_DYNAMIC_DRAW
    #define GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW_ARB
  #endif

  #ifndef GL_STATIC_DRAW
{'fraction_non_alphanumeric': 0.08323404255319149, 'fraction_numerical': 0.016, 'mean_word_length': 3.149364406779661, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4575300', 'n_tokens_mistral': 4117, 'n_tokens_neox': 4010, 'n_words': 719}