⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gim_memory.h

📁 ODE v0.8 很好用的多平台几何物理模拟库源代码,内含多個示例
💻 H
📖 第 1 页 / 共 3 页
字号:
    //terminate gimpact
    gimpact_terminate();
}
\endcode

\sa BUFFERS
*/
//! @{

//! Buffer managed array struct.
struct GBUFFER_ARRAY
{
  GBUFFER_ID m_buffer_id;
  char * m_buffer_data;
  char m_byte_stride;
  GUINT m_byte_offset;
  GUINT m_element_count;
};
//typedef  struct _GBUFFER_ARRAY GBUFFER_ARRAY;

//! Sets offset for a buffered array.
#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = _offset*(_array_data).m_byte_stride;

//! Sets offset for a buffered array.
#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) _offset = (_array_data).m_byte_offset/(_array_data).m_byte_stride;

//!Return a pointer of the element at the _index
#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + _index*(_array_data).m_byte_stride)

//! Sets stride for a buffered array.
#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);

//! Is array stride equal to the size of the type ?
#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))

///Verify if two arrays have the same data
#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame)\
{\
    aresame = 1;\
    if((_array_data1).m_buffer_id.m_buffer_id != (_array_data2).m_buffer_id.m_buffer_id || (_array_data1).m_buffer_id.m_buffer_manager_id != (_array_data2).m_buffer_id.m_buffer_manager_id || (_array_data1).m_byte_offset != (_array_data2).m_byte_offset)\
    {\
        aresame = 0;\
    }\
}\

//! Reserve size for a buffered array.
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,reserve_size)\
{ \
    if(reserve_size>(array_data).m_element_count)\
    {\
        GUINT _buffer_size,_newarray_size;\
        gim_get_buffer_size(&(array_data).m_buffer_id,_buffer_size);\
        _newarray_size = reserve_size*(array_data).m_byte_stride;\
        if(_newarray_size>_buffer_size)\
        { \
            _newarray_size += G_ARRAY_GROW_SIZE*(array_data).m_byte_stride;\
            gim_buffer_realloc(&(array_data).m_buffer_id,_newarray_size);\
        }\
    }\
}\

//! Pushes an element at last position
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_PUSH_ITEM(type,array_data,item)\
{\
    GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
    gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
    type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,(array_data).m_element_count);\
    memcpy(_pt,&item,sizeof(type));\
    gim_buffer_array_unlock(&array_data);\
    (array_data)->m_element_count++; \
}\

//! Pushes a new element at last position
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type,array_data)\
{\
    GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
    array_data->m_element_count++; \
}\

//! Inserts an element
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_INSERT_ITEM(type,array_data,item,index) \
{ \
    GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
    gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
    type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
    if(index<(array_data)->m_element_count-1) \
    { \
        memcpy(&_pt[index+1],&_pt[index],((array_data).m_element_count-index)*sizeof(type));\
    } \
    memcpy(&_pt[index],&item,sizeof(type));\
    gim_buffer_array_unlock(&array_data);\
    (array_data).m_element_count++; \
}\

//! Deletes an element
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_DELETE_ITEM(type,array_data,index) \
{ \
    if(index<(array_data).m_element_count-1) \
    { \
        gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
        type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
        memcpy(&_pt[index],&_pt[index+1],((array_data).m_element_count-index-1)*sizeof(type));\
        gim_buffer_array_unlock(&array_data);\
    } \
    (array_data).m_element_count--;    \
}\

//! Deletes an element at last position
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
{ \
    if((array_data).m_element_count>0) \
    { \
        (array_data).m_element_count--;    \
    } \
}\


//! Initializes an GBUFFER_ARRAY object from a buffer ID
/*!
m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
\param array_data Array structure to be filled
\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
\param element_count Number of elements
\param offset element offset, it isn't byte offset. 0 is recomended
\param byte_stride size of each element.  0 is recomended.
\post Adds reference to the buffer
\sa gim_buffer_add_ref
*/
#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data,buffer_id,element_count,offset,byte_stride)\
{\
    (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
    (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
    (array_data).m_buffer_data = 0;\
    (array_data).m_element_count = element_count;\
    (array_data).m_byte_stride = byte_stride;\
    GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
    gim_buffer_add_ref(&(buffer_id));\
}\

//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
/*!
m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
\param type Type of the Array. It determines the stride.
\param array_data Array structure to be filled
\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
\param element_count Number of elements
\param offset element offset, it isn't byte offset. 0 is recomended
\post Adds reference to the buffer
\sa gim_buffer_add_ref
*/
#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,offset)\
{\
    (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
    (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
    (array_data).m_buffer_data = 0;\
    (array_data).m_element_count = element_count;\
    GIM_BUFFER_ARRAY_SET_STRIDE(type,array_data);\
    GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
    gim_buffer_add_ref(&(buffer_id));\
}\

//! Initializes a buffer array giving a data type and a buffer id
/*!
m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
\param type Type of the Array. It determines the stride.
\param array_data Array structure to be filled
\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
\param element_count Number of elements
\post Adds reference to the buffer
\sa gim_buffer_add_ref
*/
#define GIM_BUFFER_ARRAY_INIT_TYPE(type,array_data,buffer_id,element_count) GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,0)

//! Gain access to the array buffer through the m_buffer_data element
/*!
m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
Then, You'd need to call unlock_array when finish to using the array access.

\pre if m_buffer_data != 0, the function returns
\param array_data Array structure to be locked
\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
\return an Buffer error code
*/
GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);

//! close the access to the array buffer through the m_buffer_data element
/*!
\param array_data Array structure to be locked
\return an Buffer error code
*/
GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);

//! Copy an array by reference
/*!
\post A reference to the m_buffer_id is increased.
*/
void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY  * dest_data);


//! Copy an array by value
/*!
\post A new buffer is created
*/
void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY  * dest_data, GUINT buffer_manager_id,int usage);

//! Destroys an GBUFFER_ARRAY object
/*!
\post Attemps to destroy the buffer, decreases reference counting
*/
void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);

//! Copy the content of the array to a pointer
/*!
\pre dest_data must have the same size as the array_data
\param type
\param array_data A GBUFFERED_ARRAY structure
\param dest_data A type pointer
*/
#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data)\
{\
    if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
    {\
        gim_download_from_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset,(void *) dest_data, (array_data).m_element_count*(array_data).m_byte_stride);\
    }\
    else\
    {\
        GUINT _k_, _ecount_= (array_data).m_element_count;\
        type * _source_vert_;\
        type * _dest_vert_ = dest_data;\
        gim_buffer_array_lock(&(array_data),G_MA_READ_ONLY);\
        for (_k_ = 0;_k_< _ecount_; _k_++)\
        {\
            _source_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
            memcpy(_dest_vert_,_source_vert_,sizeof(type));\
            _dest_vert_++;\
        }\
        gim_buffer_array_unlock(&(array_data));\
    }\
}\

//! Upload the content of a a pointer to a buffered array
/*!
\pre source_data must have the same size as the array_data
\param type
\param array_data A GBUFFERED_ARRAY structure
\param source_data A void pointer
*/
#define GIM_BUFFER_ARRAY_UPLOAD(type,array_data,source_data)\
{\
    if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
    {\
        gim_upload_to_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset,(void *) source_data, (array_data).m_element_count*(array_data).m_byte_stride);\
    }\
    else\
    {\
        GUINT _k_, _ecount_= (array_data).m_element_count;\
        type * _source_vert_ = source_data;\
        type * _dest_vert_;\
        gim_buffer_array_lock(&(array_data),G_MA_WRITE_ONLY);\
        for (_k_ = 0;_k_< _ecount_; _k_++)\
        {\
            _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
            memcpy(_dest_vert_,_source_vert_,sizeof(type));\
            _source_vert_++;\
        }\
        gim_buffer_array_unlock(&(array_data));\
    }\
}\


//!Kernel function prototype for process streams, given a buffered array as source and
/*!
\param 1 the uniform arguments
\param 2 the source stream
\param 3 the destination stream
*/
typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);

//! Generic Stream Processingp loop
/*!

This macro executes a kernel macro or function for each element of the streams
\pre _src_array->m_count <= _dst_array->m_count

\param _uniform_data An argument to be passed to the Kernel function
\param _src_array An GBUFFER_ARRAY structure passed as the source stream
\param _dst_array An GBUFFER_ARRAY  structure passed as the source stream
\param _kernel Macro or function of the kernel
\param _src_type Required. Type of all elements of the source stream
\param _dst_type Required. Type of all elements of the dest stream
*/
#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_type,_dst_type) {\
\
    gim_buffer_array_lock(&_src_array,G_MA_READ_ONLY);\
    gim_buffer_array_lock(&_dst_array,G_MA_WRITE_ONLY);\
\
    GUINT _i_, _count_=(_src_array).m_element_count;\
\
    _src_type * _source_vert_;\
    _dst_type * _dest_vert_;\
    if(GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type,_src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type,_dst_array))\
    {\
\
        _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,0);\
        _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,0);\
        for (_i_ = 0;_i_< _count_; _i_++)\
        {\
            _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
            _source_vert_++;\
            _dest_vert_++;\
        }\
    }\
    else\
    {\
        for (_i_ = 0;_i_< _count_; _i_++)\
        {\
            _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,_i_);\
            _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,_i_);\
            _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
        }\
    }\
    gim_buffer_array_unlock(&_src_array);\
    gim_buffer_array_unlock(&_dst_array);\
}\

//! @}

#endif // GIM_MEMORY_H_INCLUDED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -