rsProgramVertex.cpp revision e9ad9a719dc66437ddf021d13e6ca736a23b5413
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 23using namespace android; 24using namespace android::renderscript; 25 26 27ProgramVertex::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 36ProgramVertex::~ProgramVertex() 37{ 38} 39 40static 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 49void 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 95void ProgramVertex::addLight(const Light *l) 96{ 97 if (mLightCount < MAX_LIGHTS) { 98 mLights[mLightCount].set(l); 99 mLightCount++; 100 } 101} 102 103void 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 110void 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 117void 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 124void 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 133ProgramVertexState::ProgramVertexState() 134{ 135 mPV = NULL; 136} 137 138ProgramVertexState::~ProgramVertexState() 139{ 140 delete mPV; 141} 142 143void 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 Matrix m; 161 m.loadOrtho(0,w, h,0, -1,1); 162 alloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4); 163 164 m.loadIdentity(); 165 alloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4); 166} 167 168void ProgramVertexState::deinit(Context *rsc) 169{ 170 mDefaultAlloc.clear(); 171 mDefault.clear(); 172 mAllocType.clear(); 173 mLast.clear(); 174 delete mPV; 175 mPV = NULL; 176} 177 178 179namespace android { 180namespace renderscript { 181 182void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) 183{ 184 delete rsc->mStateVertex.mPV; 185 rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out); 186} 187 188RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) 189{ 190 ProgramVertex *pv = rsc->mStateVertex.mPV; 191 pv->incUserRef(); 192 rsc->mStateVertex.mPV = 0; 193 return pv; 194} 195 196void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants) 197{ 198 ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); 199 pv->bindAllocation(static_cast<Allocation *>(constants)); 200} 201 202void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) 203{ 204 rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); 205} 206 207void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) 208{ 209 rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); 210} 211 212 213} 214} 215