/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.tests.g3d;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Scanner;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.ObjectMap;
public class ShaderLoader {
public FileHandle root;
public ObjectMap<String, ObjectMap<String, String>> snippets = new ObjectMap<String, ObjectMap<String, String>>();
private Array<String> includes = new Array<String>();
public ShaderLoader (FileHandle root) {
this.root = root;
}
public ShaderProgram load (String vertex, String fragment) {
StringBuilder out = new StringBuilder();
load(out, vertex);
vertex = out.toString();
includes.clear();
out.setLength(0);
load(out, fragment);
fragment = out.toString();
includes.clear();
return new ShaderProgram(vertex, fragment);
}
public String load (final String name) {
StringBuilder out = new StringBuilder();
load(out, name);
includes.clear();
return out.toString();
}
protected void load (final StringBuilder out, final String name) {
final int idx = name.lastIndexOf(':');
final String fileName = idx < 0 ? name : name.substring(0, idx);
final String snipName = idx < 0 || (idx >= name.length() - 1) ? "" : name.substring(idx + 1);
ObjectMap<String, String> snips = snippets.get(fileName, null);
if (snips == null) {
snips = parse(root.child(fileName));
snippets.put(fileName, snips);
}
String result = snips.get(snipName, null);
if (result == null) throw new GdxRuntimeException("No snippet [" + snipName + "] in file " + root.child(fileName).path());
parse(out, fileName, result);
}
protected void parse (final StringBuilder out, final String currentFile, final String code) {
String[] lines = code.split("\n");
int idx, jdx;
for (final String line : lines) {
if (((idx = line.indexOf("#include")) == 0) && ((idx = line.indexOf("\"", idx)) > 0)
&& ((jdx = line.indexOf("\"", ++idx)) > idx)) {
String name = line.substring(idx, jdx);
if (name.length() > 0) {
if (name.charAt(0) == ':') name = currentFile + name;
if (!includes.contains(name, false)) {
includes.add(name);
load(out, name);
}
}
} else
out.append(line.trim()).append("\r\n");
}
}
final static StringBuilder stringBuilder = new StringBuilder();
protected ObjectMap<String, String> parse (final FileHandle file) {
ObjectMap<String, String> result = new ObjectMap<String, String>();
BufferedReader reader = file.reader(1024);
String line;
String snipName = "";
stringBuilder.setLength(0);
int idx;
try {
while ((line = reader.readLine()) != null) {
if (line.length() > 3 && line.charAt(0) == '[' && (idx = line.indexOf(']')) > 1) {
if (snipName.length() > 0 || stringBuilder.length() > 0) result.put(snipName, stringBuilder.toString());
stringBuilder.setLength(0);
snipName = line.substring(1, idx);
} else
stringBuilder.append(line.trim()).append("\r\n");
}
} catch (IOException e) {
throw new GdxRuntimeException(e);
}
if (snipName.length() > 0 || stringBuilder.length() > 0) result.put(snipName, stringBuilder.toString());
return result;
}
@Override
public String toString () {
stringBuilder.setLength(0);
for (final ObjectMap.Entry<String, ObjectMap<String, String>> entry : snippets.entries()) {
stringBuilder.append(entry.key).append(": {");
for (final String snipname : entry.value.keys())
stringBuilder.append(snipname).append(", ");
stringBuilder.append("}\n");
}
return stringBuilder.toString();
}
}