//------------------------------------------------------------------------------------ // выключаем все после прорисовки //------------------------------------------------------------------------------------ void vw_SendVertices_DisableStatesAndPointers(int DataFormat, unsigned int *VBO, unsigned int *VAO) { // флаг нужно ли с вaо делать bool NeedVAO = OpenGL_DevCaps.VAOSupported; if (VAO == 0) NeedVAO = false; if (NeedVAO) { vw_BindVAO(0); } else { // флаг нужно ли с вбо делать bool NeedVBO = OpenGL_DevCaps.VBOSupported; if (VBO == 0) NeedVBO = false; if ((DataFormat & 0x0000F00) != 0) glDisableClientState(GL_NORMAL_ARRAY); if ((DataFormat & 0x00000F0) != 0) glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); // кол-во текстур int TextQ = DataFormat & 0x000000F; for (int i=TextQ-1; i>=0; i--) { if (glClientActiveTexture_ARB != 0) glClientActiveTexture_ARB(GL_TEXTURE0+i); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } // сбрасываем индексный и вертексный буфера, если они были установлены if (IndexVBO != 0) vw_BindVBO(RI_ELEMENT_ARRAY_BUFFER, 0); if (NeedVBO) vw_BindVBO(RI_ARRAY_BUFFER, 0); } }
bool vw_BuildVAO(unsigned int *VAO, int NumVertices, int DataFormat, void *Data, int Stride, unsigned int *VBO, unsigned int RangeStart, unsigned int *DataIndex, unsigned int *DataIndexVBO) #endif { if (VAO == 0) return false; if (glGenVertexArraysARB == NULL) return false; if (glIsVertexArrayARB == NULL) return false; glGenVertexArraysARB(1, VAO); vw_BindVAO(*VAO); vw_SendVertices_EnableStatesAndPointers(NumVertices, DataFormat, Data, Stride, VBO, RangeStart, DataIndex, DataIndexVBO); vw_BindVAO(0); vw_SendVertices_DisableStatesAndPointers(DataFormat, VBO, 0); if (!glIsVertexArrayARB(*VAO)) return false; return true; }
void vw_SendVertices(int PrimitiveType, int NumVertices, int DataFormat, void *Data, int Stride, unsigned int *VBO, unsigned int RangeStart, unsigned int *DataIndex, unsigned int *DataIndexVBO, unsigned int *VAO) #endif { // если ничего не передали if (Data == 0 && VBO == 0 && VAO == 0) return; // флаг нужно ли с вaо делать bool NeedVAO = OpenGL_DevCaps.VAOSupported; if (VAO == 0) NeedVAO = false; // устанавливаем все необходимые указатели для прорисовки и получаем индексы #ifdef USE_GLES GLushort *VertexIndexPointer = 0; #else GLuint *VertexIndexPointer = 0; #endif if (NeedVAO) { vw_BindVAO(*VAO); } else { VertexIndexPointer = vw_SendVertices_EnableStatesAndPointers(NumVertices, DataFormat, Data, Stride, VBO, RangeStart, DataIndex, DataIndexVBO); } // 1) Нельзя использовать short индексы (глючит в линуксе на картах нвидия, проверял на 97.55 драйвере) // 2) Нельзя рисовать через glBegin-glEnd и glDrawArray - проблемы в линуксе у ati драйверов (на glDrawArray вообще сегфолтит) // 3) С glDrawRangeElements могут быть неприятные сюрпризы на маках (интел+интел видео), сегфолты даже если учесть все ограничения (вертекс и индекс) // рисуем switch(PrimitiveType) { case RI_POINTS: glDrawElements(GL_POINTS,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices; break; case RI_LINES: glDrawElements(GL_LINES,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices/2; break; case RI_TRIANGLES: glDrawElements(GL_TRIANGLES,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices/3; break; case RI_TRIANGLE_STRIP: glDrawElements(GL_TRIANGLE_STRIP,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices-2; break; case RI_TRIANGLE_FAN: glDrawElements(GL_TRIANGLE_FAN,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices-2; break; case RI_QUADS: #ifdef USE_GLES glDrawElements(GL_TRIANGLE_STRIP,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices-2; #else glDrawElements(GL_QUADS,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer); tmpPrimCountGL += NumVertices/4; #endif break; default: fprintf(stderr, "Error in vw_SendVertices function call, wrong PrimitiveType.\n"); return; } // выключаем все что включали vw_SendVertices_DisableStatesAndPointers(DataFormat, VBO, VAO); }