diff options
Diffstat (limited to 'libs/rs/rsProgramVertex.cpp')
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 292 |
1 files changed, 251 insertions, 41 deletions
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 68f589f..28f13d4 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -19,18 +19,34 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; -ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) : - Program(rsc, in, out) +ProgramVertex::ProgramVertex(Context *rsc, bool texMat) : + Program(rsc) +{ + mAllocFile = __FILE__; + mAllocLine = __LINE__; + mTextureMatrixEnable = texMat; + mLightCount = 0; + init(rsc); +} + +ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength) : + Program(rsc, shaderText, shaderLength, params, paramLength) { mAllocFile = __FILE__; mAllocLine = __LINE__; mTextureMatrixEnable = false; mLightCount = 0; + + init(rsc); } ProgramVertex::~ProgramVertex() @@ -40,10 +56,10 @@ ProgramVertex::~ProgramVertex() static void logMatrix(const char *txt, const float *f) { LOGV("Matrix %s, %p", txt, f); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[0], f[4], f[8], f[12]); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[1], f[5], f[9], f[13]); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[2], f[6], f[10], f[14]); - LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[0], f[4], f[8], f[12]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[1], f[5], f[9], f[13]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[2], f[6], f[10], f[14]); + LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[3], f[7], f[11], f[15]); } void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) @@ -53,7 +69,7 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) } state->mLast.set(this); - const float *f = static_cast<const float *>(mConstants->getPtr()); + const float *f = static_cast<const float *>(mConstants[0]->getPtr()); glMatrixMode(GL_TEXTURE); if (mTextureMatrixEnable) { @@ -92,6 +108,172 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) mDirty = false; } +void ProgramVertex::loadShader(Context *rsc) { + Program::loadShader(rsc, GL_VERTEX_SHADER); +} + +void ProgramVertex::createShader() +{ + mShader.setTo(""); + + mShader.append("varying vec4 varColor;\n"); + mShader.append("varying vec4 varTex0;\n"); + + if (mUserShader.length() > 1) { + mShader.append("uniform mat4 "); + mShader.append(mUniformNames[0]); + mShader.append(";\n"); + + for (uint32_t ct=0; ct < mConstantCount; ct++) { + const Element *e = mConstantTypes[ct]->getElement(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + + // Cannot be complex + rsAssert(!f->getFieldCount()); + switch(f->getComponent().getVectorSize()) { + case 1: mShader.append("uniform float UNI_"); break; + case 2: mShader.append("uniform vec2 UNI_"); break; + case 3: mShader.append("uniform vec3 UNI_"); break; + case 4: mShader.append("uniform vec4 UNI_"); break; + default: + rsAssert(0); + } + + mShader.append(e->getFieldName(field)); + mShader.append(";\n"); + } + } + + + for (uint32_t ct=0; ct < mInputCount; ct++) { + const Element *e = mInputElements[ct].get(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + + // Cannot be complex + rsAssert(!f->getFieldCount()); + switch(f->getComponent().getVectorSize()) { + case 1: mShader.append("attribute float ATTRIB_"); break; + case 2: mShader.append("attribute vec2 ATTRIB_"); break; + case 3: mShader.append("attribute vec3 ATTRIB_"); break; + case 4: mShader.append("attribute vec4 ATTRIB_"); break; + default: + rsAssert(0); + } + + mShader.append(e->getFieldName(field)); + mShader.append(";\n"); + } + } + mShader.append(mUserShader); + } else { + mShader.append("attribute vec4 ATTRIB_LegacyPosition;\n"); + mShader.append("attribute vec4 ATTRIB_LegacyColor;\n"); + mShader.append("attribute vec3 ATTRIB_LegacyNormal;\n"); + mShader.append("attribute float ATTRIB_LegacyPointSize;\n"); + mShader.append("attribute vec4 ATTRIB_LegacyTexture;\n"); + + for (uint32_t ct=0; ct < mUniformCount; ct++) { + mShader.append("uniform mat4 "); + mShader.append(mUniformNames[ct]); + mShader.append(";\n"); + } + + mShader.append("void main() {\n"); + mShader.append(" gl_Position = UNI_MVP * ATTRIB_LegacyPosition;\n"); + mShader.append(" gl_PointSize = ATTRIB_LegacyPointSize;\n"); + + mShader.append(" varColor = ATTRIB_LegacyColor;\n"); + if (mTextureMatrixEnable) { + mShader.append(" varTex0 = UNI_TexMatrix * ATTRIB_LegacyTexture;\n"); + } else { + mShader.append(" varTex0 = ATTRIB_LegacyTexture;\n"); + } + //mShader.append(" pos.x = pos.x / 480.0;\n"); + //mShader.append(" pos.y = pos.y / 800.0;\n"); + //mShader.append(" gl_Position = pos;\n"); + mShader.append("}\n"); + } +} + +void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc) +{ + //LOGE("sgl2 vtx1 %x", glGetError()); + if ((state->mLast.get() == this) && !mDirty) { + //return; + } + + rsc->checkError("ProgramVertex::setupGL2 start"); + glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]); + + const float *f = static_cast<const float *>(mConstants[0]->getPtr()); + + Matrix mvp; + mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); + Matrix t; + t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); + mvp.multiply(&t); + + glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m); + if (mTextureMatrixEnable) { + glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE, + &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); + } + + rsc->checkError("ProgramVertex::setupGL2 begin uniforms"); + uint32_t uidx = 1; + for (uint32_t ct=0; ct < mConstantCount; ct++) { + Allocation *alloc = mConstants[ct+1].get(); + if (!alloc) { + continue; + } + + const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr()); + const Element *e = mConstantTypes[ct]->getElement(); + for (uint32_t field=0; field < e->getFieldCount(); field++) { + const Element *f = e->getField(field); + uint32_t offset = e->getFieldOffsetBytes(field); + int32_t slot = sc->vtxUniformSlot(uidx); + + const float *fd = reinterpret_cast<const float *>(&data[offset]); + + //LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i", slot, offset, ct, field, uidx); + if (slot >= 0) { + switch(f->getComponent().getVectorSize()) { + case 1: + //LOGE("Uniform 1 = %f", fd[0]); + glUniform1fv(slot, 1, fd); + break; + case 2: + //LOGE("Uniform 2 = %f %f", fd[0], fd[1]); + glUniform2fv(slot, 1, fd); + break; + case 3: + //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]); + glUniform3fv(slot, 1, fd); + break; + case 4: + //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]); + glUniform4fv(slot, 1, fd); + break; + default: + rsAssert(0); + } + } + uidx ++; + } + } + + for (uint32_t ct=0; ct < mConstantCount; ct++) { + uint32_t glSlot = sc->vtxUniformSlot(ct + 1); + + } + + state->mLast.set(this); + rsc->checkError("ProgramVertex::setupGL2"); +} + void ProgramVertex::addLight(const Light *l) { if (mLightCount < MAX_LIGHTS) { @@ -102,60 +284,103 @@ void ProgramVertex::addLight(const Light *l) void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; } void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; } void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; } void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const { - float *f = static_cast<float *>(mConstants->getPtr()); + float *f = static_cast<float *>(mConstants[0]->getPtr()); Matrix mvp; mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); mvp.vectorMultiply(v4out, v3in); } +void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix) +{ + rsAssert(e->getFieldCount()); + for (uint32_t ct=0; ct < e->getFieldCount(); ct++) { + const Element *ce = e->getField(ct); + if (ce->getFieldCount()) { + initAddUserElement(ce, names, count, prefix); + } else { + String8 tmp(prefix); + tmp.append(e->getFieldName(ct)); + names[*count].setTo(tmp.string()); + (*count)++; + } + } +} + + +void ProgramVertex::init(Context *rsc) +{ + mAttribCount = 0; + if (mUserShader.size() > 0) { + for (uint32_t ct=0; ct < mInputCount; ct++) { + initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_"); + } + + mUniformCount = 1; + mUniformNames[0].setTo("UNI_MVP"); + for (uint32_t ct=0; ct < mConstantCount; ct++) { + initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_"); + } + } else { + mUniformCount = 2; + mUniformNames[0].setTo("UNI_MVP"); + mUniformNames[1].setTo("UNI_TexMatrix"); + } + + createShader(); +} + + +/////////////////////////////////////////////////////////////////////// + ProgramVertexState::ProgramVertexState() { - mPV = NULL; } ProgramVertexState::~ProgramVertexState() { - delete mPV; } void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) { - rsi_ElementBegin(rsc); - rsi_ElementAdd(rsc, RS_KIND_USER, RS_TYPE_FLOAT, false, 32, NULL); - RsElement e = rsi_ElementCreate(rsc); + RsElement e = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); rsi_TypeBegin(rsc, e); rsi_TypeAdd(rsc, RS_DIMENSION_X, 48); mAllocType.set((Type *)rsi_TypeCreate(rsc)); - ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL); + ProgramVertex *pv = new ProgramVertex(rsc, false); Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get()); mDefaultAlloc.set(alloc); mDefault.set(pv); + pv->init(rsc); + pv->bindAllocation(alloc, 0); - pv->bindAllocation(alloc); + color[0] = 1.f; + color[1] = 1.f; + color[2] = 1.f; + color[3] = 1.f; updateSize(rsc, w, h); } @@ -176,42 +401,27 @@ void ProgramVertexState::deinit(Context *rsc) mDefault.clear(); mAllocType.clear(); mLast.clear(); - delete mPV; - mPV = NULL; } namespace android { namespace renderscript { -void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) -{ - delete rsc->mStateVertex.mPV; - rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out); -} -RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) +RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, bool texMat) { - ProgramVertex *pv = rsc->mStateVertex.mPV; + ProgramVertex *pv = new ProgramVertex(rsc, texMat); pv->incUserRef(); - rsc->mStateVertex.mPV = 0; return pv; } -void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants) +RsProgramVertex rsi_ProgramVertexCreate2(Context *rsc, const char * shaderText, + uint32_t shaderLength, const uint32_t * params, + uint32_t paramLength) { - ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); - pv->bindAllocation(static_cast<Allocation *>(constants)); -} - -void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) -{ - rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); -} - -void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) -{ - rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); + ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength); + pv->incUserRef(); + return pv; } |