Как использовать OpenGL и DevIL для получения пользовательских пикселей рисования

Мне нужно загрузить изображение, отобразить изображение и позволить пользователю нарисовать несколько штрихов на изображении и получить эти пиксели рисования.

Я знаю, что OpenGL может загружать изображение текстуры, прочитанное DevIL, и отображать его. Но я не уверен, как использовать OpenGL для получения пикселей рисования пользователем из загруженной текстуры.


person realmq    schedule 11.06.2013    source источник
comment
или любая другая библиотека, которая лучше DevIL и OpenGL для этой цели?   -  person realmq    schedule 11.06.2013
comment
glReadPixels() не работает?   -  person genpfault    schedule 11.06.2013
comment
Я знаю, что glReadPixels может читать буфер кадров и сохранять его. Может ли он также считывать пиксели, выбранные пользователем при рисовании штрихов, и отображать штрихи красным цветом поверх исходного изображения в режиме реального времени? У вас есть фрагмент кода для такой функциональности?   -  person realmq    schedule 12.06.2013


Ответы (2)


Во-первых, обратите внимание, что большая часть этого кода устарела. Но это легче понять из фрагментов кода. Я не делаю все за вас, но я надеюсь, что вы начнете работу, предоставив базовый рабочий процесс.

Есть несколько вещей, которые вам нужно сделать, чтобы получить желаемый результат.
Во-первых, вам нужно загрузить текстуру в видеопамять. Это делается с помощью:

glGenTextures(1, texture_id); //generate a texture object
glBindTexture(GL_TEXTURE_2D, texture_id); //bind the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //set filters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //set filters
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, original_image_data); //create the actual texture in video ram

Когда это удастся, вы можете нарисовать свою текстуру с помощью:

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

//set to ortographic projection
glOrtho(0.0, window_width, 0.0, window_height, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

glLoadIdentity();
glBindTexture(GL_TEXTURE_2D,texture_id);

glBegin(GL_QUADS);
  glTexCoord2f(0, 1); glVertex2f(-1.0f,  1.0f);
  glTexCoord2f(1, 1); glVertex2f( 1.0f,  1.0f);
  glTexCoord2f(1, 0); glVertex2f( 1.0f, -1.0f);
  glTexCoord2f(0, 0); glVertex2f(-1.0f, -1.0f);
glEnd();

glPopMatrix();

glMatrixMode(GL_PROJECTION);
glPopMatrix();

glMatrixMode(GL_MODELVIEW);

Следующее, что вам нужно будет сделать, это захватить ввод мыши вашего пользователя. Если вы работаете в Windows, вы можете использовать обратный вызов процедуры окна и найти событие WM_MOUSE. Если вы используете библиотеку для управления окнами, то эта библиотека, вероятно, предоставит функциональность для ввода с клавиатуры и мыши.

Теперь, когда у вас есть ввод с помощью мыши, вы должны рисовать линию на экране каждый раз, когда пользователь перемещает мышь, удерживая нажатой кнопку:

glLineWidth(2.5); 
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
  glVertex2f(mouse_x_start, mouse_y_start);
  glVertex2f(mouse_x_end, mouse_y_end);
glEnd();
glColor3f(1.0, 1.0, 1.0);

Когда все вышеперечисленное пойдет хорошо, вы должны увидеть свою текстуру на экране и красную линию, если вы удерживаете кнопку мыши и перемещаете мышь. Вы почти там. Последнее, что нужно сделать, это прочитать пиксели. Вы можете сделать это с помощью glReadPixels() следующим образом:

void glReadPixels(0, 0, ширина_окна, высота_окна, GL_RGB, GL_UNSIGNED_BYTE, новые_данные_изображения);

Теперь у вас есть массив байтов с штрихами пользователя. Я настоятельно рекомендую написать собственный код для этого процесса, потому что код, который я использовал, устарел и должен использоваться только для более старых платформ. Однако рабочий процесс должен оставаться прежним. Я надеюсь, что этого достаточно, чтобы вы начали. Удачи!

person Kevin    schedule 11.06.2013
comment
Если я работаю в Linux, какая библиотека обеспечивает функциональность ввода с клавиатуры и мыши? как обратный вызов оконной процедуры? - person realmq; 18.06.2013
comment
Я никогда не работал с линуксом, поэтому ничего не могу сказать по этому поводу. Попробуйте поискать в Google цикл сообщений linux и посмотрите, поможет ли это вам дальше. - person Kevin; 18.06.2013

Я предполагаю, что вы работаете над простым 2D-приложением.
Идея состоит в том, что, если вас не волнует производительность, вы можете подумать о том, чтобы делать все в программном обеспечении, грубо манипулируя данными пикселей и рисуя изображение с помощью выбранной вами графической библиотеки. Я рекомендую библиотеку Simple Directmedia Layer. У него также есть подбиблиотека под названием SDL_image, которая может загружать большое количество форматов.
Подобный подход работает до тех пор, пока вы не возитесь с большими/множественными текстурами. Если вам нужна мощность графического процессора для частоты кадров в реальном времени, вы должны пробиться через объекты FrameBuffer, но будьте осторожны! По сути, это означает "делать все, что вы можете, внутри пиксельных шейдеров" и максимально ограничивать количество вызовов, таких как glReadPixels/glTexImage2D и т.д.

person user2464424    schedule 11.06.2013