Отображение текстуры из необработанных данных в Open GL для Android

Я пытаюсь нарисовать текстуру из необработанных данных, элементами которых являются unsigned char (или unsigned 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 :: drawRGBData (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());
}

Это скриншот, представляющий то, что я получаю на экране моего телефона, с разрешением 1080×1920.

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

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

0

Решение

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

Кажется, вы отправляете неверные треугольники, поэтому попробуйте это:

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

1

Другие решения

Тот факт, что на экране появляется текстура, говорит о том, что ваш установочный код правильный.

Скорее всего, проблема в том, что в glTexImage2D передается неправильная информация о размере или форматировании необработанных данных. Первое, что я бы попробовал, это поменять местами ширину и высоту, так как текстура может располагаться в памяти иначе, чем ожидает OpenGL.

0

Не забывайте, что текстуры должны быть степенью 2. Хотя я удивлен, что на экране вообще что-то есть. Я бы создал текстуру 1k x 1k, а затем просто передал исправленные текстурные координаты.

0

Спасибо, ребята, за ваши ответы.
Теперь я использовал код 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 };

Работает отлично, как и ожидалось.

Теперь ясно, как Fentelia сказала, что проблема связана с тем, как организованы мои необработанные данные, потому что когда я возвращаюсь к своим необработанным данным, я получаю странные результаты, мне нужна помощь, как правильно прочитать изображение bmp в нативном андроиде и передать это правильно к буферу opengl через glTexImage2D или glSubTexImage2D.
Спасибо..

0
По вопросам рекламы [email protected]