rsProgramVertex.cpp revision cacee55b3217710cc01a3aa42ea447a779facc74
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#include <GLES2/gl2.h> 23#include <GLES2/gl2ext.h> 24 25using namespace android; 26using namespace android::renderscript; 27 28 29ProgramVertex::ProgramVertex(Context *rsc, bool texMat) : 30 Program(rsc) 31{ 32 mAllocFile = __FILE__; 33 mAllocLine = __LINE__; 34 mTextureMatrixEnable = texMat; 35 mLightCount = 0; 36 init(rsc); 37} 38 39ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, 40 uint32_t shaderLength, const uint32_t * params, 41 uint32_t paramLength) : 42 Program(rsc, shaderText, shaderLength, params, paramLength) 43{ 44 mAllocFile = __FILE__; 45 mAllocLine = __LINE__; 46 mTextureMatrixEnable = false; 47 mLightCount = 0; 48 49 init(rsc); 50} 51 52ProgramVertex::~ProgramVertex() 53{ 54} 55 56static void logMatrix(const char *txt, const float *f) 57{ 58 LOGV("Matrix %s, %p", txt, f); 59 LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[0], f[4], f[8], f[12]); 60 LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[1], f[5], f[9], f[13]); 61 LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[2], f[6], f[10], f[14]); 62 LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[3], f[7], f[11], f[15]); 63} 64 65void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) 66{ 67 if ((state->mLast.get() == this) && !mDirty) { 68 return; 69 } 70 state->mLast.set(this); 71 72 const float *f = static_cast<const float *>(mConstants->getPtr()); 73 74 glMatrixMode(GL_TEXTURE); 75 if (mTextureMatrixEnable) { 76 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); 77 } else { 78 glLoadIdentity(); 79 } 80 81 glMatrixMode(GL_MODELVIEW); 82 glLoadIdentity(); 83 if (mLightCount) { 84 int v = 0; 85 glEnable(GL_LIGHTING); 86 glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v); 87 for (uint32_t ct = 0; ct < mLightCount; ct++) { 88 const Light *l = mLights[ct].get(); 89 glEnable(GL_LIGHT0 + ct); 90 l->setupGL(ct); 91 } 92 for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) { 93 glDisable(GL_LIGHT0 + ct); 94 } 95 } else { 96 glDisable(GL_LIGHTING); 97 } 98 99 if (!f) { 100 LOGE("Must bind constants to vertex program"); 101 } 102 103 glMatrixMode(GL_PROJECTION); 104 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 105 glMatrixMode(GL_MODELVIEW); 106 glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); 107 108 mDirty = false; 109} 110 111void ProgramVertex::loadShader(Context *rsc) { 112 Program::loadShader(rsc, GL_VERTEX_SHADER); 113} 114 115void ProgramVertex::createShader() 116{ 117 mShader.setTo(""); 118 119 for (uint32_t ct=0; ct < mUniformCount; ct++) { 120 mShader.append("uniform mat4 "); 121 mShader.append(mUniformNames[ct]); 122 mShader.append(";\n"); 123 } 124 125 mShader.append("varying vec4 varColor;\n"); 126 mShader.append("varying vec4 varTex0;\n"); 127 128 if (mUserShader.length() > 1) { 129 for (uint32_t ct=0; ct < mInputCount; ct++) { 130 const Element *e = mInputElements[ct].get(); 131 for (uint32_t field=0; field < e->getFieldCount(); field++) { 132 const Element *f = e->getField(field); 133 134 // Cannot be complex 135 rsAssert(!f->getFieldCount()); 136 switch(f->getComponent().getVectorSize()) { 137 case 1: mShader.append("attribute float ATTRIB_"); break; 138 case 2: mShader.append("attribute vec2 ATTRIB_"); break; 139 case 3: mShader.append("attribute vec3 ATTRIB_"); break; 140 case 4: mShader.append("attribute vec4 ATTRIB_"); break; 141 default: 142 rsAssert(0); 143 } 144 145 mShader.append(e->getFieldName(field)); 146 mShader.append(";\n"); 147 } 148 } 149 mShader.append(mUserShader); 150 } else { 151 for (uint32_t ct=VertexArray::POSITION; ct < mAttribCount; ct++) { 152 mShader.append("attribute vec4 "); 153 mShader.append(mAttribNames[ct]); 154 mShader.append(";\n"); 155 } 156 157 mShader.append("void main() {\n"); 158 mShader.append(" gl_Position = uni_MVP * ATTRIB_Position;\n"); 159 mShader.append(" gl_PointSize = ATTRIB_PointSize.x;\n"); 160 161 mShader.append(" varColor = ATTRIB_Color;\n"); 162 if (mTextureMatrixEnable) { 163 mShader.append(" varTex0 = uni_TexMatrix * ATTRIB_Texture;\n"); 164 } else { 165 mShader.append(" varTex0 = ATTRIB_Texture;\n"); 166 } 167 //mShader.append(" pos.x = pos.x / 480.0;\n"); 168 //mShader.append(" pos.y = pos.y / 800.0;\n"); 169 //mShader.append(" gl_Position = pos;\n"); 170 mShader.append("}\n"); 171 } 172} 173 174void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc) 175{ 176 //LOGE("sgl2 vtx1 %x", glGetError()); 177 if ((state->mLast.get() == this) && !mDirty) { 178 //return; 179 } 180 181 glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]); 182 183 const float *f = static_cast<const float *>(mConstants->getPtr()); 184 185 Matrix mvp; 186 mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 187 Matrix t; 188 t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); 189 mvp.multiply(&t); 190 191 glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m); 192 if (mTextureMatrixEnable) { 193 glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE, 194 &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); 195 } 196 197 state->mLast.set(this); 198 rsc->checkError("ProgramVertex::setupGL2"); 199} 200 201void ProgramVertex::addLight(const Light *l) 202{ 203 if (mLightCount < MAX_LIGHTS) { 204 mLights[mLightCount].set(l); 205 mLightCount++; 206 } 207} 208 209void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const 210{ 211 float *f = static_cast<float *>(mConstants->getPtr()); 212 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); 213 mDirty = true; 214} 215 216void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const 217{ 218 float *f = static_cast<float *>(mConstants->getPtr()); 219 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); 220 mDirty = true; 221} 222 223void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const 224{ 225 float *f = static_cast<float *>(mConstants->getPtr()); 226 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); 227 mDirty = true; 228} 229 230void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const 231{ 232 float *f = static_cast<float *>(mConstants->getPtr()); 233 Matrix mvp; 234 mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], 235 (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 236 mvp.vectorMultiply(v4out, v3in); 237} 238 239void ProgramVertex::initAddUserAttrib(const Element *e) 240{ 241 rsAssert(e->getFieldCount()); 242 for (uint32_t ct=0; ct < e->getFieldCount(); ct++) { 243 const Element *ce = e->getField(ct); 244 if (ce->getFieldCount()) { 245 initAddUserAttrib(ce); 246 } else { 247 String8 tmp("ATTRIB_"); 248 tmp.append(e->getFieldName(ct)); 249 mAttribNames[mAttribCount].setTo(tmp.string()); 250 mAttribCount++; 251 } 252 } 253} 254 255void ProgramVertex::init(Context *rsc) 256{ 257 if (mUserShader.size() > 0) { 258 mAttribCount = 0; 259 for (uint32_t ct=0; ct < mInputCount; ct++) { 260 initAddUserAttrib(mInputElements[ct].get()); 261 } 262 } else { 263 mAttribCount = 5; 264 mAttribNames[0].setTo("ATTRIB_Position"); 265 mAttribNames[1].setTo("ATTRIB_Color"); 266 mAttribNames[2].setTo("ATTRIB_Normal"); 267 mAttribNames[3].setTo("ATTRIB_PointSize"); 268 mAttribNames[4].setTo("ATTRIB_Texture"); 269 } 270 271 mUniformCount = 2; 272 mUniformNames[0].setTo("uni_MVP"); 273 mUniformNames[1].setTo("uni_TexMatrix"); 274 275 createShader(); 276} 277 278 279/////////////////////////////////////////////////////////////////////// 280 281ProgramVertexState::ProgramVertexState() 282{ 283} 284 285ProgramVertexState::~ProgramVertexState() 286{ 287} 288 289void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) 290{ 291 RsElement e = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); 292 293 rsi_TypeBegin(rsc, e); 294 rsi_TypeAdd(rsc, RS_DIMENSION_X, 48); 295 mAllocType.set((Type *)rsi_TypeCreate(rsc)); 296 297 ProgramVertex *pv = new ProgramVertex(rsc, false); 298 Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get()); 299 mDefaultAlloc.set(alloc); 300 mDefault.set(pv); 301 pv->init(rsc); 302 pv->bindAllocation(alloc); 303 304 color[0] = 1.f; 305 color[1] = 1.f; 306 color[2] = 1.f; 307 color[3] = 1.f; 308 309 updateSize(rsc, w, h); 310} 311 312void ProgramVertexState::updateSize(Context *rsc, int32_t w, int32_t h) 313{ 314 Matrix m; 315 m.loadOrtho(0,w, h,0, -1,1); 316 mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4); 317 318 m.loadIdentity(); 319 mDefaultAlloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4); 320} 321 322void ProgramVertexState::deinit(Context *rsc) 323{ 324 mDefaultAlloc.clear(); 325 mDefault.clear(); 326 mAllocType.clear(); 327 mLast.clear(); 328} 329 330 331namespace android { 332namespace renderscript { 333 334 335RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, bool texMat) 336{ 337 ProgramVertex *pv = new ProgramVertex(rsc, texMat); 338 pv->incUserRef(); 339 return pv; 340} 341 342RsProgramVertex rsi_ProgramVertexCreate2(Context *rsc, const char * shaderText, 343 uint32_t shaderLength, const uint32_t * params, 344 uint32_t paramLength) 345{ 346 ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength); 347 pv->incUserRef(); 348 return pv; 349} 350 351 352} 353} 354