OpenGL: создание 2D-текстуры из массива данных для отображения на квадроцикле

Я написал программу, которая выполняет вычисления конечной разности во временной области на двумерной сетке. Я хочу взять данные о величине одного из компонентов поля (скажем, z-компонент магнитного поля, Гц), преобразовать величины в цветовую шкалу, а затем отобразить окончательную цветовую карту на экране. Следующее изображение в ссылке imgur было сгенерировано с помощью Matlab, но я хотел бы получить тот же тип изображения в OpenGL.

http://imgur.com/8Rj77MK

Я использую GLFW для создания окна OpenGL (800x480) с ортогональной проекцией, используя следующий код:

//-->Construct GLFW Window<--//
int WINDOW_WIDTH = 800*(xIndex/4000);
int WINDOW_HEIGHT = 480*(yIndex/2400);

GLFWwindow* window;
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Hz Component Magnitude", NULL, NULL);

//GLFW terminate and error function setup not shown

glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);

glewInit();

glfwGetFramebufferSize(window, &WINDOW_WIDTH, &WINDOW_HEIGHT);

glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//Create orthographic view
glMatrixMode(GL_PROJECTION);
glOrtho(0, 0, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();

glfwSwapBuffers(window);
glfwPollEvents();
//-->END Construct GLFW Window<--//

Данные о цвете для поля Hz сохраняются:

  • Создание указателя 1D int длиной 800x480*(3 цвета)
  • Вычислите и сохраните значения цвета поля Hz в указателе 1D

Из того, что я прочитал, типичным способом отображения 2D-текстуры в окне является создание четырехугольника и применение текстуры к четырехугольнику. Я могу успешно создать четырехугольник и успешно сгенерировать данные о цвете (проверено с помощью Matlab), но у меня возникают проблемы с созданием текстуры для применения к четырехугольнику.

Мой код для создания текстуры:

int num_colors = 3;    //Number of colors per pixel
int tex_size = num_colors*WINDOW_WIDTH*WINDOW_HEIGHT;    //Number of entries in tex_Hz

int size = tex_size*sizeof(int);

//Create pointer for storing color map
int* tex_Hz = (int*)malloc(size);

for(int i = 0; i < tex_size; i++)    //Initialize colormap to 0
    tex_Hz[i] = 0;

//OpenCL buffer for the color map
cl::Buffer texture_mem(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, size, tex_Hz, &error);

//Generate a texture ID
GLuint tex_id;

glGenTextures(1, &tex_id);
glBindTexture(GL_TEXTURE_2D, tex_id);

    //*A bunch of irrelevant code*//

    //-->Start of time loop<--//

    //*A bunch of irrelevant code*//

//-->Update the Hz field<--//
time_loop_queue.enqueueNDRangeKernel(timeLoopKernels[1], 0, global_size, local_size);
time_loop_queue.finish();

//-->Generate 2D image every 100 time steps<--//
if(step%100 == 0)
{
    //Read colormap values from OpenCL buffer
    time_loop_queue.enqueueReadBuffer(texture_mem, NULL, 0, size, tex_Hz, NULL, NULL);
    time_loop_queue.finish();

    //Used only as a debug runtime check to make sure data copied back
    cout << tex_Hz[3*800*240 + 3*350] << "\n";

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_RGB, GL_INT, tex_Hz);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glBindTexture(GL_TEXTURE_2D, tex_id);

    //Draw quad and set texture coords
    glBegin(GL_QUADS);
    glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);
    glTexCoord2d(1.0,0.0); glVertex2d(1.0,-1.0);
    glTexCoord2d(1.0,1.0); glVertex2d(1.0,1.0);
    glTexCoord2d(0.0,1.0); glVertex2d(-1.0,1.0);
    glEnd();

    glfwSwapBuffers(window);
}

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

*** Я знаю, что копирование данных обратно в память хоста для последующего создания GL-текстуры не является оптимальным с точки зрения производительности, но на данный момент все, что имеет значение, — это реализация отображения поля в кратчайшие сроки, а не достижение оптимальной производительности (пока). .


person user3186298    schedule 12.01.2014    source источник
comment
На квадроцикле ничего не отображается, он просто остается черным.   -  person user3186298    schedule 12.01.2014
comment
Ну, похоже, ты не делаешь нубских ошибок. Вы пробовали заполнить tex_Hz случайными данными и нарисовать их? Тогда вы могли бы, по крайней мере, знать, является ли это проблемой данных или проблемой openGL.   -  person BWG    schedule 12.01.2014
comment
Ждать. Если вам нечего рисовать, я думаю, у вас неправильные значения glOrtho(...) z. Последние два параметра должны быть -1,1, а не 1,-1.   -  person BWG    schedule 12.01.2014
comment
Починил это. При использовании флага GL_INT в glTexImage2D(...) цветовая шкала распространяется на все значения со знаком int , и я использовал цветовую шкалу от 0 до 255 для каждого канала, что по существу равно 0 при использовании GL_INT. Спасибо, что нашли время просмотреть код. Я сводил себя с ума из-за этого.   -  person user3186298    schedule 12.01.2014
comment
Я рад, что вы исправили это. На самом деле я присматривался к этому флагу GL_INT, но никогда им не пользовался. Я всегда делал GL_UNSIGNED_BYTE или что-то в этом роде.   -  person BWG    schedule 12.01.2014
comment
@ user3186298: Если вы исправили это, вы должны написать ответ на свой вопрос и принять его. Вот как должно работать переполнение стека. Без этого никто не может сказать, просматривая вопросы, что этот вопрос был решен. Они также должны копаться в комментариях, чтобы найти ваше решение. Поскольку SO должен быть хранилищем вопросов и ответов, он работает лучше всего, когда вы правильно отвечаете на свои вопросы.   -  person Andon M. Coleman    schedule 12.01.2014


Ответы (1)


Починил это. При использовании флага GL_INT в glTexImage2D(...) цветовая шкала распространяется на все значения со знаком int , и я использовал цветовую шкалу от 0 до 255 для каждого канала, что по существу равно 0 при использовании GL_INT.

person user3186298    schedule 14.01.2014