diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index 2638d4b..196ee9e 100644 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -98,6 +98,12 @@ struct UniformObject RGBAf lightColor[MAX_LIGHTS]; }; +struct GLShaderState +{ + RGBA matColor; + SurfaceProperties surfProps; +}; + const char *shaderDecl330 = "#version 330\n"; const char *shaderDecl100es = "#version 100\n"\ @@ -129,6 +135,7 @@ static GLuint whitetex; static UniformState uniformState; static UniformScene uniformScene; static UniformObject uniformObject; +static GLShaderState shaderState; #ifndef RW_GL_USE_UBOS // State @@ -878,13 +885,39 @@ setViewMatrix(float32 *mat) Shader *lastShaderUploaded; +#define U(i) currentShader->uniformLocations[i] + +void +setMaterial(const RGBA &color, const SurfaceProperties &surfaceprops) +{ + bool force = lastShaderUploaded != currentShader; + if(force || !equal(shaderState.matColor, color)){ + rw::RGBAf col; + convColor(&col, &color); + glUniform4fv(U(u_matColor), 1, (GLfloat*)&col); + shaderState.matColor = color; + } + + if(force || + shaderState.surfProps.ambient != surfaceprops.ambient || + shaderState.surfProps.specular != surfaceprops.specular || + shaderState.surfProps.diffuse != surfaceprops.diffuse){ + float surfProps[4]; + surfProps[0] = surfaceprops.ambient; + surfProps[1] = surfaceprops.specular; + surfProps[2] = surfaceprops.diffuse; + surfProps[3] = 0.0f; + glUniform4fv(U(u_surfProps), 1, surfProps); + shaderState.surfProps = surfaceprops; + } +} + void flushCache(void) { flushGlRenderState(); #ifndef RW_GL_USE_UBOS -#define U(i) currentShader->uniformLocations[i] // TODO: this is probably a stupid way to do it without UBOs if(lastShaderUploaded != currentShader){ diff --git a/src/gl/gl3immed.cpp b/src/gl/gl3immed.cpp index cebb75f..5dbcea1 100644 --- a/src/gl/gl3immed.cpp +++ b/src/gl/gl3immed.cpp @@ -23,6 +23,9 @@ uint32 im2DVbo, im2DIbo; #ifdef RW_GL_USE_VAOS uint32 im2DVao; #endif + +Shader *im2dOverrideShader; + static int32 u_xform; #define STARTINDICES 10000 @@ -130,7 +133,10 @@ im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices) xform[2] = -1.0f; xform[3] = 1.0f; - im2dShader->use(); + if(im2dOverrideShader) + im2dOverrideShader->use(); + else + im2dShader->use(); #ifndef RW_GL_USE_VAOS setAttribPointers(im2dattribDesc, 3); #endif @@ -170,7 +176,10 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, xform[2] = -1.0f; xform[3] = 1.0f; - im2dShader->use(); + if(im2dOverrideShader) + im2dOverrideShader->use(); + else + im2dShader->use(); #ifndef RW_GL_USE_VAOS setAttribPointers(im2dattribDesc, 3); #endif diff --git a/src/gl/gl3matfx.cpp b/src/gl/gl3matfx.cpp index 687c1ab..931834a 100644 --- a/src/gl/gl3matfx.cpp +++ b/src/gl/gl3matfx.cpp @@ -72,20 +72,11 @@ void matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst) { Material *m; - RGBAf col; - GLfloat surfProps[4]; m = inst->material; defaultShader->use(); - convColor(&col, &m->color); - glUniform4fv(U(u_matColor), 1, (GLfloat*)&col); - - surfProps[0] = m->surfaceProps.ambient; - surfProps[1] = m->surfaceProps.specular; - surfProps[2] = m->surfaceProps.diffuse; - surfProps[3] = 0.0f; - glUniform4fv(U(u_surfProps), 1, surfProps); + setMaterial(m->color, m->surfaceProps); setTexture(0, m->texture); @@ -128,8 +119,6 @@ void matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, MatFX::Env *env) { Material *m; - RGBAf col; - GLfloat surfProps[4]; m = inst->material; if(env->tex == nil || env->coefficient == 0.0f){ @@ -143,14 +132,7 @@ matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, MatFX::Env *env) setTexture(1, env->tex); uploadEnvMatrix(env->frame); - convColor(&col, &m->color); - glUniform4fv(U(u_matColor), 1, (GLfloat*)&col); - - surfProps[0] = m->surfaceProps.ambient; - surfProps[1] = m->surfaceProps.specular; - surfProps[2] = m->surfaceProps.diffuse; - surfProps[3] = 0.0f; - glUniform4fv(U(u_surfProps), 1, surfProps); + setMaterial(m->color, m->surfaceProps); float fxparams[2]; fxparams[0] = env->coefficient; diff --git a/src/gl/gl3render.cpp b/src/gl/gl3render.cpp index e0d5156..15f0cff 100644 --- a/src/gl/gl3render.cpp +++ b/src/gl/gl3render.cpp @@ -144,14 +144,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) while(n--){ m = inst->material; - convColor(&col, &m->color); - glUniform4fv(U(u_matColor), 1, (GLfloat*)&col); - - surfProps[0] = m->surfaceProps.ambient; - surfProps[1] = m->surfaceProps.specular; - surfProps[2] = m->surfaceProps.diffuse; - surfProps[3] = 0.0f; - glUniform4fv(U(u_surfProps), 1, surfProps); + setMaterial(m->color, m->surfaceProps); setTexture(0, m->texture); diff --git a/src/gl/gl3shader.cpp b/src/gl/gl3shader.cpp index ef2af25..f46e5a0 100644 --- a/src/gl/gl3shader.cpp +++ b/src/gl/gl3shader.cpp @@ -85,12 +85,13 @@ printShaderSource(const char **src) bool printline; int line = 1; for(f = 0; src[f]; f++){ + int fileline = 1; char c; file = src[f]; printline = true; while(c = *file++, c != '\0'){ if(printline) - printf("%.4d: ", line++); + printf("%.4d/%d:%.4d: ", line++, f, fileline++); putchar(c); printline = c == '\n'; } @@ -243,6 +244,10 @@ Shader::create(const char **vsrc, const char **fsrc) glUniform1i(loc, i); } + // reset program + if(currentShader) + glUseProgram(currentShader->program); + return sh; } diff --git a/src/gl/gl3skin.cpp b/src/gl/gl3skin.cpp index 52ed51b..494fa08 100644 --- a/src/gl/gl3skin.cpp +++ b/src/gl/gl3skin.cpp @@ -282,8 +282,6 @@ void skinRenderCB(Atomic *atomic, InstanceDataHeader *header) { Material *m; - RGBAf col; - GLfloat surfProps[4]; setWorldMatrix(atomic->getFrame()->getLTM()); lightingCB(atomic); @@ -306,14 +304,7 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header) while(n--){ m = inst->material; - convColor(&col, &m->color); - glUniform4fv(U(u_matColor), 1, (GLfloat*)&col); - - surfProps[0] = m->surfaceProps.ambient; - surfProps[1] = m->surfaceProps.specular; - surfProps[2] = m->surfaceProps.diffuse; - surfProps[3] = 0.0f; - glUniform4fv(U(u_surfProps), 1, surfProps); + setMaterial(m->color, m->surfaceProps); setTexture(0, m->texture); diff --git a/src/gl/rwgl3.h b/src/gl/rwgl3.h index 0db16f7..3daad85 100644 --- a/src/gl/rwgl3.h +++ b/src/gl/rwgl3.h @@ -170,6 +170,8 @@ extern const char *shaderDecl; // #version stuff extern const char *header_vert_src; extern const char *header_frag_src; +extern Shader *im2dOverrideShader; + // per Scene void setProjectionMatrix(float32*); void setViewMatrix(float32*); @@ -180,6 +182,7 @@ int32 setLights(WorldLights *lightData); // per Mesh void setTexture(int32 n, Texture *tex); +void setMaterial(const RGBA &color, const SurfaceProperties &surfaceprops); void setAlphaBlend(bool32 enable); bool32 getAlphaBlend(void); diff --git a/tools/playground/main.cpp b/tools/playground/main.cpp index 2993161..ada15a9 100644 --- a/tools/playground/main.cpp +++ b/tools/playground/main.cpp @@ -175,6 +175,65 @@ setupClump(rw::Clump *clump) } } +#define MUL(x, y) ((x)*(y)/255) + +int +calcVCfx(int fb, int col, int a, int iter) +{ + int prev = fb; + int col2 = col*2; + if(col2 > 255) col2 = 255; + for(int i = 0; i < iter; i++){ + int tmp = MUL(fb, 255-a) + MUL(MUL(prev, col2), a); + tmp += MUL(prev, col); + tmp += MUL(prev, col); + prev = tmp > 255 ? 255 : tmp; + } + return prev; +} + +int +calcIIIfx(int fb, int col, int a, int iter) +{ + int prev = fb; + for(int i = 0; i < iter; i++){ + int tmp = MUL(fb, 255-a) + MUL(MUL(prev, col), a); + prev = tmp > 255 ? 255 : tmp; + } + return prev; +} + +void +postfxtest(void) +{ + rw::Image *img = rw::Image::create(256, 256, 32); + img->allocate(); + int x, y; + int iter; + static char filename[100]; + for(iter = 0; iter < 10; iter++){ + for(y = 0; y < 256; y++) + for(x = 0; x < 256; x++){ + int res = calcVCfx(y, x, 30, iter); +// int res = calcIIIfx(y, x, 30, iter); + if(0 && res == y){ + img->pixels[y*img->stride + x*img->bpp + 0] = 255; + img->pixels[y*img->stride + x*img->bpp + 1] = 0; + img->pixels[y*img->stride + x*img->bpp + 2] = 0; + }else{ + img->pixels[y*img->stride + x*img->bpp + 0] = res; + img->pixels[y*img->stride + x*img->bpp + 1] = res; + img->pixels[y*img->stride + x*img->bpp + 2] = res; + } + img->pixels[y*img->stride + x*img->bpp + 3] = 255; + } + sprintf(filename, "vcfx_%02d.bmp", iter); +// sprintf(filename, "iiifx_%02d.bmp", iter); + rw::writeBMP(img, filename); + } + exit(0); +} + bool InitRW(void) { @@ -184,6 +243,8 @@ InitRW(void) rw::d3d::isP8supported = false; + postfxtest(); + initFont(); rw::RGBA foreground = { 255, 255, 0, 255 };