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