rsProgramVertex.cpp revision cfb1d11ce6826fce7241d316d8b7dcab661f63a6
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(Element *in, Element *out) : 28 Program(in, out) 29{ 30 mTextureMatrixEnable = false; 31 mLightCount = 0; 32} 33 34ProgramVertex::~ProgramVertex() 35{ 36} 37 38static void logMatrix(const char *txt, const float *f) 39{ 40 LOGV("Matrix %s, %p", txt, f); 41 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[0], f[4], f[8], f[12]); 42 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[1], f[5], f[9], f[13]); 43 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[2], f[6], f[10], f[14]); 44 LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]); 45} 46 47void ProgramVertex::setupGL(ProgramVertexState *state) 48{ 49 if ((state->mLast.get() == this) && !mDirty) { 50 return; 51 } 52 state->mLast.set(this); 53 54 const float *f = static_cast<const float *>(mConstants->getPtr()); 55 56 glMatrixMode(GL_TEXTURE); 57 if (mTextureMatrixEnable) { 58 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); 59 } else { 60 glLoadIdentity(); 61 } 62 63 glMatrixMode(GL_MODELVIEW); 64 glLoadIdentity(); 65 if (mLightCount) { 66 int v = 1; 67 glEnable(GL_LIGHTING); 68 glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v); 69 for (uint32_t ct = 0; ct < mLightCount; ct++) { 70 const Light *l = mLights[ct].get(); 71 glEnable(GL_LIGHT0 + ct); 72 l->setupGL(ct); 73 } 74 for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) { 75 glDisable(GL_LIGHT0 + ct); 76 } 77 } else { 78 glDisable(GL_LIGHTING); 79 } 80 81 if (!f) { 82 LOGE("Must bind constants to vertex program"); 83 } 84 85 glMatrixMode(GL_PROJECTION); 86 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 87 glMatrixMode(GL_MODELVIEW); 88 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); 89 90 mDirty = false; 91} 92 93void ProgramVertex::addLight(const Light *l) 94{ 95 if (mLightCount < MAX_LIGHTS) { 96 mLights[mLightCount].set(l); 97 mLightCount++; 98 } 99} 100 101void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const 102{ 103 float *f = static_cast<float *>(mConstants->getPtr()); 104 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); 105 mDirty = true; 106} 107 108void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const 109{ 110 float *f = static_cast<float *>(mConstants->getPtr()); 111 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); 112 mDirty = true; 113} 114 115void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const 116{ 117 float *f = static_cast<float *>(mConstants->getPtr()); 118 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); 119 mDirty = true; 120} 121 122 123 124ProgramVertexState::ProgramVertexState() 125{ 126 mPV = NULL; 127} 128 129ProgramVertexState::~ProgramVertexState() 130{ 131 delete mPV; 132} 133 134void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) 135{ 136 ProgramVertex *pv = new ProgramVertex(NULL, NULL); 137 Allocation *alloc = (Allocation *) 138 rsi_AllocationCreatePredefSized(rsc, RS_ELEMENT_USER_FLOAT, 48); 139 mDefaultAlloc.set(alloc); 140 mDefault.set(pv); 141 142 pv->bindAllocation(alloc); 143 144 Matrix m; 145 m.loadOrtho(0,w, h,0, -1,1); 146 alloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0]); 147 148 m.loadIdentity(); 149 alloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0]); 150} 151 152 153namespace android { 154namespace renderscript { 155 156void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) 157{ 158 delete rsc->mStateVertex.mPV; 159 rsc->mStateVertex.mPV = new ProgramVertex((Element *)in, (Element *)out); 160} 161 162RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) 163{ 164 ProgramVertex *pv = rsc->mStateVertex.mPV; 165 pv->incRef(); 166 rsc->mStateVertex.mPV = 0; 167 return pv; 168} 169 170void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants) 171{ 172 ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); 173 pv->bindAllocation(static_cast<Allocation *>(constants)); 174} 175 176void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) 177{ 178 rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); 179} 180 181void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) 182{ 183 rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); 184} 185 186 187} 188} 189