Java OpenGL ES纹理赢得';t画

Java OpenGL ES纹理赢得';t画,java,android,opengl-es,Java,Android,Opengl Es,我遵循了一个关于如何在OpenGL中显示图像的教程,我首先必须制作一个正方形,然后对其进行纹理处理。我试过gl.glColor4f(0f,0f,0f,1f)这样就行了,我可以看到正方形。但当我尝试纹理它,屏幕只是保持白色。我做错了什么 这是带有gl.glColor4f(0f,0f,0f,1f)的屏幕: 如果应用纹理(使用教程建议的自定义纹理类),屏幕将完全为白色 这是我的密码: Square.java: package com.chrypthic.android.reference; imp

我遵循了一个关于如何在OpenGL中显示图像的教程,我首先必须制作一个正方形,然后对其进行纹理处理。我试过
gl.glColor4f(0f,0f,0f,1f)这样就行了,我可以看到正方形。但当我尝试纹理它,屏幕只是保持白色。我做错了什么

这是带有
gl.glColor4f(0f,0f,0f,1f)的屏幕

如果应用纹理(使用教程建议的自定义纹理类),屏幕将完全为白色

这是我的密码:

Square.java:

package com.chrypthic.android.reference;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;

public class Square
{
final int VERTEX_SIZE = (2+2) *4;
FloatBuffer vertices;
ShortBuffer indices;

Texture texture;

GL10 gl;
Context c;

public Square(GL10 gl, Context context)
{
    this.gl = gl;
    this.c = context;

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    vertices = byteBuffer.asFloatBuffer();
    vertices.put(new float[]{
        10.0f, 10.0f, 0.0f, 0.0f, //bl  
        160.0f, 10.0f, 1.0f, 0.0f, //br 
        160.0f, 160.0f, 1.0f, 1.0f, //tr    
        10.0f, 160.0f, 1.0f, 0.0f, //tl 
    });
    vertices.flip();

    byteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    indices = byteBuffer.asShortBuffer();
    indices.put(new short[]{
        0, 1, 2, 2, 3, 0
    });
    indices.flip();

    texture = new Texture("image/picture.png", c, gl);
}

public void draw()
{
    gl.glEnable(GL10.GL_TEXTURE_2D);
    texture.bind();
    //gl.glColor4f(0f, 0f, 0f, 1f);

    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    vertices.position(0);
    gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
    vertices.position(2);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);

    gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indices);
}
}
Texture.java

package com.chrypthic.android.reference;

import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

public class Texture {

String texturePath;
Context context;
GL10 gl;

int textureId;
int minFilter;
int magFilter;
Bitmap texture;

public Texture(String texturePath, Context context, GL10 gl)
{
    this.gl = gl;
    this.texturePath = texturePath;
    this.context = context;
}

public void load()
{
    try{
        AssetManager assetManager = context.getAssets();
        InputStream is = assetManager.open(texturePath);
        texture = BitmapFactory.decodeStream(is);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
        setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
    }catch(Exception e)
    {
        e.printStackTrace();
    }
}

public void reload()
{
    load();
    bind();
    setFilters(minFilter, magFilter);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
}

public void setFilters(int minFilter, int magFilter)
{
    this.minFilter = minFilter;
    this.magFilter = magFilter;
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter);
}

public void bind()
{
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
}

public void dispose()
{
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
    int[] textureIds = {textureId};
    gl.glDeleteTextures(1, textureIds, 0);
}

}
OpenGLRenderer.java

package com.chrypthic.android.reference;

import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;

public class OpenGLRenderer implements Renderer 
{
Random rand = new Random();
int mWidth = 0;
int mHeight = 0;

Context c;

Square square;

public OpenGLRenderer(Context c)
{
    this.c = c;
}

@Override
public void onDrawFrame(GL10 gl) 
{
    gl.glClearColor(1, 1, 1, 1);
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    gl.glViewport(0, 0, mWidth, mHeight);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glOrthof(0, mWidth, 0, mHeight, -1, 1);

    if(square != null)square.draw();
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) 
{
    mWidth = width;
    mHeight = height;
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) 
{
    square = new Square(gl, c);
}

}
我希望你能帮助我,如果你需要更多的信息就告诉我。
提前谢谢。我没有将白色屏幕作为截图发布,因为stackoverflow的白色背景似乎毫无意义。

从评论到回答


(评论):为什么要两次使用glVertexPointer而不是glVertexPointer和glTexCoordPointer?此外,该行中似乎有一个拼写错误,即“GL_FLAT”而不是“GL_FLOAT”。你确定你要给我们你的真实代码吗

-答案从这里开始-

看起来您根本没有使用纹理坐标。必须指定纹理的哪个角点要指定给三角形/四边形的哪个角点。例如,我看到在左上角顶点旁边有一个“tl”注释。同样,您需要提供一个纹理坐标,上面写着“将图像的左上角与该顶点一起使用”,然后OpenGL计算出其余部分

然后,当你要传递顶点指针时,你还必须传递一个纹理坐标指针,它包含我在上一段中刚刚提到的纹理坐标。使用glTexCoordPointer执行此操作的方式与glVertexPointer完全相同。您还可以将纹理坐标加载到VBO中(事实上,加载到与顶点相同的VBO中,然后您可以调用glTexCoordPointer,并将偏移量加载到VBO中tex坐标开始的位置)

如果您需要更多详细说明/代码示例或更多解释,请(通过注释)告诉我

编辑1:

有关纹理贴图的信息,请参见以下链接:

编辑2:


好吧,愚蠢的我。我没有注意到你实际上已经得到了纹理坐标数据和顶点数据。尝试将对glVertexPointer的第二次调用更改为glTexCoordPointer。这可能会完全解决您的问题。

您永远不会创建纹理

public void load()
{
    try{
        int []texture = new int[1];
        gl.glGenTextures(1, texture,0);//the missing method
        textureId = texture[0];
        //now you can call
        AssetManager assetManager = context.getAssets();
        InputStream is = assetManager.open(texturePath);
        texture = BitmapFactory.decodeStream(is);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);/*this fails 
          if textureId is a 'random' number. You must/should generate a valid id. */
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
        setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

它与您的
dispose()
方法正好相反

为什么要使用glVertexPointer两次,而不是glVertexPointer和glTexCoordPointer?此外,该行中似乎有一个拼写错误,即“GL_FLAT”而不是“GL_FLOAT”。你确定你给我们的是你的真实代码吗?哎呀,这是个打字错误,我来修一下。抱歉。请参阅我文章的编辑2,忽略其余部分。我刚刚注意到教程中说的是gl.glTexCoordPointer。我会回来报告,看看是否有效。有时候我就是看不到这些东西。我想在我应用建议的更改后,它会起作用。谢谢如果我解决了你的问题,别忘了向上投票并接受:)我会尽快告诉你,因为我的电脑刚刚过热,我正在打电话。我已经试过了,但没有成功。我已经更新了OP中的代码。在两个论坛上发布并研究了很久我的代码之后,我意识到我忘记调用load()方法了。天哪,我真傻。我需要更集中精神。无论如何,谢谢你指出这一点。顺便说一句,我使用GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,TEXTURE,0);而不是你认为缺少的东西。但它可以正常工作。还有一个问题,如何将原点移到左上角而不是左下角?没关系,它都是固定的。我甚至编写了一个类,将x和y坐标的整数转换为浮点,并添加图像的宽度和高度。现在它就像画布api一样。非常感谢你的帮助。它被颠倒了,因为我仍然在左下角为原点设置了坐标。我还启用了Alpha混合或其他功能。