PMG https://forum.pmg.org.ru/ |
|
glCopyTexImage2D: востановление поврежденных участков экрана https://forum.pmg.org.ru/viewtopic.php?f=1&t=6812 |
Страница 1 из 5 |
Автор: | Vitone [ 05 июн 2009 17:47 ] |
Заголовок сообщения: | glCopyTexImage2D: востановление поврежденных участков экрана |
Использую .Net + Tao.Framework. Рисую много объектов, которые можно перемещать мышкой, то есть в маусмуве нужно переисовывать все изображение. Но поскольку объекты содержат много текста, это все подтормаживает, хуже чем в жди+. Решил перемещать не просто полупрозрачный прямоугольник (как изначально хотел), а реверсивную рамку. Работает замечательно, но не красиво. Потом мне посоветовали использовать glCopyTexImage2D, но у меня ничего не вышло - вместо наложения текстуры - черный прямоугольник. Идея следующая: перед тем как выводить перемещаемый объект(объекты), сначала записать в текстуру фрагмент изображения под ним, а потом когда мышь переместится - обновить участок. Работает быстро и замечательно, только обновляется не тем... Вот мой код (возможно логика задачи и нарушена, но вопрос в том, почему вместо текстуры черный прямоугольник): Код: bool startMouseMove=false;
int RenderTex; private void glControl_MouseMove(object sender, MouseEventArgs e) { Gl.glReadBuffer(Gl.GL_FRONT); Gl.glDrawBuffer(Gl.GL_FRONT); mousePosition = glControl.PointToClient(Cursor.Position); if (startMouseMove) { //Gl.glGenTextures(1, out RenderTex); Gl.glBindTexture(Gl.GL_TEXTURE_2D, RenderTex); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP); Gl.glCopyTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, mousePositionPrev.X - 35, mousePositionPrev.Y - 60, 70, 120, 1); Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2dv(new double[] { 0.0, 0.0 }); Gl.glVertex2d(mousePositionPrev.X-35, mousePositionPrev.Y-60); Gl.glTexCoord2dv(new double[] { 1.0, 0.0 }); Gl.glVertex2d(mousePositionPrev.X-35 + 70, mousePositionPrev.Y-60); Gl.glTexCoord2dv(new double[] { 1.0, 1.0 }); Gl.glVertex2d(mousePositionPrev.X-35 + 70, mousePositionPrev.Y -60 + 120); Gl.glTexCoord2dv(new double[] { 0.0, 1.0 }); Gl.glVertex2d(mousePositionPrev.X-35, mousePositionPrev.Y -60 + 120); Gl.glEnd(); } else { startMouseMove = true; } mousePositionPrev = mousePosition; //DrawFrames(mousePosition, 1); Gl.glFlush(); Gl.glDrawBuffer(Gl.GL_BACK); Gl.glReadBuffer(Gl.GL_BACK); } |
Автор: | MagicWolf [ 06 июн 2009 10:44 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Vitone писал(а): Использую .Net + Tao.Framework. Рисую много объектов, которые можно перемещать мышкой, то есть в маусмуве нужно переисовывать все изображение. Но поскольку объекты содержат много текста, это все подтормаживает, хуже чем в жди+. "Объекты содержат много текста" - это как??? Не совсем понятно. Или трехмерный объект из текста, или на объект на несен текст? В каком виде текст? |
Автор: | Vitone [ 06 июн 2009 12:12 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
MagicWolf писал(а): "Объекты содержат много текста" - это как??? Не совсем понятно. Или трехмерный объект из текста, или на объект на несен текст? В каком виде текст? Ну вот как-то так как на скрине. Текст вывожу с помощью Tao.Freetype (используя обертку). Но вопрос не по поводу этого, я уже смирился с тем что быстрее текст если и можно вывести, то это требует много усилий. Хочу перемещать блоки не перерисовывая экран, а обновляя поврежденные участки из текстуры. Только вместо текстуры черный прямоугольник наблюдается (вернее с текущим цветом). Текстуры вроде как включены: Gl.glEnable(Gl.GL_TEXTURE_2D); Что я делю не так? |
Автор: | bad_duck [ 08 июн 2009 21:42 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
твой вопросик? http://forum.sources.ru/index.php?showtopic=274591 Не знаю как с Код: Gl.glCopyTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, mousePositionPrev.X - 35, mousePositionPrev.Y - 60, 70, 120, 1); но с Код: glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, WIDTH, HEIGHT); у меня всё работает. Попробуй эту функцию.
|
Автор: | Vitone [ 09 июн 2009 00:57 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Я не знаю что я делаю не так, но результат не изменился. Вместо текстуры - заполнение текущим цветом. Может спецификацию не внимательно читаю - ну не получается и все! Вот на всякий случай привожу измененный код. Код: private void glControl_MouseMove(object sender, MouseEventArgs e) { if (!allowMouseMove) return; mousePosition = glControl.PointToClient(Cursor.Position); Gl.glDrawBuffer(Gl.GL_FRONT); Gl.glReadBuffer(Gl.GL_FRONT); Gl.glColor3f(1f, 1f, 1f); // Current color if (startMouseMove) { Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2dv(new double[] { 0.0, 0.0 }); Gl.glVertex2d(mousePositionPrev.X, mousePositionPrev.Y); Gl.glTexCoord2dv(new double[] { 1.0, 0.0 }); Gl.glVertex2d(mousePositionPrev.X + 70, mousePositionPrev.Y); Gl.glTexCoord2dv(new double[] { 1.0, 1.0 }); Gl.glVertex2d(mousePositionPrev.X + 70, mousePositionPrev.Y + 120); Gl.glTexCoord2dv(new double[] { 0.0, 1.0 }); Gl.glVertex2d(mousePositionPrev.X, mousePositionPrev.Y + 120); Gl.glEnd(); //Gl.glFlush(); } else { startMouseMove = true; } //Gl.glGenTextures(1, out RenderTex); Gl.glBindTexture(Gl.GL_TEXTURE_2D, RenderTex); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP); //Gl.glCopyTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, mousePosition.X, mousePosition.Y, 70, 120, 1); Gl.glCopyTexSubImage2D(Gl.GL_TEXTURE_2D, 0, 0, 0, mousePosition.X, mousePosition.Y, 70, 120); DrawFramesFill(mousePosition, 1); // Moving object Gl.glFlush(); mousePositionPrev = mousePosition; Gl.glDrawBuffer(Gl.GL_BACK); } bad_duck, можешь привести кусок кода где эта команда 100% рабочая, если код не секретный? Спасибо. |
Автор: | Vitone [ 09 июн 2009 01:13 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Кстати, забыл проверить на ошибку... Код: Gl.glCopyTexSubImage2D(Gl.GL_TEXTURE_2D, 0, 0, 0, mousePosition.X, mousePosition.Y, 70, 120); int err=Gl.glGetError(); при этом err=1281. Как програмно узнать что за ошибка, неужели поочередно сравнить со всеми? Что может означать GL_INVALID_VALUE в данном случае? |
Автор: | MagicWolf [ 09 июн 2009 10:08 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
OpenGL медленно работает, когда что-то копируется с экрана. Идеология OGL завязана на вывод, быстрый вывод и двойную буферизацию. Поэтому мне кажется вначале надо определиться почему ты используешь OGL для двухмерной графики, а не GDI или что-то другое, например, gtk? И еще один принципиальный вопрос - ты zoom будешь делать? |
Автор: | bad_duck [ 09 июн 2009 10:46 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Vitone, я сам этой функцией не пользуюсь, по совету MagicWolf'а я использую frame buffer object, это тоже самое, но работает намного быстрее и намного больше возможностей. Вот упрощенный кусок кода из исходника про тени Код: RenderWorld(); glBindTexture(GL_TEXTURE_2D, g_Texture[SHADOW_ID]); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, (int)SHADOW_WIDTH, (int)SHADOW_HEIGHT); //В этом месте скопировался экран в текстуру, а потом расчеты и применение этой текстуры. //Все отлично работает ApplyShadowMap(); RenderWorld(); Если надо вот ссылка на исходник http://www.google.com/codesearch/url?hl ... FYZNDPp1fw Посмотри внимательно как там создается текстура. Может ты ее не правильно создаешь?! |
Автор: | Vitone [ 09 июн 2009 11:46 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
MagicWolf писал(а): OpenGL медленно работает, когда что-то копируется с экрана. Идеология OGL завязана на вывод, быстрый вывод и двойную буферизацию. Поэтому мне кажется вначале надо определиться почему ты используешь OGL для двухмерной графики, а не GDI или что-то другое, например, gtk? И еще один принципиальный вопрос - ты zoom будешь делать? 1. Я использовал GDI+, в принципе, не плохо, но все же мне не нравится. попробывал то же самое на ОЖЛ - совсем другое дело - появилась возможность вывести красивые полупрозрачные блоки вместо безобразных угловатых прямоугольников. Все таки C# с графикой не очень дружит. Единственное что мне не понравилось в ОЖЛ - это медленный вывод текста, потому приходится придумывать хитрые алгоритмы, чтобы избежать перерисовку всего экрана при движении мыши. Кроме того - то что я привел на форуме - лишь верхушка айсберга того что необходимо сделать, дальше будут более сложные объекты, возможно даже объемные. В общем GDI+ - это не то что мне нужно. 2. Мое приложение рассчитано на изменения масштаба, проверил - отлично работает. |
Автор: | MagicWolf [ 09 июн 2009 13:16 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Понятно. Чтобы ускорить вывод текста можно использовать технику описанную в http://pmg.org.ru/nehe/nehe17.htm - Урок 17. Двухмерные шрифты из текстур. Как быстрее я не знаю. Единственное для zoom надо делать mipmap. Можно использовать либу - http://students.cs.byu.edu/~bfish или самому что-то делать. Для вывода графики лучше не использовать C#, написать dll с графическими функциями на C++, и потом ее вызывать. >красивые полупрозрачные блоки вместо безобразных угловатых прямоугольников Не совсем понял. Я конечно активно GDI+ не юзал, но вроде сглаживание там есть и смешивание тоже. Или я не прав? |
Автор: | Inferno7000 [ 09 июн 2009 15:33 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Цитата: Все таки C# с графикой не очень дружит. C# плюс XNA очень дружит с графикой. Цитата: Для вывода графики лучше не использовать C#, написать dll с графическими функциями на C++, и потом ее вызывать. А как же кроссплатформенность? И что вы имеете против C#? Ведь это типизированный, объектно-ориентированный язык который активно продвигается Microsoft. Его новые версии выходят с каждым новым компилятором. Скоро на подходе новая версия языка и новая версия фреймворка: Net Framework 4.0. |
Автор: | MagicWolf [ 09 июн 2009 16:40 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Ничего не имею против C#, если еще с XNA и без столкновений. Но C# не подходит для реализации быстрых и ресурсоемких алгоритмов. |
Автор: | Inferno7000 [ 09 июн 2009 17:27 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Цитата: Но C# не подходит для реализации быстрых и ресурсоемких алгоритмов. Каких? Какие алгоритмы работают быстрее на C++, чем на C#. И где их применяют в играх? |
Автор: | Vitone [ 09 июн 2009 20:23 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Да, мне важна кроссплатформенность, именно потому я использую связку C#+OpenGL. Поимо этого, С# позволяет "на лету" создавать сборки что для меня очень важно. Я вот не в курсе пойдет ли XNA под Mono (нужно будет выяснить этот вопрос, но никак руки не доходят), а вот OGL я проверял - все ОК. По поводу текста еще есть такая идея что при первом его выводе, сохранять весь блок текста в текстуру (этим же способом что я пытаюсь), и изменять ее только при изменении масштаба или самого блока. Таким образом совместить шрифты FreeType и текстурные. Что скажете по поводу этой идее? Спасибо всем за помощь, буду учитывать все советы. |
Автор: | Inferno7000 [ 09 июн 2009 21:21 ] |
Заголовок сообщения: | Re: glCopyTexImage2D: востановление поврежденных участков экрана |
Цитата: Я вот не в курсе пойдет ли XNA под Mono Как только xna будет портирована под Linux, то конечно же пойдет. http://code.google.com/p/monoxna/ |
Страница 1 из 5 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |