引入可变变量后无法获取属性的属性位置
Cannot get attribute location for attributes after Varying Variable has been introduced
我正在尝试实现一个 ModelViewer,它可以使用逼真的光照可视化三角形。
由于使用 OpenGL ES 1.0 似乎无法实现逼真的照明,而且我需要一种方法来呈现单个彩色对象的深度,因此该项目使用了对我来说是新的 OpenGL ES 2.0。
对象本身由使用以下方法绘制的三角形组成:
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
至于一个测试项目,我设置了简单的着色器,在考虑模型-视图-投影矩阵的情况下绘制对象。在那之后,我的意图是实现照明,但我无法通过第一步。
使用可变变量时,将找不到顶点属性。
删除不同的属性有效,但我需要传递数据。我搜索了好几天如何实现顶点和片段着色器,这些着色器不仅仅在某个位置呈现一个对象。
// VERTEX SHADER CODE
attribute vec4 v_Position;
uniform mat4 u_MVPMatrix;
uniform vec4 u_Color;
varying vec4 v_Color;
void main() {
gl_Position = u_MVPMatrix * v_Position;
v_Color = u_Color;
};
// FRAGMENT SHADER CODE
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
整个Class:
public class Object3D {
private FloatBuffer vertexBuffer;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
// static float triangleCoords[] = { // in counterclockwise order:
// 0.0f, 0.622008459f, 0.0f, // top
// -0.5f, -0.311004243f, 0.0f, // bottom left
// 0.5f, -0.311004243f, 0.0f // bottom right
// };
float[] triangleCoords;
// Set color with red, green, blue and alpha (opacity) values
float[] colors = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
private final String vertexShaderCode =
"attribute vec4 v_Position;" +
"uniform float u_Color" +
"uniform mat4 u_MVPMatrix;" +
// outgoing
"varying vec4 v_Color" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
"gl_Position = u_MVPMatrix * v_Position;" +
"v_Color = u_Color;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"varying vec4 v_Color;" +
"void main() {" +
"gl_FragColor = v_Color;" +
"}";
// Use to access and set the view transformation
private int mMVPMatrixHandle;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private final int vertexCount;
private final int vertexStride;
public Object3D(float[] triangleCoords) {
this.triangleCoords = triangleCoords;
vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
this.colors = new float[4*vertexCount];
for (int i = 0; i < colors.length; i+=4) {
colors[i] = 0.63671875f;
colors[i+1] = 0.76953125f;
colors[i+2] = 0.22265625f;
colors[i+3] = 1.0f;
}
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
// use the device hardware's native byte order
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate
vertexBuffer.position(0);
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glBindAttribLocation(mProgram, 0, "v_Position");
// GLES20.glBindAttribLocation(mProgram, 1, "vColor");
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram);
}
public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "v_Position");
// if (mPositionHandle == -1) {
// throw new RuntimeException(
// "Could not get attrib location for v_Position");
// }
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "v_Color");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, colors, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// // get handle to shape's transformation matrix
// int mColorHandleU = GLES20.glGetUniformLocation(mProgram, "u_Color");
//
// // Apply the projection and view transformation
// GLES20.glUniform4fv(mColorHandleU, 1, new float[] {}, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
如果我想做一些必要的颜色计算,我需要不同的变量来将信息从顶点传递到片段着色器。但是,我似乎无法完成这项工作。
我不断收到的错误是:
2019-05-14 21:54:25.122 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:892 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.123 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glVertexAttribPointer:604 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.124 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glDisableVertexAttribArray:901 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.237 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:892 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.237 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glVertexAttribPointer:604 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.238 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glDisableVertexAttribArray:901 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
此外,在执行时会抛出以下异常:
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "v_Position");
if (mPositionHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for v_Position");
}
我知道对于属性,指令流程是这样的:
GLES20.glBindAttribLocation(...);
-- Link Shader Program --
attributeHandle = GLES20.glGetAttribLocation(programHandle, "a_AttributenName");
GLES20.glEnableVertexAttribArray(attributeHandle);
GLES20.glVertexAttribPointer(programHandle, ..., buffer);
制服的指令顺序是这样的:
uniformHandle = GLES20.glGetUniformLocation(mProgram, "u_UniformName");
// do something with it, for example:
GLES20.glUniform4fv(uniformHandle, ...);
但是可变变量有什么用呢?
提前致谢!
private final String vertexShaderCode =
"attribute vec4 v_Position;" +
"uniform float u_Color" +
"uniform mat4 u_MVPMatrix;" +
// outgoing
"varying vec4 v_Color" +
"void main() {" +
您在 u_Color 和 v_Color 之后缺少 semi-colon。大概您的顶点着色器没有编译,并且正在级联到您看到的错误中。
这很痛苦,但它确实节省了每次 OpenGLES 调用 (glGetError
) 后漫长的 运行 检查错误的时间。获取详细的着色器编译错误日志也很繁琐,但值得一试 - 请参阅 here(glGetShaderInfoLog
、GL_COMPILE_STATUS
)。
我正在尝试实现一个 ModelViewer,它可以使用逼真的光照可视化三角形。 由于使用 OpenGL ES 1.0 似乎无法实现逼真的照明,而且我需要一种方法来呈现单个彩色对象的深度,因此该项目使用了对我来说是新的 OpenGL ES 2.0。 对象本身由使用以下方法绘制的三角形组成:
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
至于一个测试项目,我设置了简单的着色器,在考虑模型-视图-投影矩阵的情况下绘制对象。在那之后,我的意图是实现照明,但我无法通过第一步。 使用可变变量时,将找不到顶点属性。 删除不同的属性有效,但我需要传递数据。我搜索了好几天如何实现顶点和片段着色器,这些着色器不仅仅在某个位置呈现一个对象。
// VERTEX SHADER CODE
attribute vec4 v_Position;
uniform mat4 u_MVPMatrix;
uniform vec4 u_Color;
varying vec4 v_Color;
void main() {
gl_Position = u_MVPMatrix * v_Position;
v_Color = u_Color;
};
// FRAGMENT SHADER CODE
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
整个Class:
public class Object3D {
private FloatBuffer vertexBuffer;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
// static float triangleCoords[] = { // in counterclockwise order:
// 0.0f, 0.622008459f, 0.0f, // top
// -0.5f, -0.311004243f, 0.0f, // bottom left
// 0.5f, -0.311004243f, 0.0f // bottom right
// };
float[] triangleCoords;
// Set color with red, green, blue and alpha (opacity) values
float[] colors = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
private final String vertexShaderCode =
"attribute vec4 v_Position;" +
"uniform float u_Color" +
"uniform mat4 u_MVPMatrix;" +
// outgoing
"varying vec4 v_Color" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
"gl_Position = u_MVPMatrix * v_Position;" +
"v_Color = u_Color;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"varying vec4 v_Color;" +
"void main() {" +
"gl_FragColor = v_Color;" +
"}";
// Use to access and set the view transformation
private int mMVPMatrixHandle;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private final int vertexCount;
private final int vertexStride;
public Object3D(float[] triangleCoords) {
this.triangleCoords = triangleCoords;
vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
this.colors = new float[4*vertexCount];
for (int i = 0; i < colors.length; i+=4) {
colors[i] = 0.63671875f;
colors[i+1] = 0.76953125f;
colors[i+2] = 0.22265625f;
colors[i+3] = 1.0f;
}
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
// use the device hardware's native byte order
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate
vertexBuffer.position(0);
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glBindAttribLocation(mProgram, 0, "v_Position");
// GLES20.glBindAttribLocation(mProgram, 1, "vColor");
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram);
}
public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "v_Position");
// if (mPositionHandle == -1) {
// throw new RuntimeException(
// "Could not get attrib location for v_Position");
// }
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "v_Color");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, colors, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// // get handle to shape's transformation matrix
// int mColorHandleU = GLES20.glGetUniformLocation(mProgram, "u_Color");
//
// // Apply the projection and view transformation
// GLES20.glUniform4fv(mColorHandleU, 1, new float[] {}, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
如果我想做一些必要的颜色计算,我需要不同的变量来将信息从顶点传递到片段着色器。但是,我似乎无法完成这项工作。
我不断收到的错误是:
2019-05-14 21:54:25.122 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:892 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.123 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glVertexAttribPointer:604 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.124 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glDisableVertexAttribArray:901 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.237 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:892 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.237 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glVertexAttribPointer:604 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2019-05-14 21:54:25.238 8281-8316/com.example.opengles20 E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glDisableVertexAttribArray:901 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
此外,在执行时会抛出以下异常:
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "v_Position");
if (mPositionHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for v_Position");
}
我知道对于属性,指令流程是这样的:
GLES20.glBindAttribLocation(...);
-- Link Shader Program --
attributeHandle = GLES20.glGetAttribLocation(programHandle, "a_AttributenName");
GLES20.glEnableVertexAttribArray(attributeHandle);
GLES20.glVertexAttribPointer(programHandle, ..., buffer);
制服的指令顺序是这样的:
uniformHandle = GLES20.glGetUniformLocation(mProgram, "u_UniformName");
// do something with it, for example:
GLES20.glUniform4fv(uniformHandle, ...);
但是可变变量有什么用呢?
提前致谢!
private final String vertexShaderCode =
"attribute vec4 v_Position;" +
"uniform float u_Color" +
"uniform mat4 u_MVPMatrix;" +
// outgoing
"varying vec4 v_Color" +
"void main() {" +
您在 u_Color 和 v_Color 之后缺少 semi-colon。大概您的顶点着色器没有编译,并且正在级联到您看到的错误中。
这很痛苦,但它确实节省了每次 OpenGLES 调用 (glGetError
) 后漫长的 运行 检查错误的时间。获取详细的着色器编译错误日志也很繁琐,但值得一试 - 请参阅 here(glGetShaderInfoLog
、GL_COMPILE_STATUS
)。