不能链接编译着色器的OpenGL ES 2.0编程Android版 [英] Can't link compiled shaders to program OpenGL ES 2.0 Android

查看:672
本文介绍了不能链接编译着色器的OpenGL ES 2.0编程Android版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个链接着色器OpenGL ES 2.0的编程问题。
这里是我的code

I have a problem with linking shaders to program in OpenGL ES 2.0. Here's my code

package pl.projekcik;

import android.content.Context;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.logging.Logger;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import util.LoggerConfig;
import util.ShaderHelper;
import util.TextResourceReader;

import static android.opengl.GLES20.*;
import static android.opengl.GLUtils.*;
import static android.opengl.Matrix.*;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.util.Log;

public class ProjekcikRenderer implements Renderer {

private static final int POSITION_COMPONENT_COUNT = 3;
private static final int BYTES_PER_FLOAT = 4;
private final FloatBuffer vertexData;
private final Context context;
private int program;
private static final String U_COLOR = "u_COLOR";
private int uColorLocation;
private static final String A_POSITION = "a_Position";
private int aPositionLocation;
private static final String TAG = "ProjekcikRenderer";

public ProjekcikRenderer(Context context){
    this.context = context;
    float[] tableVertices = {
        0f, 0f, 0f,
        1f, 1f, 0f,
        0f, 1f, 0f,

        0f, 0f, 0f,
        1f, 0f, 0f,
        1, 1f, 0f
    };

    vertexData = ByteBuffer
            .allocateDirect(tableVertices.length * BYTES_PER_FLOAT)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer();

    vertexData.put(tableVertices);
}

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config){
    glClearColor(1.0f, 1.0f, 0.5f, 0.0f);
    String vertexShaderSource = null;
    String fragmentShaderSource = null;
    try{
        vertexShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.simple_vertex_shader);
        fragmentShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.simple_fragment_shader);
    } catch (IOException e){
        throw new RuntimeException("IOException", e);
    } catch (Exception e){
        throw new RuntimeException("Other Exception", e);
    }

    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    Log.d(TAG, "CREATING VERTEX SHADER");
    String s = new String(Integer.toString(vertexShader));
    if(vertexShader == 0){
        if(LoggerConfig.ON){
            Log.w(TAG, "Could not create new VERTEX shader");
        }
        return;
    } else {
        if(LoggerConfig.ON){
            Log.w(TAG, s);
        }
    }
    GLES20.glShaderSource(vertexShader, vertexShaderSource);
    GLES20.glCompileShader(vertexShader);
    final int[] compileStatus = new int[1];
    GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);
    if(LoggerConfig.ON){
        Log.v(TAG, "Results of compiling source:" + "\n" + vertexShaderSource + "\n" + glGetShaderInfoLog(vertexShader));
    }
    if(compileStatus[0] == 0){
        glDeleteShader(vertexShader);
        if(LoggerConfig.ON){
            Log.w(TAG, "Compilation of shader failed");
        }
        return;
    } else {
        if(LoggerConfig.ON){
            Log.v(TAG, "VERTEX SHADER COMPILED");
        }
    }

    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    Log.d(TAG, "CREATING FRAGMENT SHADER");
    s = new String(Integer.toString(fragmentShader));
    if(fragmentShader == 0){
        if(LoggerConfig.ON){
            Log.w(TAG, "Could not create new FRAGMENT shader");
        }
        return;
    } else {
        if(LoggerConfig.ON){
            Log.w(TAG, s);
        }
    }
    GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
    GLES20.glCompileShader(vertexShader);
    GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);
    if(LoggerConfig.ON){
        Log.v(TAG, "Results of compiling source:" + "\n" + fragmentShaderSource + "\n" + glGetShaderInfoLog(fragmentShader));
    }
    if(compileStatus[0] == 0){
        glDeleteShader(fragmentShader);
        if(LoggerConfig.ON){
            Log.w(TAG, "Compilation of shader failed");
        }
        return;
    } else {
        if(LoggerConfig.ON){
            Log.v(TAG, "FRAGMENT SHADER COMPILED");
        }
    }

    program = GLES20.glCreateProgram();
    s = new String(Integer.toString(program));
    Log.v("PROGRAM ID: ", s);
    if(program == 0){
        if(LoggerConfig.ON){
            Log.w(TAG, "Could not create new program");
        }
        return;
    }

    try{
        GLES20.glAttachShader(program, vertexShader);
        GLES20.glAttachShader(program, fragmentShader);
    } catch (Exception e){
        Log.w("ATTACH", "COULD NOT ATTACH 1 OR MORE SHADERS");
    }

    try{
        GLES20.glLinkProgram(program);
    } catch (Exception e){
        Log.w("LINK", "Link program failed");
    }


    final int[] linkStatus = new int[1];
    glGetProgramiv(program, GL_LINK_STATUS, linkStatus, 0);
    if(LoggerConfig.ON){
        Log.v(TAG, "Results of linking program:\n" + glGetProgramInfoLog(program));
    }
    if(linkStatus[0] == 0){
        glDeleteProgram(program);
        if(LoggerConfig.ON){
            Log.w(TAG, "Linking of program failed");
        }
        return;
    }

    if(LoggerConfig.ON){
        validateProgram(program);
    }

    glUseProgram(program);

    uColorLocation = glGetUniformLocation(program, U_COLOR);
    aPositionLocation = glGetAttribLocation(program, A_POSITION);
    vertexData.position(0);
    glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData);
    glEnableVertexAttribArray(aPositionLocation);
}

@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height){
    glViewport(0, 0, width, height);
}

@Override
public void onDrawFrame(GL10 glUnused){
    glClear(GL_COLOR_BUFFER_BIT);
    glUniform4f(uColorLocation, 0.0f, 0.0f, 0.0f, 1.0f);
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

public static boolean validateProgram(int programObjectId){
    glValidateProgram(programObjectId);

    final int[] validateStatus = new int[1];
    glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
    Log.v(TAG, "Results of validating program: " + validateStatus[0] + "\nLog: " + glGetProgramInfoLog(programObjectId));
    return validateStatus[0] != 0;
}

}

问题是,成功地后编制我想我的着色器连接到我的程序着色器。它看起来像OT的附加着色器,但是连接不。下面是该操作的日志:

The problem is, after succesfully compiling shaders I'm trying to attach my shaders to my program. It looks like ot's attaching shaders, but linking doesn't. Here's log of from this operation:

08-12 11:24:10.330  23044-23044/pl.projekcik D/libEGL﹕ loaded /system/lib/egl/libEGL_mali.so
08-12 11:24:10.330  23044-23044/pl.projekcik D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_mali.so
08-12 11:24:10.340  23044-23044/pl.projekcik D/libEGL﹕ loaded /system/lib/egl/libGLESv2_mali.so
08-12 11:24:10.350  23044-23044/pl.projekcik D/OpenGLRenderer﹕ Enabling debug mode 0
08-12 11:24:10.420  23044-23057/pl.projekcik D/ProjekcikRenderer﹕ CREATING VERTEX SHADER
08-12 11:24:10.420  23044-23057/pl.projekcik W/ProjekcikRenderer﹕ 1
08-12 11:24:10.420  23044-23057/pl.projekcik V/ProjekcikRenderer﹕ Results of compiling source:
    attribute highp vec4 a_Position;
    void main(){
    gl_Position = a_Position;
    }
08-12 11:24:10.420  23044-23057/pl.projekcik V/ProjekcikRenderer﹕ VERTEX SHADER COMPILED
08-12 11:24:10.420  23044-23057/pl.projekcik D/ProjekcikRenderer﹕ CREATING FRAGMENT SHADER
08-12 11:24:10.420  23044-23057/pl.projekcik W/ProjekcikRenderer﹕ 2
08-12 11:24:10.420  23044-23057/pl.projekcik V/ProjekcikRenderer﹕ Results of compiling source:
    precision mediump float;
    uniform vec4 u_Color;
    void main(){
    gl_FragColor = u_Color;
    }
08-12 11:24:10.420  23044-23057/pl.projekcik V/ProjekcikRenderer﹕ FRAGMENT SHADER COMPILED
08-12 11:24:10.420  23044-23057/pl.projekcik V/PROGRAM ID:﹕ 3
08-12 11:24:10.420  23044-23057/pl.projekcik V/ProjekcikRenderer﹕ Results of linking program:
    L0101 All attached shaders must be compiled prior to linking
08-12 11:24:10.420  23044-23057/pl.projekcik W/ProjekcikRenderer﹕ Linking of program failed
08-12 11:24:10.430  23044-23046/pl.projekcik D/dalvikvm﹕ GC_CONCURRENT freed 270K, 8% free 6260K/6791K, paused 17ms+4ms, total 81ms

任何帮助将大大AP preciated

Any help would be greatly appreciated

推荐答案

您的问题就在这里:

GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
GLES20.glCompileShader(vertexShader); 
GLES20.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, compileStatus, 0);

您正在编译vertexShader代替fragmentShader,所以vertexShader是越来越编译两次,fragmentShader是没有得到根本编译。

You're compiling the vertexShader instead of the fragmentShader, so the vertexShader is getting compiled twice, and the fragmentShader isn't getting compiled at all.

这篇关于不能链接编译着色器的OpenGL ES 2.0编程Android版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆