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 2982e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang#include <string> 3082e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang 31e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Allocation; 32e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Context; 33e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Element; 34e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Mesh; 35a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 36a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukRsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) { 37a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mRSMesh = rsMesh; 38a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 3944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mAttribs = nullptr; 4044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mAttribAllocationIndex = nullptr; 4144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mGLPrimitives = nullptr; 42a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 43a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribCount = 0; 44a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 45a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 46a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukRsdMeshObj::~RsdMeshObj() { 47a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (mAttribs) { 48a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete[] mAttribs; 49a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete[] mAttribAllocationIndex; 50a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 51a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (mGLPrimitives) { 52a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete[] mGLPrimitives; 53a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 54a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 55a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 56a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukbool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) { 57a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted. 58a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Filter rs types accordingly 594a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk RsDataType dt = elem->mHal.state.fields[fieldIdx]->mHal.state.dataType; 60a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 && 61a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 && 62a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk dt != RS_TYPE_SIGNED_16) { 63a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return false; 64a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 65a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 66a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Now make sure they are not arrays 674a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk uint32_t arraySize = elem->mHal.state.fieldArraySizes[fieldIdx]; 68a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (arraySize != 1) { 69a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return false; 70a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 71a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 72a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return true; 73a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 74a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 75c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchoukbool RsdMeshObj::init(const Context *rsc) { 76a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 77c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk updateGLPrimitives(rsc); 78a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 79a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Count the number of gl attrs to initialize 80a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribCount = 0; 81a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 82a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement(); 834a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk for (uint32_t ct=0; ct < elem->mHal.state.fieldsCount; ct++) { 84a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (isValidGLComponent(elem, ct)) { 85a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribCount ++; 86a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 87a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 88a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 89a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 90a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (mAttribs) { 91a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete [] mAttribs; 92a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk delete [] mAttribAllocationIndex; 9344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mAttribs = nullptr; 9444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mAttribAllocationIndex = nullptr; 95a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 96a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (!mAttribCount) { 97a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return false; 98a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 99a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 100a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs = new RsdVertexArray::Attrib[mAttribCount]; 101a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribAllocationIndex = new uint32_t[mAttribCount]; 102a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 103a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk uint32_t userNum = 0; 104a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 105a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement(); 1064a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk uint32_t stride = elem->mHal.state.elementSizeBytes; 1074a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) { 1084a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk const Element *f = elem->mHal.state.fields[fieldI]; 109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (!isValidGLComponent(elem, fieldI)) { 111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk continue; 112a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 1144a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].size = f->mHal.state.vectorSize; 1154a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI]; 1164a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType); 1174a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32; 118a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs[userNum].stride = stride; 11982e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang std::string tmp(RS_SHADER_ATTR); 1204a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk tmp.append(elem->mHal.state.fieldNames[fieldI]); 12182e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang mAttribs[userNum].name = tmp; 122a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // Remember which allocation this attribute came from 124a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribAllocationIndex[userNum] = ct; 125a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk userNum ++; 126a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 127a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 128a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 129a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return true; 130a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 131a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 1322382aba4a55c6ae74789c478eead8fbd96593321Jason Samsvoid RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, 133e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray size_t start, uint32_t len) const { 134a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) { 135c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh or parameters"); 136a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk return; 137a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 138a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 139eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 140064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct]; 141a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 142a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (drv->uploadDeferred) { 143a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); 144a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 145eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams } 146eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams 147a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk // update attributes with either buffer information or data ptr based on their current state 148a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t ct=0; ct < mAttribCount; ct++) { 149a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk uint32_t allocIndex = mAttribAllocationIndex[ct]; 150064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex]; 151eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv; 152eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams 153eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams if (drvAlloc->bufferID) { 154eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams mAttribs[ct].buffer = drvAlloc->bufferID; 15544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mAttribs[ct].ptr = nullptr; 156a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } else { 157a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mAttribs[ct].buffer = 0; 158709a0978ae141198018ca9769f8d96292a8928e6Jason Sams mAttribs[ct].ptr = (const uint8_t*)alloc->mHal.drvState.lod[0].mallocPtr; 159a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 160a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 161a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 162a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk RsdVertexArray va(mAttribs, mAttribCount); 163c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk va.setup(rsc); 164a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 165064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex]; 166eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams if (idxAlloc) { 167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; 168a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (drvAlloc->uploadDeferred) { 169a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); 170a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 171eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams 172eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams if (drvAlloc->bufferID) { 1732382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); 1742382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, 1752382aba4a55c6ae74789c478eead8fbd96593321Jason Sams (uint16_t *)(start * 2)); 176eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams } else { 1772382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, 0); 1782382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, 179709a0978ae141198018ca9769f8d96292a8928e6Jason Sams idxAlloc->mHal.drvState.lod[0].mallocPtr); 180eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams } 181a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } else { 1822382aba4a55c6ae74789c478eead8fbd96593321Jason Sams RSD_CALL_GL(glDrawArrays, mGLPrimitives[primIndex], start, len); 183a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 184a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 185c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange"); 186a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 187a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk 188c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchoukvoid RsdMeshObj::updateGLPrimitives(const Context *rsc) { 189a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount]; 190a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) { 191064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk switch (mRSMesh->mHal.state.primitives[i]) { 192a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break; 193a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break; 194a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break; 195a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break; 196a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break; 197a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break; 198c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break; 199a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 200a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk } 201a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk} 202