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 #include "rsProgramVertex.h" 19 20 #include <GLES/gl.h> 21 #include <GLES/glext.h> 22 23 using namespace android; 24 using namespace android::renderscript; 25 26 ProgramVertex(Context * rsc,Element * in,Element * out)27 ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) : 28 Program(rsc, in, out) 29 { 30 mAllocFile = __FILE__; 31 mAllocLine = __LINE__; 32 mTextureMatrixEnable = false; 33 mLightCount = 0; 34 } 35 ~ProgramVertex()36 ProgramVertex::~ProgramVertex() 37 { 38 } 39 logMatrix(const char * txt,const float * f)40 static void logMatrix(const char *txt, const float *f) 41 { 42 LOGV("Matrix %s, %p", txt, f); 43 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[0], f[4], f[8], f[12]); 44 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[1], f[5], f[9], f[13]); 45 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[2], f[6], f[10], f[14]); 46 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]); 47 } 48 setupGL(const Context * rsc,ProgramVertexState * state)49 void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) 50 { 51 if ((state->mLast.get() == this) && !mDirty) { 52 return; 53 } 54 state->mLast.set(this); 55 56 const float *f = static_cast<const float *>(mConstants->getPtr()); 57 58 glMatrixMode(GL_TEXTURE); 59 if (mTextureMatrixEnable) { 60 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); 61 } else { 62 glLoadIdentity(); 63 } 64 65 glMatrixMode(GL_MODELVIEW); 66 glLoadIdentity(); 67 if (mLightCount) { 68 int v = 0; 69 glEnable(GL_LIGHTING); 70 glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v); 71 for (uint32_t ct = 0; ct < mLightCount; ct++) { 72 const Light *l = mLights[ct].get(); 73 glEnable(GL_LIGHT0 + ct); 74 l->setupGL(ct); 75 } 76 for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) { 77 glDisable(GL_LIGHT0 + ct); 78 } 79 } else { 80 glDisable(GL_LIGHTING); 81 } 82 83 if (!f) { 84 LOGE("Must bind constants to vertex program"); 85 } 86 87 glMatrixMode(GL_PROJECTION); 88 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 89 glMatrixMode(GL_MODELVIEW); 90 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); 91 92 mDirty = false; 93 } 94 addLight(const Light * l)95 void ProgramVertex::addLight(const Light *l) 96 { 97 if (mLightCount < MAX_LIGHTS) { 98 mLights[mLightCount].set(l); 99 mLightCount++; 100 } 101 } 102 setProjectionMatrix(const rsc_Matrix * m) const103 void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const 104 { 105 float *f = static_cast<float *>(mConstants->getPtr()); 106 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); 107 mDirty = true; 108 } 109 setModelviewMatrix(const rsc_Matrix * m) const110 void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const 111 { 112 float *f = static_cast<float *>(mConstants->getPtr()); 113 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); 114 mDirty = true; 115 } 116 setTextureMatrix(const rsc_Matrix * m) const117 void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const 118 { 119 float *f = static_cast<float *>(mConstants->getPtr()); 120 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); 121 mDirty = true; 122 } 123 transformToScreen(const Context * rsc,float * v4out,const float * v3in) const124 void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const 125 { 126 float *f = static_cast<float *>(mConstants->getPtr()); 127 Matrix mvp; 128 mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], 129 (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 130 mvp.vectorMultiply(v4out, v3in); 131 } 132 ProgramVertexState()133 ProgramVertexState::ProgramVertexState() 134 { 135 mPV = NULL; 136 } 137 ~ProgramVertexState()138 ProgramVertexState::~ProgramVertexState() 139 { 140 delete mPV; 141 } 142 init(Context * rsc,int32_t w,int32_t h)143 void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) 144 { 145 rsi_ElementBegin(rsc); 146 rsi_ElementAdd(rsc, RS_KIND_USER, RS_TYPE_FLOAT, false, 32, NULL); 147 RsElement e = rsi_ElementCreate(rsc); 148 149 rsi_TypeBegin(rsc, e); 150 rsi_TypeAdd(rsc, RS_DIMENSION_X, 48); 151 mAllocType.set((Type *)rsi_TypeCreate(rsc)); 152 153 ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL); 154 Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get()); 155 mDefaultAlloc.set(alloc); 156 mDefault.set(pv); 157 158 pv->bindAllocation(alloc); 159 160 updateSize(rsc, w, h); 161 } 162 updateSize(Context * rsc,int32_t w,int32_t h)163 void ProgramVertexState::updateSize(Context *rsc, int32_t w, int32_t h) 164 { 165 Matrix m; 166 m.loadOrtho(0,w, h,0, -1,1); 167 mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4); 168 169 m.loadIdentity(); 170 mDefaultAlloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4); 171 } 172 deinit(Context * rsc)173 void ProgramVertexState::deinit(Context *rsc) 174 { 175 mDefaultAlloc.clear(); 176 mDefault.clear(); 177 mAllocType.clear(); 178 mLast.clear(); 179 delete mPV; 180 mPV = NULL; 181 } 182 183 184 namespace android { 185 namespace renderscript { 186 rsi_ProgramVertexBegin(Context * rsc,RsElement in,RsElement out)187 void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) 188 { 189 delete rsc->mStateVertex.mPV; 190 rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out); 191 } 192 rsi_ProgramVertexCreate(Context * rsc)193 RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) 194 { 195 ProgramVertex *pv = rsc->mStateVertex.mPV; 196 pv->incUserRef(); 197 rsc->mStateVertex.mPV = 0; 198 return pv; 199 } 200 rsi_ProgramVertexBindAllocation(Context * rsc,RsProgramVertex vpgm,RsAllocation constants)201 void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants) 202 { 203 ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); 204 pv->bindAllocation(static_cast<Allocation *>(constants)); 205 } 206 rsi_ProgramVertexSetTextureMatrixEnable(Context * rsc,bool enable)207 void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) 208 { 209 rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); 210 } 211 rsi_ProgramVertexAddLight(Context * rsc,RsLight light)212 void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) 213 { 214 rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); 215 } 216 217 218 } 219 } 220