/* * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved. * * Contact: * DongKyun Yun * SangJin Kim * HyunGoo Kang * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Contributors: * - S-Core Co., Ltd * */ #include "es2front.h" void GL_APIENTRY ES2ENTRY(DrawElements)(GLenum mode, GLsizei count, GLenum type, const void* indices) { GLvoid* pNewArea; GLchar* pFixedBase; GLfloat* pFloat; GLint iArrayBufferBinding; GLint iElementArrayBufferBinding; int iFirst, iLast; int i, j; GLboolean bSpecial = (CCV(pVertexAttrib[0].bEnabled) == GL_FALSE) && (CCV(pVertexAttrib[1].bEnabled) == GL_TRUE); if (mode < 0 || GL_TRIANGLE_FAN < mode) { ES2INTER(SetError)(GL_INVALID_ENUM); return; } if (count < 0) { ES2INTER(SetError)(GL_INVALID_VALUE); return; } else if (count == 0) { return; } switch (type) { default: ES2INTER(SetError)(GL_INVALID_ENUM); return; case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT: #if defined(PROVIDING_OES_element_index_uint) case GL_UNSIGNED_INT: #endif break; } FNPTR(GetIntegerv)(GL_ELEMENT_ARRAY_BUFFER_BINDING, &iElementArrayBufferBinding); switch (type) { case GL_UNSIGNED_BYTE: { GLubyte* pSrc; static GLubyte* pBufferArea = NULL; if (iElementArrayBufferBinding != 0) { pSrc = (GLubyte*)realloc(pBufferArea, count * sizeof(GLubyte)); assert(pSrc != NULL); pBufferArea = pSrc; FNPTR(GetBufferSubData)(GL_ELEMENT_ARRAY_BUFFER, (GLintptr)indices, count * sizeof(GLubyte), pSrc); } else { pSrc = (GLubyte*)(indices); } iFirst = iLast = pSrc[0]; for (i = 1; i < count; i++) { if (pSrc[i] > iLast) iLast = pSrc[i]; else if (pSrc[i] < iFirst) iFirst = pSrc[i]; } } break; case GL_UNSIGNED_SHORT: { GLushort* pSrc; static GLushort* pBufferArea = NULL; if (iElementArrayBufferBinding != 0) { pSrc = (GLushort*)realloc(pBufferArea, count * sizeof(GLushort)); assert(pSrc != NULL); pBufferArea = pSrc; FNPTR(GetBufferSubData)(GL_ELEMENT_ARRAY_BUFFER, (GLintptr)indices, count * sizeof(GLushort), pSrc); } else { pSrc = (GLushort*)(indices); } iFirst = iLast = pSrc[0]; for (i = 1; i < count; i++) { if (pSrc[i] > iLast) iLast = pSrc[i]; else if (pSrc[i] < iFirst) iFirst = pSrc[i]; } } break; #if defined(PROVIDING_OES_element_index_uint) case GL_UNSIGNED_INT: { GLuint* pSrc; static GLuint* pBufferArea = NULL; if (iElementArrayBufferBinding != 0) { pSrc = (GLuint*)realloc(pBufferArea, count * sizeof(GLuint)); assert(pSrc != NULL); pBufferArea = pSrc; FNPTR(GetBufferSubData)(GL_ELEMENT_ARRAY_BUFFER, (GLintptr)indices, count * sizeof(GLuint), pSrc); } else { pSrc = (GLuint*)(indices); } iFirst = iLast = pSrc[0]; for (i = 1; i < count; i++) { if (pSrc[i] > iLast) iLast = pSrc[i]; else if (pSrc[i] < iFirst) iFirst = pSrc[i]; } } break; #endif } FNPTR(GetIntegerv)(GL_ARRAY_BUFFER_BINDING, &iArrayBufferBinding); FNPTR(BindBuffer)(GL_ARRAY_BUFFER, 0); for (i = 0; i < CCV(nMaxVertexAttribs); i++) { register struct VertexAttribUnit* pVertexAttrib = &(CCV(pVertexAttrib[i])); if (pVertexAttrib->bEnabled == GL_FALSE) continue; if (i == 1 && bSpecial == GL_TRUE && pVertexAttrib->eType != GL_FIXED) { FNPTR(BindBuffer)(GL_ARRAY_BUFFER, pVertexAttrib->uBufferBinding); FNPTR(VertexAttribPointer)(0, pVertexAttrib->iSize, pVertexAttrib->eType, pVertexAttrib->bNormalized, pVertexAttrib->uStride, pVertexAttrib->pData); FNPTR(BindBuffer)(GL_ARRAY_BUFFER, 0); } if (pVertexAttrib->eType != GL_FIXED) continue; if (pVertexAttrib->uBufferBinding != 0) { register GLuint uBuffer = pVertexAttrib->uBufferBinding; register struct BufferObjectUnit* pBufferObject = &CCV(pBufferObject[uBuffer]); #if defined(USE_CONVERTED) register GLubyte* pConverted = (GLubyte*)(pBufferObject->pConverted) + (GLsizei)(pVertexAttrib->pData); FNPTR(BindBuffer)(GL_ARRAY_BUFFER, 0); FNPTR(VertexAttribPointer)(i, pVertexAttrib->iSize, GL_FLOAT, pVertexAttrib->bNormalized, pVertexAttrib->uStride, pConverted); if (i == 1 && bSpecial == GL_TRUE) { FNPTR(VertexAttribPointer)(0, pVertexAttrib->iSize, GL_FLOAT, pVertexAttrib->bNormalized, pVertexAttrib->uStride, pConverted); } #else register GLubyte* pConverted = (GLubyte*)pVertexAttrib->pData + pBufferObject->uOffset; FNPTR(BindBuffer)(GL_ARRAY_BUFFER, uBuffer); FNPTR(VertexAttribPointer)(i, pVertexAttrib->iSize, GL_FLOAT, pVertexAttrib->bNormalized, pVertexAttrib->uStride, pConverted); if (i == 1 && bSpecial == GL_TRUE) { FNPTR(VertexAttribPointer)(0, pVertexAttrib->iSize, GL_FLOAT, pVertexAttrib->bNormalized, pVertexAttrib->uStride, pConverted); } FNPTR(BindBuffer)(GL_ARRAY_BUFFER, 0); #endif } else { pNewArea = realloc(pVertexAttrib->pConverted, pVertexAttrib->iSize * (iLast - iFirst + 1) * sizeof(GLfixed)); if (pNewArea == NULL) { ES2INTER(SetError)(GL_OUT_OF_MEMORY); FNPTR(BindBuffer)(GL_ARRAY_BUFFER, iArrayBufferBinding); return; } pVertexAttrib->pConverted = pNewArea; pFixedBase = (GLchar*)(pVertexAttrib->pData) + iFirst * pVertexAttrib->uStride; pFloat = (GLfloat*)(pNewArea); for (j = iFirst; j < iLast + 1; j++) { int k = pVertexAttrib->iSize; GLfixed* pFixed = (GLfixed*)(pFixedBase); while (k--) { register GLfixed xValue = *pFixed++; register GLfloat fValue = fixed_to_float(xValue); *pFloat++ = fValue; } pFixedBase += pVertexAttrib->uStride; } FNPTR(VertexAttribPointer)(i, pVertexAttrib->iSize, GL_FLOAT, pVertexAttrib->bNormalized, pVertexAttrib->iSize * sizeof(GLfixed), (GLvoid*)((GLubyte*)(pVertexAttrib->pConverted) - iFirst * pVertexAttrib->uStride)); if (i == 1 && bSpecial == GL_TRUE) { FNPTR(VertexAttribPointer)(0, pVertexAttrib->iSize, GL_FLOAT, pVertexAttrib->bNormalized, pVertexAttrib->iSize * sizeof(GLfixed), (GLvoid*)((GLubyte*)(pVertexAttrib->pConverted) - iFirst * pVertexAttrib->uStride)); } } } if (bSpecial == GL_TRUE) { FNPTR(EnableVertexAttribArray)(0); } FNPTR(BindBuffer)(GL_ARRAY_BUFFER, iArrayBufferBinding); FNPTR(DrawElements)(mode, count, type, indices); if (bSpecial == GL_TRUE) { FNPTR(DisableVertexAttribArray)(0); } }