1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "rsContext.h" 18 19 using namespace android; 20 using namespace android::renderscript; 21 22 #include <GLES/gl.h> 23 #include <GLES/glext.h> 24 25 SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc) 26 { 27 mAllocFile = __FILE__; 28 mAllocLine = __LINE__; 29 } 30 31 SimpleMesh::~SimpleMesh() 32 { 33 delete[] mVertexTypes; 34 delete[] mVertexBuffers; 35 } 36 37 void SimpleMesh::render(Context *rsc) const 38 { 39 if (mPrimitiveType.get()) { 40 renderRange(rsc, 0, mPrimitiveType->getDimX()); 41 return; 42 } 43 44 if (mIndexType.get()) { 45 renderRange(rsc, 0, mIndexType->getDimX()); 46 return; 47 } 48 49 renderRange(rsc, 0, mVertexTypes[0]->getDimX()); 50 } 51 52 void SimpleMesh::renderRange(Context *rsc, uint32_t start, uint32_t len) const 53 { 54 if (len < 1) { 55 return; 56 } 57 58 rsc->checkError("SimpleMesh::renderRange 1"); 59 VertexArray va; 60 if (rsc->checkVersion2_0()) { 61 for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { 62 mVertexBuffers[ct]->uploadCheck(rsc); 63 va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID()); 64 mVertexTypes[ct]->enableGLVertexBuffer2(&va); 65 } 66 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache); 67 } else { 68 for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { 69 mVertexBuffers[ct]->uploadCheck(rsc); 70 va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID()); 71 mVertexTypes[ct]->enableGLVertexBuffer(&va); 72 } 73 va.setupGL(rsc, 0); 74 } 75 76 rsc->checkError("SimpleMesh::renderRange 2"); 77 if (mIndexType.get()) { 78 mIndexBuffer->uploadCheck(rsc); 79 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID()); 80 glDrawElements(mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2)); 81 } else { 82 glDrawArrays(mGLPrimitive, start, len); 83 } 84 85 rsc->checkError("SimpleMesh::renderRange"); 86 } 87 88 void SimpleMesh::uploadAll(Context *rsc) 89 { 90 for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { 91 if (mVertexBuffers[ct].get()) { 92 mVertexBuffers[ct]->deferedUploadToBufferObject(rsc); 93 } 94 } 95 if (mIndexBuffer.get()) { 96 mIndexBuffer->deferedUploadToBufferObject(rsc); 97 } 98 if (mPrimitiveBuffer.get()) { 99 mPrimitiveBuffer->deferedUploadToBufferObject(rsc); 100 } 101 rsc->checkError("SimpleMesh::uploadAll"); 102 } 103 104 105 SimpleMeshContext::SimpleMeshContext() 106 { 107 } 108 109 SimpleMeshContext::~SimpleMeshContext() 110 { 111 } 112 113 114 namespace android { 115 namespace renderscript { 116 117 118 RsSimpleMesh rsi_SimpleMeshCreate(Context *rsc, RsType prim, RsType idx, RsType *vtx, uint32_t vtxCount, uint32_t primType) 119 { 120 SimpleMesh *sm = new SimpleMesh(rsc); 121 sm->incUserRef(); 122 123 sm->mIndexType.set((const Type *)idx); 124 sm->mPrimitiveType.set((const Type *)prim); 125 126 sm->mVertexTypeCount = vtxCount; 127 sm->mVertexTypes = new ObjectBaseRef<const Type>[vtxCount]; 128 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount]; 129 for (uint32_t ct=0; ct < vtxCount; ct++) { 130 sm->mVertexTypes[ct].set((const Type *)vtx[ct]); 131 } 132 133 sm->mPrimitive = (RsPrimitive)primType; 134 switch(sm->mPrimitive) { 135 case RS_PRIMITIVE_POINT: sm->mGLPrimitive = GL_POINTS; break; 136 case RS_PRIMITIVE_LINE: sm->mGLPrimitive = GL_LINES; break; 137 case RS_PRIMITIVE_LINE_STRIP: sm->mGLPrimitive = GL_LINE_STRIP; break; 138 case RS_PRIMITIVE_TRIANGLE: sm->mGLPrimitive = GL_TRIANGLES; break; 139 case RS_PRIMITIVE_TRIANGLE_STRIP: sm->mGLPrimitive = GL_TRIANGLE_STRIP; break; 140 case RS_PRIMITIVE_TRIANGLE_FAN: sm->mGLPrimitive = GL_TRIANGLE_FAN; break; 141 } 142 return sm; 143 } 144 145 void rsi_SimpleMeshBindVertex(Context *rsc, RsSimpleMesh mv, RsAllocation va, uint32_t slot) 146 { 147 SimpleMesh *sm = static_cast<SimpleMesh *>(mv); 148 rsAssert(slot < sm->mVertexTypeCount); 149 150 sm->mVertexBuffers[slot].set((Allocation *)va); 151 } 152 153 void rsi_SimpleMeshBindIndex(Context *rsc, RsSimpleMesh mv, RsAllocation va) 154 { 155 SimpleMesh *sm = static_cast<SimpleMesh *>(mv); 156 sm->mIndexBuffer.set((Allocation *)va); 157 } 158 159 void rsi_SimpleMeshBindPrimitive(Context *rsc, RsSimpleMesh mv, RsAllocation va) 160 { 161 SimpleMesh *sm = static_cast<SimpleMesh *>(mv); 162 sm->mPrimitiveBuffer.set((Allocation *)va); 163 } 164 165 166 167 168 }} 169 170