【问题标题】:Error passing vertices to shader将顶点传递给着色器时出错
【发布时间】:2015-01-18 10:41:16
【问题描述】:

我正在开始简单的 2d gles 2.0 android 应用程序。 出于某种奇怪的原因,我总是在屏幕中心得到一个点,而不是传递给着色器的顶点坐标。 我显然做错了什么。想不通是什么。 附言我没有使用任何投影矩阵,因为我需要标准四边形进行绘图。尝试投影 - 没有帮助。

public class TestActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView glv = new GLSurfaceView(this);
        glv.setEGLContextClientVersion(2);
        SimpleRenderer renderer = new SimpleRenderer(this);
        glv.setRenderer(renderer);
        glv.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        setContentView(glv);
    }
}

public class SimpleRenderer implements GLSurfaceView.Renderer {
    private final float[] squareVertices = {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            -1.0f,  1.0f,
            1.0f,  1.0f,
    };
    private FloatBuffer squareBuffer;

    private final Context context;

    private int text_program;
    private int aPositionLocation2;


    public SimpleRenderer(Context context) {
        this.context = context;
        squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).asFloatBuffer();
        squareBuffer.put(squareVertices).position(0);
    }

    public void onDrawFrame(GL10 gl) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(text_program);
        glEnableVertexAttribArray(aPositionLocation2);
        glVertexAttribPointer(aPositionLocation2, 2, GL_FLOAT, false, 0, squareBuffer);
        glDrawArrays(GL_POINTS, 0, 4);
        glDisableVertexAttribArray(aPositionLocation2);

    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        glViewport(0, 0, width, height);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        text_program = ShaderHelper.buildProgram(TextResourceReader.readTextFileFromResource(context, R.raw.texture_vertex_shader),
                TextResourceReader.readTextFileFromResource(context, R.raw.texture_fragment_shader));

        aPositionLocation2 = glGetAttribLocation(text_program, "a_Position");
        glClearColor(0f, 0f, 0f, 0f);
    }
}

public class ShaderHelper {
    private static final String TAG = "ShaderHelper";

    public static int compileVertexShader(String shaderCode) {
        return compileShader(GL_VERTEX_SHADER, shaderCode);
    }

    public static int compileFragmentShader(String shaderCode) {
        return compileShader(GL_FRAGMENT_SHADER, shaderCode);
    }

    private static int compileShader(int type, String shaderCode) {
        final int shaderObjectId = glCreateShader(type);
        if (shaderObjectId == 0) Log.w(TAG, "Shader not created!");
        glShaderSource(shaderObjectId, shaderCode);
        glCompileShader(shaderObjectId);
        final int[] compileStatus = new int[1];
        glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
        Log.v(TAG, "Results of compiling source:" + "\n" + shaderCode + "\n:"
                + glGetShaderInfoLog(shaderObjectId));
        if (compileStatus[0] == 0) {
            // If it failed, delete the shader object.
            glDeleteShader(shaderObjectId);
            Log.w(TAG, "Compilation of shader failed.");
            return 0;
        }
        return shaderObjectId;
    }

    public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
        final int programObjectId = glCreateProgram();
        if (programObjectId == 0) {
            Log.w(TAG, "Could not create new program");
            return 0;
        }
        glAttachShader(programObjectId, vertexShaderId);
        glAttachShader(programObjectId, fragmentShaderId);
        glLinkProgram(programObjectId);
        final int[] linkStatus = new int[1];
        glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
        Log.v(TAG, "Results of linking program:\n"
                + glGetProgramInfoLog(programObjectId));
        if (linkStatus[0] == 0) {
            // If it failed, delete the program object.
            glDeleteProgram(programObjectId);
            Log.w(TAG, "Linking of program failed.");
            return 0;
        }
        return programObjectId;
    }

    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;
    }

    public static int buildProgram(String vertexShaderSource,
                                   String fragmentShaderSource) {
        int program;
        // Compile the shaders.
        int vertexShader = compileVertexShader(vertexShaderSource);
        int fragmentShader = compileFragmentShader(fragmentShaderSource);
        // Link them into a shader program.
        program = linkProgram(vertexShader, fragmentShader);

        validateProgram(program);

        return program;
    }

}

顶点着色器:

attribute vec4 a_Position;

void main()
{
    gl_Position = a_Position;
    gl_PointSize = 10.0;
}

片段着色器:

void main()
{
    gl_FragColor = vec4(1.0,1.0,1.0,1.0);
}

【问题讨论】:

  • 也许有人知道可靠的调试工具来查看着色器中的顶点数据。任何帮助都会很棒。在这个愚蠢的问题上已经花了 2 天时间!
  • 是否至少调用了一次 onSurfaceChanged()?宽度和高度的值是多少?
  • 是的,在onSurfaceCreated()之后调用,width=720 height=1022。
  • 你尝试过其他顶点位置吗? -1.0 和 1.0 将位于屏幕边缘并且可能会被剪裁(尽管这并不能解释中心点)。那么 -0.5 和 0.5 呢?
  • 也许尝试在每个 gl 调用之后添加对 glGetError 的调用,以查看是否有问题。 glVertexAttribPointer 没有在正确的位置发送值,或者 squareBuffer 以某种方式包含零。

标签: android opengl-es glsl opengl-es-2.0 vertex-shader


【解决方案1】:

问题确实在于传递顶点数据:OpenGL 使用本机字节顺序(x86 emu 为小端),但我在 java 中分配了缓冲区(我想是大端),因此损坏的浮点值被传递给顶点着色器。在字节缓冲区中指定字节顺序后一切正常。

squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 2014-11-02
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多