Я читал много о текстурах в 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);
в результатах фрагмента шейдеров в :
Здесь есть много вещей, которые могут пойти не так. Я вижу, что вы уже проверили несколько, но все же вы должны попытаться определить, в чем проблема. Попробуйте рисовать простой текстурированный прямоугольник, который занимает часть экрана. Проверьте цвет, если он нарисован. Проверьте правильность координат текстуры (в шейдере фрагмента используйте X, Y для красного и зеленого цветов, и вы увидите хороший призрак). Если это все удастся, то ваша проблема должна быть в загрузке, передаче текстуры или в параметрах текстуры. –
Привет, спасибо за ваш ответ. Я уже вижу, что куб, который я рисую, рисуется, поскольку за ним есть другие нетекстовые элементы, обозначающие черный куб. Я проведу с координатами текстуры в шейдере фрагмента, но печать буфера, который я передаю, привела к правильному буферу, я отредактирую массивы float в вопросе. – damian
Итак, кажется, что ваши данные текстуры, полученные в шейдере, как-то черные или пустые. Не могли бы вы проверить параметры текстуры после загрузки из растрового изображения. Проверьте ширину, высоту и внутренний формат, если это возможно. Даже некоторые пиксельные данные могут быть приятными. Если эти проверки могут быть связаны только с подключением текстуры к шейдеру. Также какова связь между mTexture и textureHandle. Код, создающий вашу текстуру, по-видимому, не имеет отношения ни к одному объекту, на котором можно установить идентификатор текстуры, и вы не опубликовали ни одного выхода журнала из этой части приложения. –