Вопрос

Я работаю над игрой для iPhone, в которой используется механика рисования/рисования, и у меня возникают проблемы с попыткой создать инструмент, который стирал бы уже нарисованные объекты.

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

Какие-нибудь советы?

РЕДАКТИРОВАТЬ:Чтобы дать немного больше информации, я использую текстуры для своих кистей и использую glVertexPointer() и glDrawArrays() для их рендеринга.Например:

glBindTexture(GL_TEXTURE_2D, circleBrush);
glVertexPointer(3, GL_FLOAT, 0, verts);
glTexCoordPointer(2, GL_FLOAT, 0, coords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

РЕДАКТИРОВАТЬ 2:К сожалению, буферы трафаретов недоступны на iPhone.:(

РЕДАКТИРОВАТЬ 3:Объекты фреймбуфера доступны на iPhone, и я выбрал именно этот путь.Я еще не реализовал это полностью, но пока похоже, что все работает так, как я хотел.Всем спасибо!

Это было полезно?

Решение

Нарисуйте полноэкранный текстурированный квад поверх вашей сцены. Когда пользователь рисует мазок кисти, используйте glTexSubImage2D , чтобы обновить текстуру.

glReadPixels / glDrawPixels работает медленно.

Использование FrameBufferObjects еще лучше, но я сомневаюсь, что это расширение доступно на iPhone (опять же, я точно не знаю, так что, возможно, попробуйте). FBO позволяют рисовать непосредственно в текстуру, как если бы это был другой контекст рендеринга.

Другие советы

Трафаретный буфер - лучший способ подойти к этому наверняка ... Вы сэкономите время, ресурсы процессора и потенциальные проблемы ..., они доступны на Iphone, вам просто нужно создать поверхность OpenGlES 2.0 (не gles 1.0 или 1.1).

        //Turn off writing to the Color Buffer and Depth Buffer
        //We want to draw to the Stencil Buffer only
        glColorMask(false, false, false, false);
        glDepthMask(false);

        //Enable the Stencil Buffer
        glEnable(GL_STENCIL_TEST);

        //Set 1 into the stencil buffer
        glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

        //CALL YOUR DRAWING METHOD HERE


        //Turn on Color Buffer and Depth Buffer
        glColorMask(true, true, true, true);
        glDepthMask(true);

        //Only write to the Stencil Buffer where 1 is set
        glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
        //Keep the content of the Stencil Buffer
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

        //CALL OUR DRAWING METHOD AGAIN

Найти этот пример: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.c

Вот визуальный результат: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.jpg

Я внедрил такой же инструмент ластика с этим на Android и iPhone, и он работает как шарм!

Удачи!

Ура!

Вы не предоставляете много информации, но я предполагаю, что вы храните все, что они "рисуют" в буфер и затем рисуем его на экране следующим образом:

 glWindowPos2i(X, Y);
 glDrawPixels(drawing->Width, drawing->Height, drawing->Format, 
              GL_UNSIGNED_BYTE, drawing->ImageData);

С рисунком > ImageData является буфером. Что вы можете сделать, так это создать отдельный фоновый буфер и нарисовать его первым. Затем инструмент стирания просто уберет буфер рисования (повернув все значения, включая альфа, вверх).

Чтобы это решение работало, вам нужно включить смешивание и отключить проверку глубины .

 glEnable(GL_BLEND);
 glDisable(GL_DEPTH_TEST);
 glWindowPos2i(X, Y);
 //background never changes
 glDrawPixels(background->Width, background->Height, background->Format, 
              GL_UNSIGNED_BYTE, background->ImageData);
 glWindowPos2i(X, Y);
 glDrawPixels(drawing->Width, drawing->Height, drawing->Format, 
              GL_UNSIGNED_BYTE, drawing->ImageData);
 glEnable(GL_DEPTH_TEST);
 glDisable(GL_BLEND);

Это то, что вы ищете?

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

  • В то время, когда пользователи стираются, нарисуйте область «стерто» в буфер трафарета (используя трафарет, см. Ниже).Вы можете использовать любую функцию рисования GL для этого.

  • В каждом проходе рендеринга сначала нарисуйте фон (если вы хотите, вы можете использовать здесь отрицательный тест на трафарет, чтобы только нарисовать «стертную» часть фона - может повысить производительность).

  • Затем включите тест трафарета для всех других операций на рисовании.Затем OpenGL будет привлекать только «неэразированные» области.

Функция, определяющая, как буфер трафарета должен влиять на рисование (или нет):glStencilFunc()

Функция, определяющая влияние рисования на сам буфер трафарета:глСтенцилОп()

Дальнейшее объяснение, а также аргументы в пользу этого:http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node117.html

Использование режима glBlendFunc (GL_ONE, GL_ZERO) может быть полезным.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top