rsProgramVertex.cpp revision e514b45de8561fbc6ef6770845102ca10b0a69d7
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 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(const Context *rsc, 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 = 0; 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 rsi_ElementBegin(rsc); 137 rsi_ElementAdd(rsc, RS_KIND_USER, RS_TYPE_FLOAT, false, 32, NULL); 138 RsElement e = rsi_ElementCreate(rsc); 139 140 rsi_TypeBegin(rsc, e); 141 rsi_TypeAdd(rsc, RS_DIMENSION_X, 48); 142 mAllocType = rsi_TypeCreate(rsc); 143 144 ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL); 145 Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType); 146 mDefaultAlloc.set(alloc); 147 mDefault.set(pv); 148 149 pv->bindAllocation(alloc); 150 151 Matrix m; 152 m.loadOrtho(0,w, h,0, -1,1); 153 alloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4); 154 155 m.loadIdentity(); 156 alloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4); 157} 158 159 160namespace android { 161namespace renderscript { 162 163void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) 164{ 165 delete rsc->mStateVertex.mPV; 166 rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out); 167} 168 169RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) 170{ 171 ProgramVertex *pv = rsc->mStateVertex.mPV; 172 pv->incUserRef(); 173 rsc->mStateVertex.mPV = 0; 174 return pv; 175} 176 177void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants) 178{ 179 ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); 180 pv->bindAllocation(static_cast<Allocation *>(constants)); 181} 182 183void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) 184{ 185 rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); 186} 187 188void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) 189{ 190 rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); 191} 192 193 194} 195} 196