glslshaderobjectsstate.java

来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 917 行 · 第 1/3 页

JAVA
917
字号
     *
     * @param name attribute variable to change
     * @param size Specifies the number of values for each element of the
     * generic vertex attribute array. Must be 1, 2, 3, or 4.
     * @param normalized Specifies whether fixed-point data values should be
     * normalized or converted directly as fixed-point values when they are
     * accessed.
     * @param unsigned Specifies wheter the data is signed or unsigned
     * @param stride Specifies the byte offset between consecutive attribute
     * values. If stride is 0 (the initial value), the attribute values are
     * understood to be tightly packed in the array.
     * @param data The actual data to use as attribute pointer
     */
    public void setAttributePointer(String name, int size, boolean normalized,
            boolean unsigned, int stride, IntBuffer data) {
        ShaderVariablePointerInt shaderUniform =
                getShaderAttribute(name, ShaderVariablePointerInt.class);
        shaderUniform.size = size;
        shaderUniform.normalized = normalized;
        shaderUniform.unsigned = unsigned;
        shaderUniform.stride = stride;
        shaderUniform.data = data;

        setNeedsRefresh(true);
    }

    /**
     * Set an attribute pointer value for this shader object.
     *
     * @param name attribute variable to change
     * @param size Specifies the number of values for each element of the
     * generic vertex attribute array. Must be 1, 2, 3, or 4.
     * @param normalized Specifies whether fixed-point data values should be
     * normalized or converted directly as fixed-point values when they are
     * accessed.
     * @param unsigned Specifies wheter the data is signed or unsigned
     * @param stride Specifies the byte offset between consecutive attribute
     * values. If stride is 0 (the initial value), the attribute values are
     * understood to be tightly packed in the array.
     * @param data The actual data to use as attribute pointer
     */
    public void setAttributePointer(String name, int size, boolean normalized,
            boolean unsigned, int stride, ShortBuffer data) {
        ShaderVariablePointerShort shaderUniform =
                getShaderAttribute(name, ShaderVariablePointerShort.class);
        shaderUniform.size = size;
        shaderUniform.normalized = normalized;
        shaderUniform.unsigned = unsigned;
        shaderUniform.stride = stride;
        shaderUniform.data = data;

        setNeedsRefresh(true);
    }

    /**
     * <code>clearAttributes</code> clears all attribute values from this
     * state.
     */
    public void clearAttributes() {
        shaderAttributes.clear();
    }


    /**
     * @return RS_SHADER_OBJECTS
     * @see com.jme.scene.state.RenderState#getType()
     * @deprecated As of 2.0, use {@link RenderState#getStateType()} instead.
     */
    public int getType() {
        return RS_GLSL_SHADER_OBJECTS;
    }

    /**
     * <code>getStateType</code> returns the type {@link RenderState.StateType#GLSLShaderObjects}
     * 
     * @return {@link RenderState.StateType#GLSLShaderObjects}
     * @see com.jme.scene.state.RenderState#getStateType()
     */
    public StateType getStateType() {
    	
        return StateType.GLSLShaderObjects;
    }

    /**
     * Creates or retrieves a uniform shadervariable.
     *
     * @param name Name of the uniform shadervariable to retrieve or create
     * @param classz Class type of the shadervariable
     * @return
     */
    private <T extends ShaderVariable> T getShaderUniform(String name,
            Class<T> classz) {
        T shaderVariable = getShaderVariable(name, classz, shaderUniforms);
        checkUniformSizeLimits();
        return shaderVariable;
    }

    /**
     * Creates or retrieves a attribute shadervariable.
     *
     * @param name Name of the attribute shadervariable to retrieve or create
     * @param classz Class type of the shadervariable
     * @return
     */
    private <T extends ShaderVariable> T getShaderAttribute(String name,
            Class<T> classz) {
        T shaderVariable = getShaderVariable(name, classz, shaderAttributes);
        checkAttributeSizeLimits();
        return shaderVariable;
    }

    /**
     * @param name Name of the shadervariable to retrieve or create
     * @param classz Class type of the shadervariable
     * @param shaderVariableList List retrieve shadervariable from
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T extends ShaderVariable> T getShaderVariable(String name,
            Class<T> classz, ArrayList<ShaderVariable> shaderVariableList) {
        for (int i = shaderVariableList.size(); --i >= 0;) {
            ShaderVariable temp = shaderVariableList.get(i);
            if (name.equals(temp.name)) {
                temp.needsRefresh = true;
                return (T) temp;
            }
        }

        try {
            T shaderUniform = classz.newInstance();
            shaderUniform.name = name;
            shaderVariableList.add(shaderUniform);

            return shaderUniform;
        } catch (InstantiationException e) {
            logger.logp(Level.SEVERE, this.getClass().toString(),
                    "getShaderVariable(name, classz, shaderVariableList)", "Exception", e);
        } catch (IllegalAccessException e) {
            logger.logp(Level.SEVERE, this.getClass().toString(),
                    "getShaderVariable(name, classz, shaderVariableList)", "Exception", e);
        }

        return null;
    }

    /**
     * Check if we are keeping the size limits in terms of uniform locations
     * on the card.
     */
    public void checkUniformSizeLimits() {
        // Implement in provider
    }

    /**
     * Check if we are keeping the size limits in terms of attribute locations
     * on the card.
     */
    public void checkAttributeSizeLimits() {
        // Implement in provider
    }

    /**
     * Loads shader from URL
     * 
     * @param url
     * @return
     */
    private String load(URL url) {
        BufferedReader r = null;
        try {
            r = new BufferedReader(new InputStreamReader(url.openStream()));
            StringBuffer buf = new StringBuffer();
            while (r.ready()) {
                buf.append(r.readLine()).append('\n');
            }
            r.close();
            return buf.toString();
        } catch (IOException e) {
            logger.severe("Could not load shader program: " + e);
            logger.logp(Level.SEVERE, getClass().getName(), "load(URL)", "Exception", e);
            return null;
        }
    }
    
    /**
     * <code>load</code> loads the shader object from the specified file. The
     * program must be in ASCII format. The implementation must
     * convert the String into data compatible with the graphics library.
     *
     * @param vert text file containing the vertex shader object
     * @param frag text file containing the fragment shader object
     */
    public void load(URL vert, URL frag){
        vertShader = vert != null ? load(vert) : null;
        fragShader = frag != null ? load(frag) : null;
        needSendShader = true;
    }

    /**
     * <code>load</code> loads the shader object from the specified file. The
     * program must be in ASCII format. The implementation must
     * convert the String into data compatible with the graphics library.
     *
     * @param vert The input stream from which the vertex shader can be read
     * @param frag The input stream from which the fragment shader can be read
     */
    public void load(InputStream vert, InputStream frag) {
        ByteBuffer vertexByteBuffer = vert != null ? load(vert) : null;
        ByteBuffer fragmentByteBuffer = frag != null ? load(frag) : null;
        sendToGL(vertexByteBuffer, fragmentByteBuffer);
	}
    
    /**
     * <code>load</code> loads the shader object from the specified string. The
     * program must be in ASCII format. We delegate the loading to each
     * implementation because we do not know in what format the underlying API
     * wants the data.
     *
     * @param vert string containing the vertex shader object
     * @param frag string containing the fragment shader object
     */
    public void load(String vert, String frag){
        vertShader = vert;
        fragShader = frag;
        needSendShader = true;
    }

    public void write(JMEExporter e) throws IOException {
        super.write(e);
        OutputCapsule capsule = e.getCapsule(this);
        capsule.writeSavableArrayList(shaderUniforms, "shaderUniforms",
                new ArrayList<ShaderVariable>());
        capsule.writeSavableArrayList(shaderAttributes, "shaderAttributes",
                new ArrayList<ShaderVariable>());
    }

    @SuppressWarnings ("unchecked")
    public void read(JMEImporter e) throws IOException {
        super.read(e);
        InputCapsule capsule = e.getCapsule(this);
        shaderUniforms = capsule.readSavableArrayList("shaderUniforms",
                new ArrayList<ShaderVariable>());
        shaderAttributes = capsule.readSavableArrayList("shaderAttributes",
                new ArrayList<ShaderVariable>());
    }

    public Class<? extends GLSLShaderObjectsState> getClassTag() {
        return GLSLShaderObjectsState.class;
    }
    
    /**
     * Loads the shader object. Use null for an empty vertex or empty fragment
     * shader.
     *
     * @param vertexByteBuffer vertex shader
     * @param fragmentByteBuffer fragment shader
     * @see com.jme.scene.state.GLSLShaderObjectsState#load(java.net.URL,
     *java.net.URL)
     */
    protected abstract void sendToGL(ByteBuffer vertexByteBuffer,
            						 ByteBuffer fragmentByteBuffer); 
    
    /**
     * Load an URL and grab content into a ByteBuffer.
     *
     * @param in The input stream to read
     * @return the loaded url
     */
    protected ByteBuffer load(InputStream in) {
        DataInputStream dataStream = null;
        try {
            BufferedInputStream bufferedInputStream =
                    new BufferedInputStream(in);
            dataStream =
                    new DataInputStream(bufferedInputStream);
            byte shaderCode[] = new byte[bufferedInputStream.available()];
            dataStream.readFully(shaderCode);
            bufferedInputStream.close();
            dataStream.close();
            ByteBuffer shaderByteBuffer =
                    BufferUtils.createByteBuffer(shaderCode.length);
            shaderByteBuffer.put(shaderCode);
            shaderByteBuffer.rewind();

            return shaderByteBuffer;
        } catch (Exception e) {
            logger.severe("Could not load shader object: " + e);
            logger.logp(Level.SEVERE, getClass().getName(), "load(URL)", "Exception", e);
            return null;
        }
        finally {
            // Ensure that the stream is closed, even if there is an exception.
            if (dataStream != null) {
                try {
                    dataStream.close();
                } catch (IOException closeFailure) {
                    logger.log(Level.WARNING,
                            "Failed to close the shader object",
                            closeFailure);
                }
            }
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?