2014-04-10 2 views
4

Я читал много о текстурах в Open GL ES 2.0 сегодня. Моя проблема в том, что все они черные.OpenGL ES 2.0 - Текстуры всегда черные

Мой код:

Чтобы создать текстуру из растрового изображения:

private void generateTexture(Bitmap bmp) { 
    final int[] textureHandle = new int[1]; 

    Log.d(TAG, "Generating texture handle"); 
    GLES20.glGenTextures(1, textureHandle, 0); 

    if (textureHandle[0] != 0) { 

     Log.d(TAG, "binding texture to " + textureHandle[0]); 
     // Bind to the texture in OpenGL 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); 
     Log.d(TAG, "[email protected]=" + GLES20.glGetError()); 

     // Set filtering 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, 
       GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, 
       GLES20.GL_CLAMP_TO_EDGE); 

     Log.d(TAG, "Loading bitmap into texture"); 
     // Load the bitmap into the bound texture. 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0); 

     Log.d(TAG, "[email protected]=" + GLES20.glGetError()); 

     Log.d(TAG, "Recycle bitmap"); 
     // Recycle the bitmap, since its data has been loaded into OpenGL. 
     bmp.recycle(); 
    } 

Там нет ошибок в моей LogCat, все, кажется, как это предполагается.

Как использовать текстуру:

if (mShader instanceof Texture2DShader && mTextureBuffer != null) { 
     // activate texture 
     Log.d(TAG, "Passing texture stuff"); 
     mTextureBuffer.position(0); 
     Log.d(TAG, "Activate Texture"); 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     Log.d(TAG, "Binding texture -> " + mTexture.getHandle()); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.getHandle()); 

     if (mShader.getGLLocation(BaseShader.U_TEXTURE) != -1) { 
      Log.d(TAG, "Passing u_Texture"); 
      GLES20.glUniform1i(mShader.getGLLocation(BaseShader.U_TEXTURE), 0); 
     } 

     if (mShader.getGLLocation(BaseShader.A_TEXCOORDINATE) != -1) { 
      Log.d(TAG, "Passing a_TexCoordinate"); 
      GLES20.glVertexAttribPointer(mShader.getGLLocation(BaseShader.A_TEXCOORDINATE), 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer); 
      GLES20.glEnableVertexAttribArray(mShader.getGLLocation(BaseShader.A_TEXCOORDINATE)); 
     } 
     Log.d(TAG, "Texture stuff passed."); 
     Log.d(TAG, "Error = " + GLES20.glGetError()); 
    } 

Logcat говорит что-то вроде этого:

D/TextureCube﹕ Activate Texture 
D/TextureCube﹕ Binding texture -> 3 
D/TextureCube﹕ Passing u_Texture 
D/TextureCube﹕ Passing a_TexCoordinate 
D/TextureCube﹕ Texture stuff passed. 
D/TextureCube﹕ Error = 0 

Так нет ошибок, кажется, работает?

Мои шейдеры:

пиксельный шейдер:

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_Light; 
uniform vec4 u_Ambient; 
uniform vec3 u_LightDirection; 
uniform vec3 u_CameraPos; 
uniform sampler2D u_Texture; 

//varying vec4 v_Ambient;  // Ambient light factor! 
varying vec2 v_TexCoordinate; 
varying vec3 v_Position;  // Interpolated position for this fragment. 
varying vec4 v_Color;   // This is the color from the vertex shader interpolated across the triangle per fragment. 
varying vec3 v_Normal;   // Interpolated normal for this fragment. 
//varying vec3 v_CameraPosition; 

// 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.1); 

    // Add attenuation. (used to be 0.25) 
    diffuse = diffuse * (1.0/(1.0 + (0.25 * distance * distance))); 

    // calculate specular light! 
    //vec3 lightDirection = -u_LightDirection; 
    //vec3 vertexToEye = normalize(u_CameraPos - v_CameraPos); 
    //vec3 lightReflect = normalize(reflect(u_LightDirection, v_Normal)); 
    //float specularFactor = dot(vertexToEye, lightReflect); 



    // Multiply the color by the diffuse illumination level to get final output color. 
    // 
    gl_FragColor = v_Color * (u_Ambient + (diffuse * u_Light) * texture2D(u_Texture, v_TexCoordinate)); 
} 

Vertex Shader:

uniform mat4 u_MVPMatrix;  // A constant representing the combined model/view/projection matrix. 
uniform mat4 u_MVMatrix;  // A constant representing the combined model/view matrix. 

attribute vec4 a_Position;  // Per-vertex position information we will pass in. 
attribute vec4 a_Color;   // Per-vertex color information we will pass in. 
attribute vec3 a_Normal;  // Per-vertex normal information we will pass in. 
attribute vec2 a_TexCoordinate; 

varying vec2 v_TexCoordinate; 
varying vec3 v_Position;  // This will be passed into the fragment shader. 
varying vec4 v_Color;   // This will be passed into the fragment shader. 
varying vec3 v_Normal;   // This will be passed into the fragment shader. 
//varying vec3 v_CameraPosition; 
//varying vec4 v_Ambient;   // Pass the ambient color to the fragment shader. 

// The entry point for our vertex shader. 
void main() 
{ 
    // Transform the vertex into eye space. 
    v_Position = vec3(u_MVMatrix * a_Position); 

    v_TexCoordinate = a_TexCoordinate; 

    // Pass through the color. 
    v_Color = a_Color; 

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

    // gl_Position is a special variable used to store the final position. 
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates. 
    gl_Position = u_MVPMatrix * a_Position; 
} 

Похоже Texture2D возвращает нулевой вектор в пиксельный шейдер, так как если я просто пишу gl_FragColor = vec4(0.5,0.5,0.5,1.0) + texture2D(..) его нарисован.

Я уже рассматривал бесчисленные вопросы здесь, как и другие сайты, я знаю, что этот точный вопрос задавали пару раз, но независимо от того, что я пробовал, это не помогло.

Я уже уменьшил мою текстуру до 512x512, затем 256x256 и даже ниже до 64x64, но никаких изменений. Я распечатал обработчики текстур, проверил на ошибки GL и т. Д., Но ничего.

EDIT:

Сначала я не пытался загрузить текстуру из R.raw, а затем переехал его R.drawable, но никаких изменений.

EDIT 2: Куб вершины/нормали/текстура/цвет декларация:

private final float[] mCubePosition = { 

       // Front face 
       -1.0f, 1.0f, 1.0f, 
       -1.0f, -1.0f, 1.0f, 
       1.0f, 1.0f, 1.0f, 
       -1.0f, -1.0f, 1.0f, 
       1.0f, -1.0f, 1.0f, 
       1.0f, 1.0f, 1.0f, 

       // Right face 
       1.0f, 1.0f, 1.0f, 
       1.0f, -1.0f, 1.0f, 
       1.0f, 1.0f, -1.0f, 
       1.0f, -1.0f, 1.0f, 
       1.0f, -1.0f, -1.0f, 
       1.0f, 1.0f, -1.0f, 

       // Back face 
       1.0f, 1.0f, -1.0f, 
       1.0f, -1.0f, -1.0f, 
       -1.0f, 1.0f, -1.0f, 
       1.0f, -1.0f, -1.0f, 
       -1.0f, -1.0f, -1.0f, 
       -1.0f, 1.0f, -1.0f, 

       // Left face 
       -1.0f, 1.0f, -1.0f, 
       -1.0f, -1.0f, -1.0f, 
       -1.0f, 1.0f, 1.0f, 
       -1.0f, -1.0f, -1.0f, 
       -1.0f, -1.0f, 1.0f, 
       -1.0f, 1.0f, 1.0f, 

       // Top face 
       -1.0f, 1.0f, -1.0f, 
       -1.0f, 1.0f, 1.0f, 
       1.0f, 1.0f, -1.0f, 
       -1.0f, 1.0f, 1.0f, 
       1.0f, 1.0f, 1.0f, 
       1.0f, 1.0f, -1.0f, 

       // Bottom face 
       1.0f, -1.0f, -1.0f, 
       1.0f, -1.0f, 1.0f, 
       -1.0f, -1.0f, -1.0f, 
       1.0f, -1.0f, 1.0f, 
       -1.0f, -1.0f, 1.0f, 
       -1.0f, -1.0f, -1.0f, 
     }; 

// R, G, B, A 
private final float[] mCubeColors = 
     { 
       // Front face (red) 
       1.0f, 0.0f, 0.0f, 1.0f, 
       1.0f, 0.0f, 0.0f, 1.0f, 
       1.0f, 0.0f, 0.0f, 1.0f, 
       1.0f, 0.0f, 0.0f, 1.0f, 
       1.0f, 0.0f, 0.0f, 1.0f, 
       1.0f, 0.0f, 0.0f, 1.0f, 

       // Right face (green) 
       0.0f, 1.0f, 0.0f, 1.0f, 
       0.0f, 1.0f, 0.0f, 1.0f, 
       0.0f, 1.0f, 0.0f, 1.0f, 
       0.0f, 1.0f, 0.0f, 1.0f, 
       0.0f, 1.0f, 0.0f, 1.0f, 
       0.0f, 1.0f, 0.0f, 1.0f, 

       // Back face (blue) 
       0.0f, 0.0f, 1.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 1.0f, 

       // Left face (yellow) 
       1.0f, 1.0f, 0.0f, 1.0f, 
       1.0f, 1.0f, 0.0f, 1.0f, 
       1.0f, 1.0f, 0.0f, 1.0f, 
       1.0f, 1.0f, 0.0f, 1.0f, 
       1.0f, 1.0f, 0.0f, 1.0f, 
       1.0f, 1.0f, 0.0f, 1.0f, 

       // Top face (cyan) 
       0.0f, 1.0f, 1.0f, 1.0f, 
       0.0f, 1.0f, 1.0f, 1.0f, 
       0.0f, 1.0f, 1.0f, 1.0f, 
       0.0f, 1.0f, 1.0f, 1.0f, 
       0.0f, 1.0f, 1.0f, 1.0f, 
       0.0f, 1.0f, 1.0f, 1.0f, 

       // Bottom face (magenta) 
       1.0f, 0.0f, 1.0f, 1.0f, 
       1.0f, 0.0f, 1.0f, 1.0f, 
       1.0f, 0.0f, 1.0f, 1.0f, 
       1.0f, 0.0f, 1.0f, 1.0f, 
       1.0f, 0.0f, 1.0f, 1.0f, 
       1.0f, 0.0f, 1.0f, 1.0f 
     }; 

private final float[] mCubeNormals = 
     { 
       // Front face 
       0.0f, 0.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 
       0.0f, 0.0f, 1.0f, 

       // Right face 
       1.0f, 0.0f, 0.0f, 
       1.0f, 0.0f, 0.0f, 
       1.0f, 0.0f, 0.0f, 
       1.0f, 0.0f, 0.0f, 
       1.0f, 0.0f, 0.0f, 
       1.0f, 0.0f, 0.0f, 

       // Back face 
       0.0f, 0.0f, -1.0f, 
       0.0f, 0.0f, -1.0f, 
       0.0f, 0.0f, -1.0f, 
       0.0f, 0.0f, -1.0f, 
       0.0f, 0.0f, -1.0f, 
       0.0f, 0.0f, -1.0f, 

       // Left face 
       -1.0f, 0.0f, 0.0f, 
       -1.0f, 0.0f, 0.0f, 
       -1.0f, 0.0f, 0.0f, 
       -1.0f, 0.0f, 0.0f, 
       -1.0f, 0.0f, 0.0f, 
       -1.0f, 0.0f, 0.0f, 

       // Top face 
       0.0f, 1.0f, 0.0f, 
       0.0f, 1.0f, 0.0f, 
       0.0f, 1.0f, 0.0f, 
       0.0f, 1.0f, 0.0f, 
       0.0f, 1.0f, 0.0f, 
       0.0f, 1.0f, 0.0f, 

       // Bottom face 
       0.0f, -1.0f, 0.0f, 
       0.0f, -1.0f, 0.0f, 
       0.0f, -1.0f, 0.0f, 
       0.0f, -1.0f, 0.0f, 
       0.0f, -1.0f, 0.0f, 
       0.0f, -1.0f, 0.0f 
     }; 

private final float[] mCubeTexture = 
     { 
       // Front face 
       0.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       1.0f, 0.0f, 

       // Right face 
       0.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       1.0f, 0.0f, 

       // Back face 
       0.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       1.0f, 0.0f, 

       // Left face 
       0.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       1.0f, 0.0f, 

       // Top face 
       0.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       1.0f, 0.0f, 

       // Bottom face 
       0.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 0.0f, 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       1.0f, 0.0f 
     }; 

EDIT 3: координаты текстуры, как цвет, чтобы увидеть, если они передаются:

gl_FragColor = vec4(v_TexCoordinate.x, v_TexCoordinate.y, 0, 1); в результатах фрагмента шейдеров в :

enter image description here

+0

Здесь есть много вещей, которые могут пойти не так. Я вижу, что вы уже проверили несколько, но все же вы должны попытаться определить, в чем проблема. Попробуйте рисовать простой текстурированный прямоугольник, который занимает часть экрана. Проверьте цвет, если он нарисован. Проверьте правильность координат текстуры (в шейдере фрагмента используйте X, Y для красного и зеленого цветов, и вы увидите хороший призрак). Если это все удастся, то ваша проблема должна быть в загрузке, передаче текстуры или в параметрах текстуры. –

+0

Привет, спасибо за ваш ответ. Я уже вижу, что куб, который я рисую, рисуется, поскольку за ним есть другие нетекстовые элементы, обозначающие черный куб. Я проведу с координатами текстуры в шейдере фрагмента, но печать буфера, который я передаю, привела к правильному буферу, я отредактирую массивы float в вопросе. – damian

+0

Итак, кажется, что ваши данные текстуры, полученные в шейдере, как-то черные или пустые. Не могли бы вы проверить параметры текстуры после загрузки из растрового изображения. Проверьте ширину, высоту и внутренний формат, если это возможно. Даже некоторые пиксельные данные могут быть приятными. Если эти проверки могут быть связаны только с подключением текстуры к шейдеру. Также какова связь между mTexture и textureHandle. Код, создающий вашу текстуру, по-видимому, не имеет отношения ни к одному объекту, на котором можно установить идентификатор текстуры, и вы не опубликовали ни одного выхода журнала из этой части приложения. –

ответ

0

Ok, я нашел решение. Я снова был смущен тем, как работает поток OpenGL. Я загружал Bitmap в поток, а затем использовал glView.post();, чтобы отправить Runnable обратно в (как я думал) поток OpenGL, где текстура должна была быть сгенерирована и привязана к растровому изображению.

Это не работает. То, что я должен был сделать это:

GLSurfaceView glView = ...; 
glView.queueEvent(new Runnable() { 
    @Override 
    public void run() { 
    generateTexture(bitmap); 
    } 
}); 

Где в generateTexture, я исполню все вещи и т.д. GLES20.generateTexture, так как с queueEvent, это снова на реальном OpenGL потоке, не в потоке пользовательского интерфейса.

По-видимому, мой код для использования текстуры верен. Спасибо за вашу помощь.

0

это очень распространенная проблема, то вы не работают с мощностью 2 текста (пиксель мудрый).

Чтобы не повторить здесь то же самое уже предоставленное решение, пожалуйста, взгляните на мой предыдущий ответ по этому вопросу.

Android OpenGL2.0 showing black textures

Я надеюсь, что это решит проблему.

Приветствия Маурицио

+0

То, что я сейчас в настоящее время isung - это именно то, что вы имеете в виду, поскольку я уже читал ваш ответ на этот вопрос раньше - но это ничего не меняет в моем случае. Кроме того, я упомянул, что я изменил текстуру на мощность 2-х размеров. К сожалению, это не решение моей проблемы. – damian

Смежные вопросы