1a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk/* 2a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project 3a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * 4a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License"); 5a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * you may not use this file except in compliance with the License. 6a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * You may obtain a copy of the License at 7a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * 8a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * http://www.apache.org/licenses/LICENSE-2.0 9a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * 10a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Unless required by applicable law or agreed to in writing, software 11a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS, 12a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * See the License for the specific language governing permissions and 14a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * limitations under the License. 15a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk */ 16a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 17a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <GLES/gl.h> 18a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <GLES2/gl2.h> 19a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <GLES/glext.h> 20a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 21a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <rs_hal.h> 22a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <rsContext.h> 23a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <rsMesh.h> 24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 25eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdAllocation.h" 26a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdMeshObj.h" 27c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk#include "rsdGL.h" 28a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 29a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukusing namespace android; 30a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukusing namespace android::renderscript; 31a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 32a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukRsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) { 33a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mRSMesh = rsMesh; 34a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 35a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs = NULL; 36a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribAllocationIndex = NULL; 37a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mGLPrimitives = NULL; 38a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 39a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribCount = 0; 40a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 41a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 42a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukRsdMeshObj::~RsdMeshObj() { 43a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (mAttribs) { 44a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete[] mAttribs; 45a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete[] mAttribAllocationIndex; 46a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 47a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (mGLPrimitives) { 48a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete[] mGLPrimitives; 49a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 50a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 51a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 52a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukbool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) { 53a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted. 54a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Filter rs types accordingly 554a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk RsDataType dt = elem->mHal.state.fields[fieldIdx]->mHal.state.dataType; 56a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 && 57a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 && 58a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk dt != RS_TYPE_SIGNED_16) { 59a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return false; 60a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 61a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 62a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Now make sure they are not arrays 634a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk uint32_t arraySize = elem->mHal.state.fieldArraySizes[fieldIdx]; 64a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (arraySize != 1) { 65a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return false; 66a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 67a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 68a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return true; 69a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 70a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 71c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchoukbool RsdMeshObj::init(const Context *rsc) { 72a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 73c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk updateGLPrimitives(rsc); 74a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 75a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Count the number of gl attrs to initialize 76a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribCount = 0; 77a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 78a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement(); 794a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk for (uint32_t ct=0; ct < elem->mHal.state.fieldsCount; ct++) { 80a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (isValidGLComponent(elem, ct)) { 81a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribCount ++; 82a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 83a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 84a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 85a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 86a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (mAttribs) { 87a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete [] mAttribs; 88a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete [] mAttribAllocationIndex; 89a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs = NULL; 90a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribAllocationIndex = NULL; 91a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 92a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (!mAttribCount) { 93a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return false; 94a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 95a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 96a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs = new RsdVertexArray::Attrib[mAttribCount]; 97a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribAllocationIndex = new uint32_t[mAttribCount]; 98a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 99a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk uint32_t userNum = 0; 100a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 101a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement(); 1024a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk uint32_t stride = elem->mHal.state.elementSizeBytes; 1034a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) { 1044a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk const Element *f = elem->mHal.state.fields[fieldI]; 105a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 106a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (!isValidGLComponent(elem, fieldI)) { 107a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk continue; 108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 1104a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].size = f->mHal.state.vectorSize; 1114a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI]; 1124a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType); 1134a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32; 114a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs[userNum].stride = stride; 115a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk String8 tmp(RS_SHADER_ATTR); 1164a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk tmp.append(elem->mHal.state.fieldNames[fieldI]); 117a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs[userNum].name.setTo(tmp.string()); 118a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 119a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Remember which allocation this attribute came from 120a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribAllocationIndex[userNum] = ct; 121a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk userNum ++; 122a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 124a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 125a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return true; 126a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 127a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 1282382aba4a55c6ae74789c478eead8fbd96593321Jason Samsvoid RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, 129e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray size_t start, uint32_t len) const { 130a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) { 131c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh or parameters"); 132a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return; 133a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 134a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 135eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 136064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct]; 137a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 138a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (drv->uploadDeferred) { 139a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); 140a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 141eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams } 142eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams 143a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // update attributes with either buffer information or data ptr based on their current state 144a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t ct=0; ct < mAttribCount; ct++) { 145a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk uint32_t allocIndex = mAttribAllocationIndex[ct]; 146064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex]; 147eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv; 148eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams 149eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams if (drvAlloc->bufferID) { 150eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams mAttribs[ct].buffer = drvAlloc->bufferID; 151a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs[ct].ptr = NULL; 152a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } else { 153a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs[ct].buffer = 0; 154709a0978ae141198018ca9769f8d96292a8928e6Jason Sams mAttribs[ct].ptr = (const uint8_t*)alloc->mHal.drvState.lod[0].mallocPtr; 155a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 156a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 157a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 158a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk RsdVertexArray va(mAttribs, mAttribCount); 159c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk va.setup(rsc); 160a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 161064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex]; 162eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams if (idxAlloc) { 163eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; 164a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (drvAlloc->uploadDeferred) { 165a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); 166a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams 168eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams if (drvAlloc->bufferID) { 1692382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); 1702382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, 1712382aba4a55c6ae74789c478eead8fbd96593321Jason Sams (uint16_t *)(start * 2)); 172eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams } else { 1732382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, 0); 1742382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, 175709a0978ae141198018ca9769f8d96292a8928e6Jason Sams idxAlloc->mHal.drvState.lod[0].mallocPtr); 176eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams } 177a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } else { 1782382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glDrawArrays, mGLPrimitives[primIndex], start, len); 179a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 180a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 181c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange"); 182a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 183a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 184c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchoukvoid RsdMeshObj::updateGLPrimitives(const Context *rsc) { 185a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount]; 186a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) { 187064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk switch (mRSMesh->mHal.state.primitives[i]) { 188a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break; 189a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break; 190a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break; 191a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break; 192a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break; 193a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break; 194c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break; 195a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 196a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 197a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 198