Fixing uniform binding for fragment shader.

Updating the glsl fragment shader to color the lights.

Change-Id: I6f850d1aa22059a2974e379f652f7e99d6a799fb
This commit is contained in:
Alex Sakhartchouk
2010-08-31 12:02:01 -07:00
parent 6dabe240ed
commit 8442e0bffe
7 changed files with 159 additions and 136 deletions

View File

@@ -7,12 +7,9 @@ varying lowp float light1_Specular;
void main() {
vec2 t0 = varTex0.xy;
lowp vec4 col = texture2D(uni_Tex0, t0).rgba;
/*col = col * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor);
col += light0_Specular * UNI_light0_SpecularColor;
col += light1_Specular * UNI_light1_SpecularColor;*/
col = col * (light0_Diffuse + light1_Diffuse);
col += light0_Specular;
col += light1_Specular;
col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor);
col.xyz += light0_Specular * UNI_light0_SpecularColor;
col.xyz += light1_Specular * UNI_light1_SpecularColor;
gl_FragColor = col;
}

View File

@@ -73,6 +73,8 @@ rs_program_fragment gProgFragmentCustom;
//What we are showing
#pragma rs export_var(gDisplayMode)
float gDt = 0;
void init() {
}
@@ -300,7 +302,7 @@ void displayCullingSamples() {
rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
// Aplly a rotation to our mesh
gTorusRotation += 50.0f * rsGetDt();
gTorusRotation += 50.0f * gDt;
if(gTorusRotation > 360.0f) {
gTorusRotation -= 360.0f;
}
@@ -333,15 +335,15 @@ void setupCustomShaderLights() {
float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
float3 light0DiffCol = {0.9f, 0.7f, 0.7f};
float3 light0SpecCol = {0.9f, 0.8f, 0.8f};
float3 light1DiffCol = {0.7f, 0.7f, 0.9f};
float3 light1SpecCol = {0.8f, 0.8f, 0.9f};
float3 light0SpecCol = {0.9f, 0.6f, 0.6f};
float3 light1DiffCol = {0.5f, 0.5f, 0.9f};
float3 light1SpecCol = {0.5f, 0.5f, 0.9f};
gLight0Rotation += 150.0f * rsGetDt();
gLight0Rotation += 50.0f * gDt;
if(gLight0Rotation > 360.0f) {
gLight0Rotation -= 360.0f;
}
gLight1Rotation -= 50.0f * rsGetDt();
gLight1Rotation -= 50.0f * gDt;
if(gLight1Rotation > 360.0f) {
gLight1Rotation -= 360.0f;
}
@@ -359,7 +361,7 @@ void setupCustomShaderLights() {
gVSConstants->light0_Posision.z = light0Pos.z;
gVSConstants->light0_Diffuse = 1.0f;
gVSConstants->light0_Specular = 0.5f;
gVSConstants->light0_CosinePower = 70.0f;
gVSConstants->light0_CosinePower = 40.0f;
// Set light 1 properties
gVSConstants->light1_Posision.x = light1Pos.x;
gVSConstants->light1_Posision.y = light1Pos.y;
@@ -382,7 +384,7 @@ void displayCustomShaderSamples() {
// Update vertex shader constants
// Load model matrix
// Aplly a rotation to our mesh
gTorusRotation += 50.0f * rsGetDt();
gTorusRotation += 50.0f * gDt;
if(gTorusRotation > 360.0f) {
gTorusRotation -= 360.0f;
}
@@ -390,6 +392,7 @@ void displayCustomShaderSamples() {
// Position our model on the screen
rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
setupCustomShaderLights();
rsgBindProgramVertex(gProgVertexCustom);
@@ -416,6 +419,8 @@ void displayCustomShaderSamples() {
int root(int launchID) {
gDt = rsGetDt();
rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
rsgClearDepth(1.0f);

View File

@@ -241,7 +241,129 @@ void Program::setShader(const char *txt, uint32_t len)
mUserShader.setTo(txt, len);
}
void Program::appendUserConstants() {
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);
const char *fn = e->getFieldName(field);
if (fn[0] == '#') {
continue;
}
// Cannot be complex
rsAssert(!f->getFieldCount());
if(f->getType() == RS_TYPE_MATRIX_4X4) {
mShader.append("uniform mat4 UNI_");
}
else if(f->getType() == RS_TYPE_MATRIX_3X3) {
mShader.append("uniform mat3 UNI_");
}
else if(f->getType() == RS_TYPE_MATRIX_2X2) {
mShader.append("uniform mat2 UNI_");
}
else {
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(fn);
mShader.append(";\n");
}
}
}
void Program::setupUserConstants(ShaderCache *sc, bool isFragment) {
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);
const char *fieldName = e->getFieldName(field);
// If this field is padding, skip it
if(fieldName[0] == '#') {
continue;
}
uint32_t offset = e->getFieldOffsetBytes(field);
const float *fd = reinterpret_cast<const float *>(&data[offset]);
int32_t slot = -1;
if(!isFragment) {
slot = sc->vtxUniformSlot(uidx);
}
else {
slot = sc->fragUniformSlot(uidx);
}
//LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
if (slot >= 0) {
if(f->getType() == RS_TYPE_MATRIX_4X4) {
glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
}
else if(f->getType() == RS_TYPE_MATRIX_3X3) {
glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
}
else if(f->getType() == RS_TYPE_MATRIX_2X2) {
glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
}
else {
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 ++;
}
}
}
void Program::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 if(e->getFieldName(ct)[0] != '#') {
String8 tmp(prefix);
tmp.append(e->getFieldName(ct));
names[*count].setTo(tmp.string());
(*count)++;
}
}
}
namespace android {
namespace renderscript {

View File

@@ -72,6 +72,11 @@ protected:
uint32_t mConstantCount;
bool mIsValid;
// Applies to vertex and fragment shaders only
void appendUserConstants();
void setupUserConstants(ShaderCache *sc, bool isFragment);
void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
ObjectBaseRef<Allocation> mConstants[MAX_UNIFORMS];
mutable bool mDirty;

View File

@@ -71,7 +71,7 @@ ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
mConstantColorUniformIndex = mUniformCount;
mUniformNames[mUniformCount++].setTo("uni_Color");
//}
createShader();
init(rsc);
}
ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
@@ -93,9 +93,9 @@ ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
mUniformNames[0].setTo("uni_Tex0");
mUniformNames[1].setTo("uni_Tex1");
createShader();
mTextureEnableMask = (1 << mTextureCount) -1;
init(rsc);
}
@@ -134,6 +134,9 @@ void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state,
rsc->checkError("ProgramFragment::color setup");
}
rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
setupUserConstants(sc, true);
for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
glActiveTexture(GL_TEXTURE0 + ct);
if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
@@ -179,7 +182,7 @@ void ProgramFragment::createShader()
sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
mShader.append(buf);
}
appendUserConstants();
mShader.append(mUserShader);
} else {
uint32_t mask = mTextureEnableMask;
@@ -272,6 +275,13 @@ void ProgramFragment::createShader()
void ProgramFragment::init(Context *rsc)
{
if (mUserShader.size() > 0) {
for (uint32_t ct=0; ct < mConstantCount; ct++) {
initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
}
}
createShader();
}
void ProgramFragment::serialize(OStream *stream) const
@@ -304,7 +314,6 @@ void ProgramFragmentState::init(Context *rsc)
};
ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
mDefault.set(pf);
pf->init(rsc);
}
void ProgramFragmentState::deinit(Context *rsc)

View File

@@ -134,43 +134,7 @@ void ProgramVertex::createShader()
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);
const char *fn = e->getFieldName(field);
if (fn[0] == '#') {
continue;
}
// Cannot be complex
rsAssert(!f->getFieldCount());
if(f->getType() == RS_TYPE_MATRIX_4X4) {
mShader.append("uniform mat4 UNI_");
}
else if(f->getType() == RS_TYPE_MATRIX_3X3) {
mShader.append("uniform mat3 UNI_");
}
else if(f->getType() == RS_TYPE_MATRIX_2X2) {
mShader.append("uniform mat2 UNI_");
}
else {
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(fn);
mShader.append(";\n");
}
}
appendUserConstants();
for (uint32_t ct=0; ct < mInputCount; ct++) {
const Element *e = mInputElements[ct].get();
@@ -248,65 +212,7 @@ void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, Shad
}
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 char *fieldName = e->getFieldName(field);
const float *fd = reinterpret_cast<const float *>(&data[offset]);
// If this field is padding, skip it
if(fieldName[0] == '#') {
continue;
}
//LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
if (slot >= 0) {
if(f->getType() == RS_TYPE_MATRIX_4X4) {
glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
}
else if(f->getType() == RS_TYPE_MATRIX_3X3) {
glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
}
else if(f->getType() == RS_TYPE_MATRIX_2X2) {
glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
}
else {
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 ++;
}
}
setupUserConstants(sc, false);
state->mLast.set(this);
rsc->checkError("ProgramVertex::setupGL2");
@@ -356,24 +262,6 @@ void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const fl
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 if(e->getFieldName(ct)[0] != '#') {
String8 tmp(prefix);
tmp.append(e->getFieldName(ct));
names[*count].setTo(tmp.string());
(*count)++;
}
}
}
void ProgramVertex::init(Context *rsc)
{
mAttribCount = 0;

View File

@@ -63,9 +63,6 @@ protected:
// Hacks to create a program for now
bool mTextureMatrixEnable;
private:
void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
};