|
@@ -320,6 +320,11 @@ int tnsNextPowOf2(int i){
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+void tnsAddShaderComponent(const char* name, const char* replacement){
|
|
|
+ tnsShaderComponent* sc=lstAppendPointerSized(&T->ShaderComponents,0,sizeof(tnsShaderComponent));
|
|
|
+ sc->name=name; sc->replacement=replacement;
|
|
|
+}
|
|
|
+
|
|
|
void tnsShaderMakeIndex(tnsShader *tns){
|
|
|
int program;
|
|
|
|
|
@@ -357,6 +362,7 @@ void tnsShaderMakeIndex(tnsShader *tns){
|
|
|
tns->iInputColorSpace=glGetUniformLocation(program, "InputColorSpace");
|
|
|
tns->iTexIsUI=glGetUniformLocation(program, "TexIsUI");
|
|
|
tns->iTex2IsUI=glGetUniformLocation(program, "Tex2IsUI");
|
|
|
+ tns->iTexPremultiplied=glGetUniformLocation(program, "TexPremultiplied");
|
|
|
tns->iUseLut=glGetUniformLocation(program, "UseLut");
|
|
|
tns->iShowStripes=glGetUniformLocation(program, "ShowStripes");
|
|
|
tns->iComposing=glGetUniformLocation(program, "Composing");
|
|
@@ -413,103 +419,6 @@ void tnsShaderApplyShadowMatrix(tnsShader *tns, tnsMatrix44d m){
|
|
|
glUniformMatrix4fv(tns->iShadow, 1, 0, mf);
|
|
|
}
|
|
|
|
|
|
-char* tnsEnsureShaderCommoms(const char* Content, const char* Library, const char* Material){
|
|
|
- char* c=0,*c1=0;
|
|
|
- c1=strSub(Content,"#with TNS_SHADER_COLOR_COMMON",TNS_SHADER_COLOR_COMMON);
|
|
|
- c=strSub(c1,"#with LA_SHADER_LIB_FXAA",LA_SHADER_LIB_FXAA); free(c1);
|
|
|
- c1=strSub(c,"#with TNS_SHADER_MATERIAL",Material?Material:""); free(c);
|
|
|
- c=strSub(c1,"#with TNS_SHADER_LIBRARY",Library?Library:""); free(c1);
|
|
|
-#ifdef LA_USE_GLES
|
|
|
- const char uint_texture_selection[] = "#define GLES_UINT_TEXTURE";
|
|
|
-#else
|
|
|
- const char uint_texture_selection[] = "";
|
|
|
-#endif
|
|
|
- c1=strSub(c,"#with TNS_GLES_UINT_TEXTURE",uint_texture_selection); free(c);
|
|
|
- return c1;
|
|
|
-}
|
|
|
-int tnsCheckShaderCompileStatus(GLuint shader_object, char* name){
|
|
|
- int status=0; char error[65536]={0};
|
|
|
- glGetShaderiv(shader_object, GL_COMPILE_STATUS, &status);
|
|
|
- if (status == GL_FALSE){
|
|
|
- glGetShaderInfoLog(shader_object, sizeof(error), 0, error); logPrint("%s shader error:\n%s",name?name:"(unnamed)",error);
|
|
|
- glDeleteShader(shader_object); return 0;
|
|
|
- } else {
|
|
|
- glGetShaderInfoLog(shader_object, sizeof(error), 0, error); if(error[0]) logPrint("%s shader info:\n%s",name?name:"(unnamed)",error);
|
|
|
- }
|
|
|
- return 1;
|
|
|
-}
|
|
|
-int tnsCheckProgramLinkStatus(GLuint program_object, char* name){
|
|
|
- int status=0; char error[65536]={0};
|
|
|
- glGetProgramiv(program_object, GL_LINK_STATUS, &status);
|
|
|
- if (status == GL_FALSE){
|
|
|
- glGetProgramInfoLog(program_object, sizeof(error), 0, error); logPrintNew("%s program Linking error:\n%s",name?name:"(unnamed)",error); return 0;
|
|
|
- glDeleteProgram(program_object); return 0;
|
|
|
- } else {
|
|
|
- glGetProgramInfoLog(program_object, sizeof(error), 0, error); if (error[0]) logPrintNew("%s program Linking info:\n%s",name?name:"(unnamed)",error);
|
|
|
- }
|
|
|
- return 1;
|
|
|
-}
|
|
|
-int tnsNewVertexShader(const char *Content){
|
|
|
- int status = 0;
|
|
|
- char error[8192]={0};
|
|
|
- GLuint VertexShaderObject;
|
|
|
- tnsShader *s = 0;
|
|
|
-
|
|
|
- if (!Content) return -1;
|
|
|
-
|
|
|
- VertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
|
|
|
-
|
|
|
- char* UseContent=tnsEnsureShaderCommoms(Content,0,0);
|
|
|
- glShaderSource(VertexShaderObject, 1, &UseContent, 0);
|
|
|
- glCompileShader(VertexShaderObject);
|
|
|
- if(!tnsCheckShaderCompileStatus(VertexShaderObject,"Vertex")){ free(UseContent); return -1; }
|
|
|
- free(UseContent);
|
|
|
-
|
|
|
- return VertexShaderObject;
|
|
|
-}
|
|
|
-int tnsNewFragmentShaderMaterial(const char *Content, const char* Library, const char* Material){
|
|
|
- int status = 0;
|
|
|
- char error[8192]={0};
|
|
|
- GLuint FragmentShaderObject;
|
|
|
- tnsShader *s = 0;
|
|
|
-
|
|
|
- if (!Content) return -1;
|
|
|
-
|
|
|
- FragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
-
|
|
|
- char* UseContent=tnsEnsureShaderCommoms(Content,Library,Material);
|
|
|
- glShaderSource(FragmentShaderObject, 1, &UseContent, 0);
|
|
|
- glCompileShader(FragmentShaderObject);
|
|
|
- if(!tnsCheckShaderCompileStatus(FragmentShaderObject,"Vertex")){ free(UseContent); return -1; }
|
|
|
- free(UseContent);
|
|
|
-
|
|
|
- return FragmentShaderObject;
|
|
|
-}
|
|
|
-int tnsNewFragmentShader(const char *Content){
|
|
|
- return tnsNewFragmentShaderMaterial(Content,0,0);
|
|
|
-}
|
|
|
-int tnsNewGeometryShader(const char *Content){
|
|
|
-#ifndef LAGUI_ANDROID
|
|
|
- int status = 0;
|
|
|
- char error[8192]={0};
|
|
|
- GLuint GeometryShaderObject;
|
|
|
- tnsShader *s = 0;
|
|
|
-
|
|
|
- if (!Content) return -1;
|
|
|
-
|
|
|
- GeometryShaderObject = glCreateShader(GL_GEOMETRY_SHADER);
|
|
|
-
|
|
|
- char* UseContent=tnsEnsureShaderCommoms(Content,0,0);
|
|
|
- glShaderSource(GeometryShaderObject, 1, &UseContent, 0);
|
|
|
- glCompileShader(GeometryShaderObject);
|
|
|
- if(!tnsCheckShaderCompileStatus(GeometryShaderObject,"Geometry")){ free(UseContent); return -1; }
|
|
|
- free(UseContent);
|
|
|
-
|
|
|
- return GeometryShaderObject;
|
|
|
-#endif
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
tnsShader *tnsNewShaderProgram(int VertexShaderID, int FragmentShaderID, int GeometryShaderID){
|
|
|
int vso = VertexShaderID;
|
|
|
int fso = FragmentShaderID;
|
|
@@ -1435,6 +1344,17 @@ void tnsInitRenderKernel(int matrixStackLevel){
|
|
|
arrEnsureLength(&T->DrawingCommand, T->NextCommand, &T->MaxCommand, sizeof(tnsCommand));
|
|
|
}
|
|
|
void tnsInitBuiltinShaders(){
|
|
|
+
|
|
|
+
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+ const char uint_texture_selection[] = "#define GLES_UINT_TEXTURE";
|
|
|
+#else
|
|
|
+ const char uint_texture_selection[] = "";
|
|
|
+#endif
|
|
|
+ tnsAddShaderComponent("#with TNS_GLES_UINT_TEXTURE",uint_texture_selection);
|
|
|
+ tnsAddShaderComponent("#with TNS_SHADER_COLOR_COMMON",TNS_SHADER_COLOR_COMMON);
|
|
|
+ tnsAddShaderComponent("#with LA_SHADER_LIB_FXAA",LA_SHADER_LIB_FXAA);
|
|
|
+
|
|
|
T->immShader = tnsNewShaderProgram(
|
|
|
tnsNewVertexShader(LA_IMM_VERTEX_SHADER),tnsNewFragmentShader(LA_IMM_FRAGMENT_SHADER),-1);
|
|
|
|
|
@@ -1702,7 +1622,7 @@ void tnsDrawBatchInitArrayStates(tnsBatch* batch){
|
|
|
}
|
|
|
}
|
|
|
if(cs->iUV>=0){ glDisableVertexAttribArray(cs->iUV); }
|
|
|
- tnsUniformUseTexture(cs,0,0,0,0);
|
|
|
+ tnsUniformUseTexture(cs,0,0,0,0,0);
|
|
|
}
|
|
|
int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) {
|
|
|
if (!batch) return 0;
|
|
@@ -1948,9 +1868,10 @@ void tnsUseTexture(tnsTexture *t){
|
|
|
else if(t->GLTexType == GL_TEXTURE_2D_MULTISAMPLE){ T->StateTexColor = t; T->StateTextureMode=3; }
|
|
|
#endif
|
|
|
}
|
|
|
-void tnsUseTexture2(tnsTexture* t, int mixmode){
|
|
|
+void tnsUseTexture2(tnsTexture* t, int mixmode, int premultiplied){
|
|
|
if(!t){ T->StateTextureMode=TEX_MODE_IS_MIXING(T)?2:0; return; }
|
|
|
if(t->GLTexType == GL_TEXTURE_2D){ T->StateTexColor2=t; T->StateTextureMode=5+mixmode; }
|
|
|
+ T->StatePremultiplied=premultiplied;
|
|
|
}
|
|
|
void tnsUseNoTexture(){
|
|
|
tnsUseTexture(0);
|
|
@@ -2015,11 +1936,12 @@ void tnsUnbindTexture2(){
|
|
|
else{ tnsActiveTexture(GL_TEXTURE4); glBindTexture(T->TexColor2->GLTexType, 0); T->TexColor2=0; }
|
|
|
}
|
|
|
}
|
|
|
-void tnsUniformUseTexture(tnsShader* s, int mode, int sample, int TexIsUInt, int Tex2IsUInt){
|
|
|
+void tnsUniformUseTexture(tnsShader* s, int mode, int sample, int TexIsUInt, int Tex2IsUInt, int Premultiply){
|
|
|
if(s->StateTextureMode != mode){ s->StateTextureMode=mode; glUniform1i(s->iTextureMode,mode); }
|
|
|
if(mode==3 && s->StateSampleAmount != sample){ s->StateSampleAmount=sample, glUniform1i(s->iSampleAmount,sample); }
|
|
|
if(s->StateTexIsUI != TexIsUInt){ s->StateTexIsUI=TexIsUInt; glUniform1i(s->iTexIsUI,TexIsUInt); }
|
|
|
if(s->StateTex2IsUI != Tex2IsUInt){ s->StateTex2IsUI=Tex2IsUInt; glUniform1i(s->iTex2IsUI,Tex2IsUInt); }
|
|
|
+ if(s->StatePremultiplied != Premultiply){ s->StatePremultiplied=Premultiply; glUniform1i(s->iTexPremultiplied,Premultiply); }
|
|
|
}
|
|
|
void tnsUniformUseMultiplyColor(tnsShader* s, int enable){
|
|
|
int mode=enable?1:0;
|
|
@@ -2468,6 +2390,7 @@ void tnsPackAs(GLenum Mode){
|
|
|
c->ColorTexture2 = T->StateTexColor2;
|
|
|
c->TextureMode = T->StateTextureMode;
|
|
|
c->MultiplyColor = T->StateMultiplyColor;
|
|
|
+ c->Premultiply = T->StatePremultiplied;
|
|
|
c->LineWidth=T->StateLineWidth;
|
|
|
c->PointSize=T->StatePointSize;
|
|
|
c->UseHalftone = T->StateUseHalftone;
|
|
@@ -2570,9 +2493,11 @@ void tnsFlush(){
|
|
|
tnsBindTexture(c->ColorTexture);
|
|
|
if(c->ColorTexture2) tnsBindTexture2(c->ColorTexture2);
|
|
|
tnsUniformUseTexture(cs, c->TextureMode, c->ColorTexture->Multisample,
|
|
|
- c->ColorTexture?c->ColorTexture->IsUIntTexture:0, c->ColorTexture2?c->ColorTexture2->IsUIntTexture:0);
|
|
|
+ c->ColorTexture?c->ColorTexture->IsUIntTexture:0,
|
|
|
+ c->ColorTexture2?c->ColorTexture2->IsUIntTexture:0,
|
|
|
+ c->Premultiply);
|
|
|
}else{
|
|
|
- tnsUniformUseTexture(cs,0,0,0,0); //tnsUnbindTexture();
|
|
|
+ tnsUniformUseTexture(cs,0,0,0,0,0); //tnsUnbindTexture();
|
|
|
}
|
|
|
|
|
|
if(cs->iMultiplyColor != -1){ tnsUniformUseMultiplyColor(cs, c->MultiplyColor); }
|