Package codeanticode.glgraphics

Source Code of codeanticode.glgraphics.GLModelEffect

/**
* Part of the GLGraphics library: http://glgraphics.sourceforge.net/
* Copyright (c) 2008-11 Andres Colubri
*
* This source 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 2 of the License, or
* (at your option) any later version.
*
* This code 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.
*
* A copy of the GNU General Public License is available on the World
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also
* obtain it by writing to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

package codeanticode.glgraphics;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import javax.media.opengl.GL;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.opengl.PGraphicsOpenGL;
import processing.xml.XMLElement;

public class GLModelEffect implements PConstants {
  protected PApplet parent;
  protected String description;
  protected GL gl;
  protected PGraphicsOpenGL pgl;
  protected GLState glstate;
  protected GLSLShader shader;
  protected String vertexFN;
  protected String geometryFN;
  protected String fragmentFN;
  protected String inGeoPrim;
  protected String outGeoPrim;
  protected int maxNumOutVert;
  protected int numTextures;
  protected HashMap<String, Integer> texHashMap;
  protected int[] texUnitUniform;
  protected String[] texNameArray;
  protected int numParams;
  protected HashMap<String, GLModelEffectParameter> paramsHashMap; 
  protected GLModelEffectParameter[] paramsArray;
  protected int numVertAttribs;
  protected HashMap<String, GLModelEffectVertexAttrib> vertAttribHashMap;
  protected GLModelEffectVertexAttrib[] vertAttribArray;
 
  public GLModelEffect() {
    this.parent = null;
  }

  public GLModelEffect(PApplet parent, String filename) {
    this.parent = parent;
    initEffect(filename);
  }

  /**
   * Creates an instance of GLTextureFilter, loading the filter from a URL.
   */
  public GLModelEffect(PApplet parent, URL url) {
    this.parent = parent;
    initEffect(url);
  }
 
  public void delete() {
    shader.delete();   
  }

  /**
   * Returns the description of the filter.
   *
   * @return String
   */
  public String getDescription() {
    return description;
  }

  public void apply(GLModel model) {
    model.render(this);
  }

  public void apply(GLModel[] models) {
    for (int i = 0; i < models.length; i++)
      models[i].render(this);
  }

  public void start() {
    shader.start();

    for (int i = 0; i < numParams; i++)
      paramsArray[i].copyToShader();
  }

  public void stop() {
    shader.stop();
  }

  public void setTextures(GLTexture[] textures) {
    for (int i = 0; i < textures.length; i++) {
      if (-1 < texUnitUniform[i]) {
        String name = textures[i].getName();
        if (!name.equals("") && texHashMap.containsKey(name)) {
          Integer texUnit = (Integer)texHashMap.get(name);
          gl.glUniform1iARB(texUnitUniform[i], texUnit);          
        } else {
           // The texture doesn't have a name so assuming
          // the texture unit is just i.
          gl.glUniform1iARB(texUnitUniform[i], i);
        }       
      }
    }
  }

  public void setVertexAttribs(int[] attribVBO, String[] attribName, int[] attribSize) {
    for (int i = 0; i < numVertAttribs; i++) {
      String name = attribName[i];
      gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, attribVBO[i]);
      if (!name.equals("") && vertAttribHashMap.containsKey(name)) {
        GLModelEffectVertexAttrib attribute = (GLModelEffectVertexAttrib)vertAttribHashMap.get(name);
        attribute.setAttribArrayPointer(attribSize[i], false, 0);
      } else {
        vertAttribArray[i].setAttribArrayPointer(attribSize[i], false, 0);
      }
    }
  }

  public void enableVertexAttribs() {
    for (int i = 0; i < numVertAttribs; i++) {
      vertAttribArray[i].enableVertexAttribArray();
    }
  }

  public void disableVertexAttribs() {
    for (int i = 0; i < numVertAttribs; i++) {
      vertAttribArray[i].disableVertexAttribArray();
    }
  }

  /**
   * Sets the parameter value when the type is int.
   *
   * @param String paramName
   * @param int value
   */
  public void setParameterValue(String paramName, int value) {
    if (paramsHashMap.containsKey(paramName)) {
      GLModelEffectParameter param = (GLModelEffectParameter) paramsHashMap
          .get(paramName);
      param.setValue(value);
    }
  }

  /**
   * Sets the parameter value when the type is float.
   *
   * @param String paramName
   * @param float value
   */
  public void setParameterValue(String paramName, float value) {
    if (paramsHashMap.containsKey(paramName)) {
      GLModelEffectParameter param = (GLModelEffectParameter) paramsHashMap
          .get(paramName);
      param.setValue(value);
    }
  }

  /**
   * Sets the parameter value for any type. When the type is int or float, the
   * first element of the value array is considered.
   *
   * @param String paramName
   * @param value float[]
   */
  public void setParameterValue(String paramName, float[] value) {
    if (paramsHashMap.containsKey(paramName)) {
      GLModelEffectParameter param = (GLModelEffectParameter) paramsHashMap
          .get(paramName);
      param.setValue(value);
    }
  }

  /**
   * Sets the ith value for the parameter (only valid for vec or mat types).
   *
   * @param String paramName
   * @param int i
   * @param value float
   */
  public void setParameterValue(String paramName, int i, float value) {
    if (paramsHashMap.containsKey(paramName)) {
      GLModelEffectParameter param = (GLModelEffectParameter) paramsHashMap
          .get(paramName);
      param.setValue(i, value);
    }
  }

  /**
   * Sets the (ith, jth) value for the parameter (only valid for mat types).
   *
   * @param String paramName
   * @param int i
   * @param int j
   * @param value float
   */
  public void setParameterValue(String paramName, int i, int j, float value) {
    if (paramsHashMap.containsKey(paramName)) {
      GLModelEffectParameter param = (GLModelEffectParameter) paramsHashMap
          .get(paramName);
      param.setValue(i, j, value);
    }
  }

  /**
   * Sets all the value for all the parameters, by means of a parameter list of
   * variable length. values is an array of float[].
   *
   * @param float[] values
   */
  public void setParameterValues(float[]... values) {
    float[] value;
    for (int i = 0; i < values.length; i++) {
      value = values[i];
      paramsArray[i].setValue(value);
    }
  }

  /**
   * Get number of parameters.
   *
   * @return int
   */
  public int getParameterCount() {
    return numParams;
  }

  /**
   * Returns the type of the i-th parameter.
   *
   * @return int
   */
  public int getParameterType(int i) {
    return paramsArray[i].getType();
  }

  /**
   * Returns the name of the i-th parameter.
   *
   * @return String
   */
  public String getParameterName(int i) {
    return paramsArray[i].getName();
  }

  /**
   * Returns the label of the i-th parameter.
   *
   * @return String
   */
  public String getParameterLabel(int i) {
    return paramsArray[i].getLabel();
  }

  /**
   * Returns the i-th parameter.
   *
   * @return GLModelEffectParameter
   */
  public GLModelEffectParameter getParameter(int i) {
    return paramsArray[i];
  }

  /**
   * Sets the parameter value when the type is int.
   *
   * @param int n
   * @param int value
   */
  public void setParameterValue(int n, int value) {
    paramsArray[n].setValue(value);
  }

  /**
   * Sets the parameter value when the type is float.
   *
   * @param int n
   * @param float value
   */
  public void setParameterValue(int n, float value) {
    paramsArray[n].setValue(value);
  }

  /**
   * Sets the parameter value for any type. When the type is int or float, the
   * first element of the value array is considered.
   *
   * @param int n
   * @param value float[]
   */
  public void setParameterValue(int n, float[] value) {
    paramsArray[n].setValue(value);
  }

  /**
   * Sets the ith value for the parameter (only valid for vec or mat types).
   *
   * @param int n
   * @param int i
   * @param value float
   */
  public void setParameterValue(int n, int i, float value) {
    paramsArray[n].setValue(i, value);
  }

  /**
   * Sets the (ith, jth) value for the parameter (only valid for mat types).
   *
   * @param int n
   * @param int i
   * @param int j
   * @param value float
   */
  public void setParameterValue(int n, int i, int j, float value) {
    paramsArray[n].setValue(i, j, value);
  }

  /**
   * Returns the parameter with the provided name.
   *
   * @return GLModelEffectParameter
   */
  public GLModelEffectParameter getParameter(String paramName) {
    if (paramsHashMap.containsKey(paramName)) {
      GLModelEffectParameter param = (GLModelEffectParameter) paramsHashMap
          .get(paramName);
      return param;
    }
    return null;
  }

  /**
   * @invisible
   */
  protected void initEffect(String filename) {
    initEffectCommon();

    filename = filename.replace('\\', '/');
    XMLElement xml = new XMLElement(parent, filename);

    loadXML(xml);

    initShader(filename, false);
  }

  /**
   * @invisible
   */
  protected void initEffect(URL url) {
    initEffectCommon();

    try {
      String xmlText = PApplet
          .join(PApplet.loadStrings(url.openStream()), "\n");
      XMLElement xml = new XMLElement(xmlText);
      loadXML(xml);
    } catch (IOException e) {
      System.err.println("Error loading effect: " + e.getMessage());
    }

    initShader(url.toString(), true);
  }

  /**
   * Common initialization code
   *
   * @invisible
   */
  private void initEffectCommon() {
    pgl = (PGraphicsOpenGL) parent.g;
    gl = pgl.gl;

    glstate = new GLState(gl);

    numTextures = 0;
    texHashMap = new HashMap<String, Integer>();
    texUnitUniform = null;
    texNameArray = null;

    numParams = 0;
    paramsHashMap = new HashMap<String, GLModelEffectParameter>();
    paramsArray = null;

    numVertAttribs = 0;
    vertAttribHashMap = new HashMap<String, GLModelEffectVertexAttrib>();
    vertAttribArray = null;
  }

  protected void loadXML(XMLElement xml) {
    // Parsing xml configuration.

    int n = xml.getChildCount();
    String name;
    XMLElement child;
    vertexFN = geometryFN = fragmentFN = "";
    for (int i = 0; i < n; i++) {
      child = xml.getChild(i);
      name = child.getName();
      if (name.equals("description")) {
        description = child.getContent();
      } else if (name.equals("vertex")) {
        // vertexFN = fixShaderFilename(child.getContent(), rootPath);
        vertexFN = child.getContent();
      } else if (name.equals("geometry")) {
        // geometryFN = fixShaderFilename(child.getContent(), rootPath);
        geometryFN = child.getContent();
        inGeoPrim = child.getString("input");
        outGeoPrim = child.getString("output");
        maxNumOutVert = child.getInt("vertcount");
      } else if (name.equals("fragment")) {
        // fragmentFN = fixShaderFilename(child.getContent(), rootPath);
        fragmentFN = child.getContent();
      } else if (name.equals("textures")) {
        loadTextures(child);
      } else if (name.equals("vertexattribs")) {
        loadVertAttribs(child);
      } else if (name.equals("parameters")) {
        loadParams(child);
      } else {
        System.err.println("Unrecognized element in effect config file!");
      }
    }   
  }

  protected void loadTextures(XMLElement xml) {
    int n = xml.getChildCount();
    numTextures = n;
    texNameArray = new String[numTextures];
    texUnitUniform = new int[numTextures];

    XMLElement child;
    String name, texName, valueStr;
    int texUnit;
    for (int i = 0; i < n; i++) {
      child = xml.getChild(i);
      name = child.getName();
      if (name.equals("texture")) {
        texName = child.getString("name");
        valueStr = child.getContent();
        texUnit = PApplet.parseInt(PApplet.split(valueStr, ' '))[0];
        texHashMap.put(texName, new Integer(texUnit));
        texNameArray[i] = texName;
      }
    }
  }

  protected void loadVertAttribs(XMLElement xml) {
    int n = xml.getChildCount();
    numVertAttribs = n;
    vertAttribArray = new GLModelEffectVertexAttrib[numVertAttribs];

    XMLElement child;
    String name;
    String attrName, attrTypeStr, attrValueStr, attrLabelStr;
    int attrType;
    GLModelEffectVertexAttrib attrib;
    for (int i = 0; i < n; i++) {
      child = xml.getChild(i);
      name = child.getName();
      if (name.equals("vertexattrib")) {
        float[] attrValue;
        attrName = child.getString("name");
        attrTypeStr = child.getString("type");
        attrLabelStr = child.getString("label");
        attrValueStr = child.getContent();
        attrType = GLModelEffectVertexAttrib.getType(attrTypeStr);

        attrValue = PApplet.parseFloat(PApplet.split(attrValueStr, ' '));

        if ((-1 < attrType) && !paramsHashMap.containsKey(attrName)) {
          attrib = new GLModelEffectVertexAttrib(parent, attrName,
              attrLabelStr, attrType);
          attrib.setValue(attrValue);
          vertAttribHashMap.put(attrName, attrib);
          vertAttribArray[i] = attrib;
        }
      }
    }
  }

  protected void loadParams(XMLElement xml) {
    int n = xml.getChildCount();
    numParams = n;
    paramsArray = new GLModelEffectParameter[numParams];

    XMLElement child;
    String name;
    String parName, parTypeStr, parValueStr, parLabelStr;
    int parType;
    GLModelEffectParameter param;
    for (int i = 0; i < n; i++) {
      child = xml.getChild(i);
      name = child.getName();
      if (name.equals("parameter")) {
        float[] parValue;
        parName = child.getString("name");
        parTypeStr = child.getString("type");
        parLabelStr = child.getString("label");
        parValueStr = child.getContent();
        parType = GLModelEffectParameter.getType(parTypeStr);

        parValue = PApplet.parseFloat(PApplet.split(parValueStr, ' '));

        if ((-1 < parType) && !paramsHashMap.containsKey(parName)) {
          param = new GLModelEffectParameter(parent, parName, parLabelStr, parType, parValue.length);
          param.setValue(parValue);
          paramsHashMap.put(parName, param);
          paramsArray[i] = param;
        }
      }
    }
  }

  /**
   * @invisible
   */
  String fixShaderFilename(String filename, String rootPath) {
    String fixedFN = filename.replace('\\', '/');
    if (!rootPath.equals("") && (fixedFN.indexOf(rootPath) != 0))
      fixedFN = rootPath + fixedFN;
    return fixedFN;
  }

  /**
   * Initialize the GLSLShader object.
   *
   * @param xmlFilename
   *          the XML filename for this filter, used to generate the proper path
   *          for the shader's programs
   * @param useURL
   *          if true, URL objects will be created to load the shader programs
   *          instead of direct filenames
   * @invisible
   */
  protected void initShader(String xmlFilename, boolean useURL) {
    // Getting the root path of the xml file
    int idx;
    boolean usingGeom = false;
    String rootPath = "";
    idx = xmlFilename.lastIndexOf('/');
    if (-1 < idx) {
      rootPath = xmlFilename.substring(0, idx + 1);
    }

    // Initializing shader.
    shader = new GLSLShader(parent);

    if (!vertexFN.equals("")) {
      vertexFN = fixShaderFilename(vertexFN, rootPath);
      if (useURL) {
        try {
          shader.loadVertexShader(new URL(vertexFN));
        } catch (MalformedURLException e) {
          System.err.println(e.getMessage());
        }
      } else
        shader.loadVertexShader(vertexFN);
    }

    if (!geometryFN.equals("")) {
      geometryFN = fixShaderFilename(geometryFN, rootPath);
      if (useURL) {
        try {
          shader.loadGeometryShader(new URL(geometryFN));
        } catch (MalformedURLException e) {
          System.err.println(e.getMessage());
        }
      } else {
        shader.loadGeometryShader(geometryFN);
      }
      usingGeom = true;     
    }

    if (!fragmentFN.equals("")) {
      fragmentFN = fixShaderFilename(fragmentFN, rootPath);
      if (useURL) {
        try {
          shader.loadFragmentShader(new URL(fragmentFN));
        } catch (MalformedURLException e) {
          System.err.println(e.getMessage());
        }
      } else
        shader.loadFragmentShader(fragmentFN);
    }

    if (usingGeom) {
      shader.setupGeometryShader(inGeoPrim, outGeoPrim, maxNumOutVert);
    } else {
      shader.setup();
    }

    for (int i = 0; i < numTextures; i++) {
      texUnitUniform[i] = shader.getUniformLocation(texNameArray[i]);
    }

    // Generating the parameter IDs.
    for (int i = 0; i < numParams; i++) {
      paramsArray[i].setShader(shader);
      paramsArray[i].init();
    }

    // Generating the vertex attribute IDs.
    for (int i = 0; i < numVertAttribs; i++) {
      vertAttribArray[i].setShader(shader);
      vertAttribArray[i].init();
    }
  }
}
TOP

Related Classes of codeanticode.glgraphics.GLModelEffect

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.