android opengles将图像显示为纹理

时间:2014-04-21 05:51:30

标签: android opengl-es glsurfaceview render-to-texture

我使用下面的代码将大小为480 * 800的图像渲染到openGL纹理中,在三星S3中渲染图像很好,在纵向模式下分辨率为720 * 1280。

//initialization
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &s_texture);
glBindTexture(GL_TEXTURE_2D, s_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glShadeModel(GL_FLAT);
check_gl_error("glShadeModel");

glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
check_gl_error("glColor4x");
glTexImage2D(GL_TEXTURE_2D, /* target*/
    0, /* level*/
    GL_RGBA, /* internal format*/
    480, /* width*/
    800, /* height*/
    0, /* border*/
    GL_RGBA, /* format*/
    GL_UNSIGNED_BYTE,/* type*/ //can it be GL_UNSIGNED_SHORT_5_6_5??
    0); /*source pixels*/ 
    check_gl_error("glTexImage2D");

//rendering loop
glClear(GL_COLOR_BUFFER_BIT);
glTexParameterf(GL_TEXTURE_2D,
                       GL_TEXTURE_WRAP_S,
                       GL_REPEAT);
    check_gl_error("glTexParameterf:GL_TEXTURE_WRAP_S ");
    glTexParameterf(GL_TEXTURE_2D,
                       GL_TEXTURE_WRAP_T,
                       GL_REPEAT);
    check_gl_error("glTexParameterf:GL_TEXTURE_WRAP_T");
int rect[4] = { 0, 800, 480, -800 };
    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);
glTexSubImage2D(GL_TEXTURE_2D, 0,0, 0, 480, 800, GL_RGBA, GL_UNSIGNED_BYTE, s_pixels);
check_gl_error("glTexSubImage2D");


glDrawTexiOES(0, 0, 0, screen_width, screen_height); //draw into full available window

现在我将源图像更改为720 * 1280尺寸,也是渲染目标,分辨率为720 * 1360,是平板电脑。

现在改变上面的代码似乎不起作用,因为它在肖像模式设备(上面的例子)上工作。图像未完全显示,部分图像重复多次。

//initialization
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &s_texture);
glBindTexture(GL_TEXTURE_2D, s_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glShadeModel(GL_FLAT);
check_gl_error("glShadeModel");

glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
check_gl_error("glColor4x");
glTexImage2D(GL_TEXTURE_2D, /* target*/
    0, /* level*/
    GL_RGBA, /* internal format*/
    720, /* width*/
    1280, /* height*/
    0, /* border*/
    GL_RGBA, /* format*/
    GL_UNSIGNED_BYTE,/* type*/ //can it be GL_UNSIGNED_SHORT_5_6_5??
    /*s_pixels*/0); /*source pixels*/ 
    check_gl_error("glTexImage2D");

//rendering loop
glClear(GL_COLOR_BUFFER_BIT);
glTexParameterf(GL_TEXTURE_2D,
                       GL_TEXTURE_WRAP_S,
                       GL_REPEAT);
    check_gl_error("glTexParameterf:GL_TEXTURE_WRAP_S ");
    glTexParameterf(GL_TEXTURE_2D,
                       GL_TEXTURE_WRAP_T,
                       GL_REPEAT);
    check_gl_error("glTexParameterf:GL_TEXTURE_WRAP_T");
int rect[4] = { 0, 720, 1280, -720};
    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);
glTexSubImage2D(GL_TEXTURE_2D, 0,0, 0, 720, 1280, GL_RGBA, GL_UNSIGNED_BYTE, s_pixels);
check_gl_error("glTexSubImage2D");


glDrawTexiOES(0, 0, 0, screen_width, screen_height); //draw into full available window

1.有人可以解释我的错误吗?

2.有人可以解释我如何处理在各种尺寸显示中渲染各种分辨率的图像,因为我看到的所有例子都表明使用glDrawTexiOES(0, 0, 0, screen_width, screen_height);会正确地做到这一点,但事实并非如此。

3.如果我删除int rect[4] = { 0, 720, 1280, -720}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);我不会在屏幕上看到任何内容,这就是我使用它的原因,但我真的不知道它的目的以及如何使用它,任何人都可以告诉我它的目的和正确使用?

1 个答案:

答案 0 :(得分:2)

您的代码看起来是正确的,但我不是OpenGL专家。也许screen_width和screen_height不对。无论如何一些提示:

  • 不要为2个纹理创建pow,这不是一个好主意。在某些设备中,它将被忽略。如果要使用780x1280图像,则需要创建1024x2048纹理。在glTexImage2D中,您将设置" 1024,2048"在rect和glTexSubImage中,您将使用实际图像大小(780x1280)。
  • glDrawTexiOES(和glTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_CROP_RECT_OES)是对的。
  • 将GL_REPEAT更改为GL_CLAMP_TO_EDGE,这样可以避免图像重复出现。

请记住在glTexImage2D中定义纹理,但图像可以是其中的一部分。在glTexSubImage和GL_TEXTURE_CROP_RECT_OES中,您可以定义要绘制的纹理部分,在glDrawTexiOES中,您可以定义要绘制的屏幕的矩形。