File indexing completed on 2026-04-09 07:49:38
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 struct NP ;
0014 struct SMesh ;
0015 struct SGLFW_Program ;
0016
0017
0018 struct SGLFW_Mesh
0019 {
0020 static constexpr const char* _DUMP = "SGLFW_Mesh__DUMP" ;
0021 bool DUMP ;
0022 const SMesh* mesh ;
0023
0024 SGLFW_Buffer* vtx ;
0025 SGLFW_Buffer* nrm ;
0026 SGLFW_Buffer* ins ;
0027
0028 SGLFW_VAO* vao ;
0029 SGLFW_Buffer* idx ;
0030
0031 int inst_num ;
0032 const float* inst_values ;
0033 int render_count ;
0034
0035 SGLFW_Mesh(const SMesh* mesh ) ;
0036 void init();
0037
0038 void set_inst(const NP* _inst );
0039 void set_inst(int _inst_num, const float* _inst_values );
0040 bool has_inst() const ;
0041
0042 std::string descInst() const ;
0043 std::string desc() const ;
0044
0045 void render(const SGLFW_Program* prog);
0046 void render_drawElements() const ;
0047 };
0048
0049 inline SGLFW_Mesh::SGLFW_Mesh(const SMesh* _mesh )
0050 :
0051 DUMP(ssys::getenvbool(_DUMP)),
0052 mesh(_mesh),
0053 vtx(nullptr),
0054 nrm(nullptr),
0055 ins(nullptr),
0056 vao(nullptr),
0057 idx(nullptr),
0058 inst_num(0),
0059 inst_values(nullptr),
0060 render_count(0)
0061 {
0062 init();
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 inline void SGLFW_Mesh::init()
0076 {
0077 vtx = new SGLFW_Buffer( "SGLFW_Mesh.vtx", mesh->vtx->arr_bytes(), mesh->vtx->cvalues<float>(), GL_ARRAY_BUFFER, GL_STATIC_DRAW );
0078 vtx->bind();
0079 vtx->upload();
0080
0081 nrm = new SGLFW_Buffer( "SGLFW_Mesh.nrm", mesh->nrm->arr_bytes(), mesh->nrm->cvalues<float>(), GL_ARRAY_BUFFER, GL_STATIC_DRAW );
0082 nrm->bind();
0083 nrm->upload();
0084
0085 vao = new SGLFW_VAO("SGLFW_Mesh.vao") ;
0086 vao->bind();
0087
0088 idx = new SGLFW_Buffer("SGLFW_Mesh.idx", mesh->tri->arr_bytes(), mesh->tri->cvalues<int>() , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW );
0089 idx->bind();
0090 idx->upload();
0091 }
0092
0093 inline void SGLFW_Mesh::set_inst(const NP* _inst )
0094 {
0095 if(_inst == nullptr) return ;
0096 assert( _inst->uifc == 'f' );
0097 assert( _inst->ebyte == 4 );
0098 assert( _inst->has_shape(-1,4,4));
0099 set_inst( _inst->num_items(), _inst->cvalues<float>() );
0100 }
0101
0102 inline void SGLFW_Mesh::set_inst(int _inst_num, const float* _inst_values )
0103 {
0104 inst_num = _inst_num ;
0105 inst_values = _inst_values ;
0106
0107 int itemsize = 4*4*sizeof(float) ;
0108 int num_bytes = inst_num*itemsize ;
0109 ins = new SGLFW_Buffer("SGLFW_Mesh.ins", num_bytes, inst_values, GL_ARRAY_BUFFER, GL_STATIC_DRAW );
0110 ins->bind();
0111 ins->upload();
0112 }
0113
0114 inline bool SGLFW_Mesh::has_inst() const
0115 {
0116 return inst_num > 0 && inst_values != nullptr ;
0117 }
0118
0119
0120 inline std::string SGLFW_Mesh::desc() const
0121 {
0122 std::stringstream ss ;
0123 ss << descInst() ;
0124 std::string str = ss.str() ;
0125 return str ;
0126 }
0127 inline std::string SGLFW_Mesh::descInst() const
0128 {
0129 int edge_items = 10 ;
0130 std::stringstream ss ;
0131 ss << "[SGLFW_Mesh::descInst inst_num " << inst_num << std::endl ;
0132 ss << stra<float>::DescItems( inst_values, 16, inst_num, edge_items );
0133 ss << "]SGLFW_Mesh::descInst inst_num " << inst_num << std::endl ;
0134 std::string str = ss.str() ;
0135 return str ;
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 inline void SGLFW_Mesh::render(const SGLFW_Program* prog)
0151 {
0152 prog->use();
0153 vao->bind();
0154
0155 vtx->bind();
0156 prog->enableVertexAttribArray( prog->vtx_attname, SMesh::VTX_SPEC );
0157
0158 nrm->bind();
0159 prog->enableVertexAttribArray( prog->nrm_attname, SMesh::NRM_SPEC );
0160
0161 if(ins)
0162 {
0163 ins->bind();
0164 prog->enableVertexAttribArray_OfTransforms( prog->ins_attname ) ;
0165 }
0166
0167 idx->bind();
0168 prog->updateMVP();
0169
0170 render_drawElements();
0171 render_count += 1 ;
0172 }
0173
0174 inline void SGLFW_Mesh::render_drawElements() const
0175 {
0176 GLenum mode = GL_TRIANGLES ;
0177 GLsizei count = mesh->indices_num() ;
0178 GLenum type = GL_UNSIGNED_INT ;
0179 const void * indices = (GLvoid*)(sizeof(GLuint) * mesh->indices_offset() ) ;
0180 GLsizei instancecount = ins ? inst_num : 0 ;
0181
0182 if(instancecount > 0)
0183 {
0184
0185 #ifdef __APPLE__
0186 glDrawElementsInstanced(mode, count, type, indices, instancecount );
0187 if(DUMP && render_count < 10 ) std::cout
0188 << "SGLFW_Mesh::render_drawElements.glDrawElementsInstanced"
0189 << " render_count " << render_count
0190 << " instancecount " << instancecount
0191 << std::endl
0192 ;
0193
0194 #else
0195 GLint basevertex = 0 ;
0196 GLuint baseinstance = 0 ;
0197 glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, basevertex, baseinstance );
0198
0199
0200 if(DUMP && render_count < 10 ) std::cout
0201 << "SGLFW_Mesh::render_drawElements.glDrawElementsInstancedBaseVertexBaseInstance"
0202 << " render_count " << render_count
0203 << " instancecount " << instancecount
0204 << std::endl
0205 ;
0206 #endif
0207
0208 }
0209 else
0210 {
0211 glDrawElements(mode, count, type, indices );
0212 }
0213 }
0214
0215
0216