|
@@ -319,11 +319,12 @@ void tnsShaderApplyShadowMatrix(tnsShader *tns, tnsMatrix44d m){
|
|
|
glUniformMatrix4fv(tns->iShadow, 1, 0, mf);
|
|
|
}
|
|
|
|
|
|
-char* tnsEnsureShaderCommoms(char* Content){
|
|
|
+char* tnsEnsureShaderCommoms(char* Content, 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);
|
|
|
- return c;
|
|
|
+ c1=strSub(c,"#with TNS_SHADER_MATERIAL",Material?Material:""); free(c);
|
|
|
+ return c1;
|
|
|
}
|
|
|
int tnsNewVertexShader(char *Content){
|
|
|
int status = 0;
|
|
@@ -335,7 +336,7 @@ int tnsNewVertexShader(char *Content){
|
|
|
|
|
|
VertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
|
|
- char* UseContent=tnsEnsureShaderCommoms(Content);
|
|
|
+ char* UseContent=tnsEnsureShaderCommoms(Content,0);
|
|
|
glShaderSource(VertexShaderObject, 1, &UseContent, 0);
|
|
|
glCompileShader(VertexShaderObject);
|
|
|
glGetShaderiv(VertexShaderObject, GL_COMPILE_STATUS, &status);
|
|
@@ -349,7 +350,7 @@ int tnsNewVertexShader(char *Content){
|
|
|
|
|
|
return VertexShaderObject;
|
|
|
}
|
|
|
-int tnsNewFragmentShader(char *Content){
|
|
|
+int tnsNewFragmentShaderMaterial(char *Content, char* Material){
|
|
|
int status = 0;
|
|
|
char error[1024];
|
|
|
GLuint FragmentShaderObject;
|
|
@@ -359,7 +360,7 @@ int tnsNewFragmentShader(char *Content){
|
|
|
|
|
|
FragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
|
|
- char* UseContent=tnsEnsureShaderCommoms(Content);
|
|
|
+ char* UseContent=tnsEnsureShaderCommoms(Content,Material);
|
|
|
glShaderSource(FragmentShaderObject, 1, &UseContent, 0);
|
|
|
glCompileShader(FragmentShaderObject);
|
|
|
glGetShaderiv(FragmentShaderObject, GL_COMPILE_STATUS, &status);
|
|
@@ -373,6 +374,9 @@ int tnsNewFragmentShader(char *Content){
|
|
|
|
|
|
return FragmentShaderObject;
|
|
|
}
|
|
|
+int tnsNewFragmentShader(char *Content){
|
|
|
+ return tnsNewFragmentShaderMaterial(Content,0);
|
|
|
+}
|
|
|
int tnsNewGeometryShader(char *Content){
|
|
|
int status = 0;
|
|
|
char error[1024];
|
|
@@ -383,7 +387,7 @@ int tnsNewGeometryShader(char *Content){
|
|
|
|
|
|
GeometryShaderObject = glCreateShader(GL_GEOMETRY_SHADER);
|
|
|
|
|
|
- char* UseContent=tnsEnsureShaderCommoms(Content);
|
|
|
+ char* UseContent=tnsEnsureShaderCommoms(Content,0);
|
|
|
glShaderSource(GeometryShaderObject, 1, &UseContent, 0);
|
|
|
glCompileShader(GeometryShaderObject);
|
|
|
glGetShaderiv(GeometryShaderObject, GL_COMPILE_STATUS, &status);
|
|
@@ -455,28 +459,25 @@ int tnsEnableShader(int index){
|
|
|
}
|
|
|
int tnsEnableShaderv(tnsShader *shader){
|
|
|
tnsMatrixStackItem *tmsi;
|
|
|
- tnsShader *tns = shader;
|
|
|
- if (!tns){
|
|
|
- glUseProgram(0);
|
|
|
- T->CurrentShader = 0;
|
|
|
- T->BindedShader = 0;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- glUseProgram(tns->glProgramID);
|
|
|
- T->CurrentShader = tns;
|
|
|
- T->BindedShader = tns;
|
|
|
+ tnsShader *s = shader;
|
|
|
+ if (!s){ glUseProgram(0); T->CurrentShader = 0;T->BindedShader = 0; return 0; }
|
|
|
+ glUseProgram(s->glProgramID);
|
|
|
+ T->CurrentShader = s;
|
|
|
+ T->BindedShader = s;
|
|
|
|
|
|
tmsi = tKnlGetCurrentMatStackItem();
|
|
|
- tnsShaderApplyProjection(tns, tmsi->projection);
|
|
|
- tnsShaderApplyProjectionInverse(tns, tmsi->projection);
|
|
|
- tnsShaderApplyView(tns, tmsi->view);
|
|
|
- tnsShaderApplyModel(tns, tmsi->model); tnsUseShader(tns);
|
|
|
-
|
|
|
- //if (tns->iVertex != -1) glEnableVertexAttribArray(tns->iVertex);
|
|
|
- //if (tns->iColor != -1) glEnableVertexAttribArray(tns->iColor);
|
|
|
- //if (tns->iNormal != -1) glEnableVertexAttribArray(tns->iNormal);
|
|
|
- //if (tns->iUV != -1) glEnableVertexAttribArray(tns->iUV);
|
|
|
-
|
|
|
+ tnsShaderApplyProjection(s, tmsi->projection);
|
|
|
+ tnsShaderApplyProjectionInverse(s, tmsi->projection);
|
|
|
+ tnsShaderApplyView(s, tmsi->view);
|
|
|
+ tnsShaderApplyModel(s, tmsi->model); tnsUseShader(s);
|
|
|
+
|
|
|
+ if(s->iUseNormal) glUniform1i(s->iUseNormal,T->SetUseNormal);
|
|
|
+ if(s->uViewPos) glUniform3fv(s->uViewPos,1,T->SetViewPos);
|
|
|
+ if(s->iUseHalftone) glUniform1f(s->iUseHalftone,T->SetUseHalftone);
|
|
|
+ if(s->iHalftoneSize) glUniform1f(s->iHalftoneSize,T->SetHalftoneSize);
|
|
|
+ //if(s->iTextureMode) glUniform1i(s->iTextureMode,T->StateTextureMode);
|
|
|
+ //if(cs->iSampleAmount) glUniform1i(cs->iSampleAmount);
|
|
|
+
|
|
|
return 1;
|
|
|
}
|
|
|
int tnsUseShader(tnsShader *shader){
|
|
@@ -1516,6 +1517,9 @@ void tnsCommandUseUniformColor(tnsBatchCommand*c, real* color){
|
|
|
tnsVectorCopy4d(color, c->UniformColor);
|
|
|
c->UseUniformColor=1;
|
|
|
}
|
|
|
+void tnsCommandUseMaterial(tnsBatchCommand*c, tnsMaterial* material){
|
|
|
+ c->Material=material;
|
|
|
+}
|
|
|
void tnsCommandUseWidth(tnsBatchCommand*c, real width){
|
|
|
c->Width=width;
|
|
|
}
|
|
@@ -1561,13 +1565,8 @@ void tnsDeleteBatch(tnsBatch *b){
|
|
|
|
|
|
FreeMem(b);
|
|
|
}
|
|
|
-int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) {
|
|
|
- //int Mode = batch->DrawMode;
|
|
|
- if (!batch) return;
|
|
|
+void tnsDrawBatchInitArrayStates(tnsBatch* batch){
|
|
|
tnsShader* cs=T->BindedShader;
|
|
|
- int Drawn=0;
|
|
|
-
|
|
|
- //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch->VBO);
|
|
|
glEnableVertexAttribArray(cs->iVertex);
|
|
@@ -1587,12 +1586,25 @@ int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUni
|
|
|
}
|
|
|
if(cs->iUV>=0){ glDisableVertexAttribArray(cs->iUV); }
|
|
|
tnsUniformUseTexture(cs, 0, 0);
|
|
|
+}
|
|
|
+int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) {
|
|
|
+ if (!batch) return;
|
|
|
+ int Drawn=0; tnsShader *LastShader=T->BindedShader,*SaveShader=T->BindedShader; int NeedInit=1;
|
|
|
|
|
|
int IsOverrideColor=0; int PointSizeChanged=0,LineWidthChanged=0;
|
|
|
for (tnsBatchCommand* bc = batch->Branches.pFirst; bc; bc = bc->Item.pNext) {
|
|
|
if(OverrideCommand && !strSame(OverrideCommand, bc->name)){ continue; }
|
|
|
if(!OverrideCommand && bc->HiddenByDefault){ continue; }
|
|
|
- if(cs->iColor){
|
|
|
+ if(NeedInit || (bc->Material && LastShader!=bc->Material->Shader) || ((!bc->Material)&&LastShader!=SaveShader)){
|
|
|
+ if(bc->Material && bc->Material->Shader){ LastShader=bc->Material->Shader;
|
|
|
+ tnsUseShader(LastShader); tnsEnableShaderv(LastShader);
|
|
|
+ }else{
|
|
|
+ tnsUseShader(SaveShader); tnsEnableShaderv(SaveShader);
|
|
|
+ }
|
|
|
+ tnsDrawBatchInitArrayStates(batch); NeedInit=0;
|
|
|
+ }
|
|
|
+ tnsShader* cs=T->BindedShader;
|
|
|
+ if(cs->iColor>-1){
|
|
|
if(bc->OverrideColorArray){
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, bc->CBO); glEnableVertexAttribArray(cs->iColor);
|
|
|
glVertexAttribPointer(cs->iColor, bc->ColorDimension, GL_FLOAT, 0, 0, 0); IsOverrideColor=1;
|
|
@@ -1619,6 +1631,8 @@ int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUni
|
|
|
if(PointSizeChanged){ glPointSize(1); } if(LineWidthChanged){ glLineWidth(1); }
|
|
|
}
|
|
|
|
|
|
+ if(SaveShader!=LastShader){ tnsUseShader(SaveShader); tnsEnableShaderv(SaveShader); }
|
|
|
+
|
|
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
return Drawn;
|
|
|
}
|
|
@@ -3637,7 +3651,8 @@ void tnsApplyCameraView(int W, int H, tnsCamera *Camera){
|
|
|
|
|
|
if (current_shader = T->CurrentShader){
|
|
|
tnsShaderApplyView(current_shader, result);
|
|
|
- if(current_shader->uViewPos>-1) glUniform3f(current_shader->uViewPos,LA_COLOR3(Camera->Base.Location));
|
|
|
+ if(current_shader->uViewPos>-1) glUniform3f(current_shader->uViewPos,LA_COLOR3(Camera->Base.GLocation));
|
|
|
+ tnsVectorSet3v(T->SetViewPos,Camera->Base.GLocation);
|
|
|
}
|
|
|
}
|
|
|
void tnsApplyShadowCameraView(tnsLight *Light){
|
|
@@ -4103,6 +4118,7 @@ tnsMaterial *tnsCreateMaterial(char *Name){
|
|
|
tnsMaterial *m; if(!Name || !Name[0]) return 0;
|
|
|
m = memAcquireHyper(sizeof(tnsMaterial));
|
|
|
strSafeSet(&m->Name, Name); tnsVectorSet4(m->Color,0.8,0.8,0.8,1);
|
|
|
+ m->Page=memAcquire(sizeof(laRackPage));
|
|
|
lstAppendItem(&T->World->Materials, m);
|
|
|
return m;
|
|
|
}
|
|
@@ -4112,7 +4128,9 @@ tnsMaterial *tnsFindMaterial(char *name){
|
|
|
return 0;
|
|
|
}
|
|
|
void tnsRemoveMaterial(tnsMaterial* mat){
|
|
|
- lstRemoveItem(&T->World->Materials,mat); memLeave(mat);
|
|
|
+ lstRemoveItem(&T->World->Materials,mat);
|
|
|
+ laNodeRack* rr; while(rr=lstPopItem(&mat->Page->Racks)){ laDestroyRack(rr); } memLeave(mat->Page);
|
|
|
+ memLeave(mat);
|
|
|
}
|
|
|
tnsMaterialSlot* tnsNewMaterialSlot(tnsMeshObject* mo){
|
|
|
if(mo->Base.Type!=TNS_OBJECT_MESH) return 0; short nextid=0,found=1;
|
|
@@ -4122,7 +4140,7 @@ tnsMaterialSlot* tnsNewMaterialSlot(tnsMeshObject* mo){
|
|
|
}
|
|
|
}
|
|
|
tnsMaterialSlot* ms=memAcquire(sizeof(tnsMaterialSlot)); lstAppendItem(&mo->Materials,ms);
|
|
|
- ms->Index=nextid; ms->Parent=mo; memAssignRef(mo,&mo->CurrentMaterial,ms);
|
|
|
+ ms->Index=nextid; memAssignRef(ms,&ms->Parent,mo); memAssignRef(mo,&mo->CurrentMaterial,ms);
|
|
|
return ms;
|
|
|
}
|
|
|
void tnsRemoveMaterialSlot(tnsMeshObject* mo, tnsMaterialSlot* ms){
|
|
@@ -4138,6 +4156,17 @@ void tnsAssignMaterialSlot(tnsMeshObject* mo, tnsMaterialSlot* ms){
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void tnsEnsureMaterialShader(tnsMaterial* mat, int Refresh){
|
|
|
+ if(Refresh){
|
|
|
+ if(mat->Shader && mat->Shader!=T->immShader){ tnsDeleteShaderProgram(mat->Shader); mat->Shader=0; }
|
|
|
+ }
|
|
|
+ if(!(mat->Page->Script&&mat->Page->Script->Ptr)){ mat->Shader=T->immShader; return; }
|
|
|
+ char* str=mat->Page->Script->Ptr;
|
|
|
+ mat->Shader = tnsNewShaderProgram(
|
|
|
+ tnsNewVertexShader(LA_IMM_VERTEX_SHADER),tnsNewFragmentShaderMaterial(LA_OBJECT_FRAGMENT_SHADER,str),-1);
|
|
|
+ if(!mat->Shader){ mat->Shader=T->immShader; }
|
|
|
+}
|
|
|
+
|
|
|
//==================================================================[Util]
|
|
|
|
|
|
#define MAX3(a, b, c) \
|