package codechicken.lib.render; import java.util.ArrayList; import codechicken.lib.render.CCRenderState.IVertexOperation; import codechicken.lib.render.CCRenderState.VertexAttribute; public class CCRenderPipeline { public class PipelineBuilder { public PipelineBuilder add(IVertexOperation op) { ops.add(op); return this; } public PipelineBuilder add(IVertexOperation... ops) { for(int i = 0; i < ops.length; i++) CCRenderPipeline.this.ops.add(ops[i]); return this; } public void build() { rebuild(); } public void render() { rebuild(); CCRenderState.render(); } } private class PipelineNode { public ArrayList deps = new ArrayList(); public IVertexOperation op; public void add() { if(op == null) return; for(int i = 0; i < deps.size(); i++) deps.get(i).add(); deps.clear(); sorted.add(op); op = null; } } private ArrayList attribs = new ArrayList(); private ArrayList ops = new ArrayList(); private ArrayList nodes = new ArrayList(); private ArrayList sorted = new ArrayList(); private PipelineNode loading; private PipelineBuilder builder = new PipelineBuilder(); public void setPipeline(IVertexOperation... ops) { this.ops.clear(); for(int i = 0; i < ops.length; i++) this.ops.add(ops[i]); rebuild(); } public void reset() { ops.clear(); unbuild(); } private void unbuild() { for(int i = 0; i < attribs.size(); i++) attribs.get(i).active = false; attribs.clear(); sorted.clear(); } public void rebuild() { if(ops.isEmpty() || CCRenderState.model == null) return; //ensure enough nodes for all ops while(nodes.size() < CCRenderState.operationCount()) nodes.add(new PipelineNode()); unbuild(); if(CCRenderState.useNormals) addAttribute(CCRenderState.normalAttrib); if(CCRenderState.baseColour != -1 || CCRenderState.alphaOverride >= 0) addAttribute(CCRenderState.colourAttrib); else if(CCRenderState.hasColour) CCRenderState.setColour(-1); for(int i = 0; i < ops.size(); i++) { IVertexOperation op = ops.get(i); loading = nodes.get(op.operationID()); boolean loaded = op.load(); if(loaded) loading.op = op; if(op instanceof VertexAttribute) if(loaded) attribs.add((VertexAttribute)op); else ((VertexAttribute)op).active = false; } for(int i = 0; i < nodes.size(); i++) nodes.get(i).add(); } public void addRequirement(int opRef) { loading.deps.add(nodes.get(opRef)); } public void addDependency(VertexAttribute attrib) { loading.deps.add(nodes.get(attrib.operationID())); addAttribute(attrib); } public void addAttribute(VertexAttribute attrib) { if(!attrib.active) { ops.add(attrib); attrib.active = true; } } public void operate() { for(int i = 0; i < sorted.size(); i++) sorted.get(i).operate(); } public PipelineBuilder builder() { ops.clear(); return builder; } }