/* * 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; }