android - Android OpenGL ES(和 Cardboard SDK)上的照明 + 纹理着色器不显示纹理

标签 android opengl-es texture-mapping google-cardboard glsles

我正在 Google Cardboard SDK 中处理一些项目,但在涉及纹理的第一个示例中遇到了一些问题。我将我的示例与 Cardboard SDK example 中的代码拼凑在一起。和一些online tutorials 。您可以浏览查看项目源码here .

如果您克隆并构建项目,我的问题应该是不言而喻的。我还创建了一个“lighting”分支,代表我尝试向纹理着色器添加照明。唯一的变化是设置法线顶点属性指针,并将漫反射值乘以着色器中的颜色。此更改使我的显示不再是这样: enter image description here

对此: enter image description here

显然,第一张图像在地球上没有光照,第二张图像有光照但没有纹理。给出了什么?

我确信我做错了™。我就是一辈子都无法弄清楚我做错了什么。我还尝试从头开始重新创建一个最小的示例,但如果不将代码复制到新项目中,我就会不断遇到不相关的问题。我陷入了最近的尝试,只是试图让我的solid_color_lighting Material 在普通立方体上工作。

如果您懒得去看我的存储库,这里是一些重要的代码;)

绘图功能:

public void draw(float[] view, float[] perspective, float[] model) {
    GLES20.glUseProgram(program);

    // Set the active texture unit to texture unit 0.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);

    // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
    GLES20.glUniform1i(textureParam, 0);

    Matrix.multiplyMM(modelView, 0, view, 0, model, 0);
    Matrix.multiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);

    GLES20.glUniform3fv(lightPosParam, 1, RenderBox.instance.mainLight.lightPosInEyeSpace, 0);
    GLES20.glUniform4fv(lightColParam, 1, RenderBox.instance.mainLight.color, 0);

    // Set the ModelView in the shader, used to calculate lighting
    GLES20.glUniformMatrix4fv(MVParam, 1, false, modelView, 0);

    // Set the position of the cube
    GLES20.glVertexAttribPointer(positionParam, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);

    // Set the ModelViewProjection matrix in the shader.
    GLES20.glUniformMatrix4fv(MVPParam, 1, false, modelViewProjection, 0);


    // Set the normal positions of the cube, again for shading
    if(normalParam > -1)
        GLES20.glVertexAttribPointer(normalParam, 3, GLES20.GL_FLOAT, false, 0, normalBuffer);
    GLES20.glVertexAttribPointer(texCoordParam, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer);


    GLES20.glDrawElements(GLES20.GL_TRIANGLES, numIndices, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
}

顶点着色器:

uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;

attribute vec4 a_Position;
attribute vec3 a_Normal;
attribute vec2 a_TexCoordinate;

varying vec3 v_Position;
varying vec3 v_Normal;
varying vec2 v_TexCoordinate;

void main() {
   // Transform the vertex into eye space.
   v_Position = vec3(u_MVMatrix * a_Position);

  // Pass through the color.
  //v_Color = a_Color;

  // Pass through the texture coordinate.
  v_TexCoordinate = a_TexCoordinate;

  // Transform the normal's orientation into eye space.
  v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

  // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
  gl_Position = u_MVPMatrix * a_Position;
}

fragment 着色器:

precision mediump float;        // Set the default precision to medium. We don't need as high of a
                            // precision in the fragment shader.
uniform vec3 u_LightPos;        // The position of the light in eye space.
uniform vec4 u_LightCol;
uniform sampler2D u_Texture;    // The input texture.

varying vec3 v_Position;        // Interpolated position for this fragment.
                            // triangle per fragment.
varying vec3 v_Normal;          // Interpolated normal for this fragment.
varying vec2 v_TexCoordinate;   // Interpolated texture coordinate per fragment.

// The entry point for our fragment shader.
void main() {
    // Will be used for attenuation.
    float distance = length(u_LightPos - v_Position);

    // Get a lighting direction vector from the light to the vertex.
    vec3 lightVector = normalize(u_LightPos - v_Position);

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
    // pointing in the same direction then it will get max illumination.
    float diffuse = max(dot(v_Normal, lightVector), 0.0);

    // Add attenuation.
    //diffuse = diffuse * (1.0 / (1.0 + (0.1 * distance)));

    // Add ambient lighting
    //diffuse = diffuse + 0.3;  //No ambient lighting.... this is space

    // Multiply the color by the diffuse illumination level and texture value to get final output color.
    //gl_FragColor = (v_Color * diffuse * texture2D(u_Texture, v_TexCoordinate));
    //gl_FragColor = u_LightCol * diffuse * texture2D(u_Texture, v_TexCoordinate);
    //gl_FragColor = texture2D(u_Texture, v_TexCoordinate);
    gl_FragColor = texture2D(u_Texture, v_TexCoordinate) * diffuse;
    //gl_FragColor = u_LightCol * diffuse;
}

最佳答案

我找到了答案!感谢@jimbo00000指出我需要为我的所有属性调用 glEnableVertexAttribArray!我根本不是为了那个特定的 Material 而调用它的。我知道这会很简单!

明确地说,我只需要添加

GLES20.glEnableVertexAttribArray(positionParam);
GLES20.glEnableVertexAttribArray(normalParam);
GLES20.glEnableVertexAttribArray(texCoordParam);

在我的着色器设置步骤中。

关于android - Android OpenGL ES(和 Cardboard SDK)上的照明 + 纹理着色器不显示纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34009958/

相关文章:

android - getCheckedItemCount() 在光标更改后返回错误值

ios - 了解 OpenGL ES : CATransform3DScale instead of glScalef?

ios - 为什么 GLKView 在界面生成器中具有上下文属性?

javascript - Three.js 使用图像主色而不是图像本身

通过opengl函数调用调整opengl纹理lod偏差?

android - 上下文切换是否占用了大量时间?

java - 如何从 ListView 中删除项目我使用 ArrayAdapter<String> 在 ListView 上显示

java - Android 帧动画被强制停止。需要理由

ios - 在 OpenGL 中绘制凹多边形

java - Android 纹理映射 - PNG 文件的映射不正确