/*
* LaGUI: A graphical application framework.
* Copyright (C) 2022-2023 Wu Yiming
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#define _GNU_SOURCE 1
#include "la_5.h"
#include
#include
extern tnsMain* T;
char* tnsRegexReplace(char* in, char* pairs[]){
std::string a=in; char** p=pairs;
while(p[0]){
a = std::regex_replace(a,std::regex(p[0]),p[1]); p+=2;
}
int len=a.length()+1; void* ret=malloc(len); memcpy(ret, a.c_str(), len); return (char*)ret;
}
std::string tnsEnsureShaderCommoms(std::string in){
std::string str=in;
for(tnsShaderComponent* sc=(tnsShaderComponent*)T->ShaderComponents.pFirst;sc;sc=(tnsShaderComponent*)sc->Item.pNext){
str = std::regex_replace(str,std::regex(sc->name),sc->replacement);
}
return str;
}
std::string tnsEnsureShaderCommomsLib(std::string in, std::string lib, std::string material){
std::string str=tnsEnsureShaderCommoms(in);
str = std::regex_replace(str,std::regex("#with TNS_SHADER_MATERIAL"),material);
str = std::regex_replace(str,std::regex("#with TNS_SHADER_LIBRARY"),lib);
return str;
}
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;
GLuint VertexShaderObject;
tnsShader *s = 0;
if (!Content) return -1;
VertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
std::string UseContent=tnsEnsureShaderCommoms(Content);
const char* str=UseContent.c_str();
glShaderSource(VertexShaderObject, 1, &str, 0);
glCompileShader(VertexShaderObject);
if(!tnsCheckShaderCompileStatus(VertexShaderObject,"Vertex")){ return -1; }
return VertexShaderObject;
}
int tnsNewFragmentShaderMaterial(const char *Content, const char* Library, const char* Material){
int status = 0;
GLuint FragmentShaderObject;
tnsShader *s = 0;
if (!Content) return -1;
FragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
std::string UseContent=tnsEnsureShaderCommomsLib(Content,Library?Library:"",Material?Material:"");
const char* str=UseContent.c_str();
glShaderSource(FragmentShaderObject, 1, &str, 0);
glCompileShader(FragmentShaderObject);
if(!tnsCheckShaderCompileStatus(FragmentShaderObject,"Vertex")){ return -1; }
return FragmentShaderObject;
}
int tnsNewFragmentShader(const char *Content){
return tnsNewFragmentShaderMaterial(Content,0,0);
}
int tnsNewGeometryShader(const char *Content){
#ifndef LAGUI_ANDROID
int status = 0;
GLuint GeometryShaderObject;
tnsShader *s = 0;
if (!Content) return -1;
GeometryShaderObject = glCreateShader(GL_GEOMETRY_SHADER);
std::string UseContent=tnsEnsureShaderCommoms(Content);
const char* str=UseContent.c_str();
glShaderSource(GeometryShaderObject, 1, &str, 0);
glCompileShader(GeometryShaderObject);
if(!tnsCheckShaderCompileStatus(GeometryShaderObject,"Geometry")){ return -1; }
return GeometryShaderObject;
#endif
return 0;
}