在opengl原生Android中显示原始数据的纹理



我试图从原始数据中绘制纹理,这些元素是无符号字符(或无符号int),每3个后续元素(RGB)代表像素数据。我想要的是*显示这个rgb原始数据(宽度=640,高度=480)在我的手机屏幕上(1920*1080)*。这是我的代码!我正在用egl准备图形环境,如下所示:

bool Render::initializing(ANativeWindow* window)
{
const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE,
        8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE };
EGLDisplay display;
EGLConfig config;
EGLint numConfigs;
EGLint format;
EGLSurface surface;
EGLContext context;
EGLint width;
EGLint height;
GLfloat ratio;
Log::info("Initializing context");
if ((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) {
    Log::error("eglGetDisplay() returned error %d", eglGetError());
    return false;
}
if (!eglInitialize(display, 0, 0)) {
    Log::error("eglInitialize() returned error %d", eglGetError());
    return false;
}
if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs)) {
    Log::error("eglChooseConfig() returned error %d", eglGetError());
    destroy();
    return false;
}
if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format)) {
    Log::error("eglGetConfigAttrib() returned error %d", eglGetError());
    destroy();
    return false;
}
Log::info("Setting buffer geometry");
ANativeWindow_setBuffersGeometry(window, 0, 0, format);
Log::info("End Setting buffer geometry");
if (!(surface = eglCreateWindowSurface(display, config, window, 0))) {
    Log::error("eglCreateWindowSurface() returned error %d", eglGetError());
    destroy();
    return false;
}
if (!(context = eglCreateContext(display, config, 0, 0))) {
    Log::error("eglCreateContext() returned error %d", eglGetError());
    destroy();
    return false;
}
if (!eglMakeCurrent(display, surface, surface, context)) {
    Log::error("eglMakeCurrent() returned error %d", eglGetError());
    destroy();
    return false;
}
if (!eglQuerySurface(display, surface, EGL_WIDTH, &width)
        || !eglQuerySurface(display, surface, EGL_HEIGHT, &height)) {
    Log::error("eglQuerySurface() returned error %d", eglGetError());
    destroy();
    return false;
}
//If Landscape
/*if (!eglQuerySurface(display, surface, EGL_WIDTH, &width) ||
 !eglQuerySurface(display, surface, EGL_HEIGHT, &height)) {
 Log::error("eglQuerySurface() returned error %d", eglGetError());
 destroy();
 return false;
 }*/
//
_display = display;
_surface = surface;
_context = context;

}}

和这个用于绘制RGB原始数据:void Render:: drawgbdata (unsigned char *rgb) {

glEnable(GL_TEXTURE_2D);
glGenTextures(1, &gl_rgb_tex);
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 640, 480, 0, GL_RGB,
        GL_UNSIGNED_BYTE, (GLubyte*) rgb);
//**Drawing***/
float tricoords[12] = { 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0,
        1.0, 0.0 };
float texcoords[12] = { 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0,
        1.0, 0.0 };
/*float tricoords[12] = { -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0,
 1.0, -1.0 };
 float texcoords[12] = { 0-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0,
 1.0, -1.0 };*/

glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
glEnableClientState(GL_VERTEX_ARRAY); //enable gl vertex pointer to be used in draw fct
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, tricoords);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
glDrawArrays(GL_TRIANGLES, 0, 8);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
} 

对于每个新接收到的rgb数据,在循环中调用最后一个方法。我这样做是为了交换缓冲区:

if (!eglSwapBuffers(renderer->_display, renderer->_surface)) {
Log::error("eglSwapBuffers() returned error %d", eglGetError());
        }

这是我手机屏幕的截图,分辨率为1080x1920。

http://s1.postimg.org/hh4z4j2gv/Screenshot_2014_07_17_17_55_17_Convert_Image.jpg

问题是在绘制纹理的过程中,并将像素从原始数据正确映射到要显示的纹理。

首先让我们确保你的三角形渲染正确。

你似乎提交了无效的三角形,所以试试这个:

float tricoords[12] = { 0.0, 0.0, 
                        1.0, 0.0, 
                        1.0, 1.0, 
                        0.0, 0.0, 
                        1.0, 1.0, 
                        0.0, 1.0 };
float texcoords[12] = { 0.0, 0.0, 
                        1.0, 0.0, 
                        1.0, 1.0, 
                        0.0, 0.0, 
                        1.0, 1.0,
                        0.0, 1.0 };

下一步你试图画8个顶点…两个三角形应为6:

glDrawArrays(GL_TRIANGLES, 0, 6);

确保你的三角形渲染没有纹理,所以传递一个颜色数组:

glDisable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
float colors[18] = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 
                     0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0 }; 
glColorPointer(3, GL_FLOAT, 0, colors);

现在你已经确认三角形是正确渲染的,这里是一个资源来加载和显示你的。bmp文件:

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/Loading__BMP_images_yourself

纹理出现在屏幕上的事实表明你的设置代码是正确的。

最有可能的问题是错误的信息被传递给glTexImage2D关于原始数据的大小或格式。我要尝试的第一件事是交换宽度和高度,因为纹理可能在内存中安排与OpenGL期望的不同。

不要忘记纹理需要是2的幂。不过我很惊讶你能在屏幕上看到任何东西。我会创建一个1k x 1k的纹理,然后传入校正后的纹理坐标。

谢谢大家的回答。现在,我已经使用了Pondwater代码来显示简单的彩色三角形,我已经改变了颜色表(每种颜色应该在4通道上):

float tricoords[12] = { -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0,
        1.0, -1.0, 1.0 };
float texcoords[12] = { -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0,
        1.0, -1.0, 1.0 };
float colors[24] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
        0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 };

完全符合预期。

现在很明显,芬特利亚说,这个问题是有关我的原始数据是如何组织的,因为当我回到我的原始数据我得到奇怪的结果,我需要帮助,如何正确读取原生android的bmp图像,并通过glTexImage2D或glSubTexImage2D正确传输到opengl缓冲区。谢谢. .

最新更新