#opengl #3d
#opengl #3D
Вопрос:
Раньше я писал небольшие игры с рисованием «на пиксель», я имею в виду с некоторой функцией SetPixel (x, y, color) или тому подобное.
Я также интересуюсь OpenGL, но не очень разбираюсь в нем.
Это хороший (быстрый) способ сделать рисование на пиксель в OpenGL?
Было бы хорошо, например, использовать текстурированные квадратики в качестве спрайтов или всего фонового экрана приложения, с возможностью установки отдельного пикселя с помощью какой-то моей собственной процедуры SetPixel, которую я бы написал … или любым другим способом, но она должна быть настолько эффективной, насколько это возможно
(особенно меня интересует версия OGL basic fundamenta 1.0)
Комментарии:
1. Кстати, OpenGL 1.0 может показаться самым простым, но на самом деле OpenGL 1.1 — это наименьший общий знаменатель. Я никогда не видел платформы, которая не поддерживала бы как минимум 1.1 (и будь то в программном обеспечении). В версии 1.0 у вас нет текстурных объектов и массивов вершин.
2. хорошо, tnx много, полезно знать
Ответ №1:
Вы можете установить проекцию, которая будет отображать координаты вершин 1: 1 в пиксельные координаты:
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width, 0, window_height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
С этого момента координаты вершин X, Y указаны в пикселях с началом координат в нижнем левом углу. Теоретически вы могли бы использовать немедленный режим с примитивами GL_POINT. Но это гораздо лучшая идея для пакетной обработки. Вместо того, чтобы отправлять каждую точку по отдельности, создайте массив всех точек, которые вы хотите нарисовать:
struct Vertex
{
GLfloat x,y,red,green,blue;
};
std::vector<Vertex> vertices;
/* fill the vertices vector */
На это вы можете указать OpenGL…
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
/* Those next two calls don't copy the data, they set a pointer, so vertices must not be deallocated, as long OpenGL points to it! */
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), amp;vertices[0].x);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), amp;vertices[0].red);
… и получить к нему доступ и нарисовать все это одним вызовом:
glDrawArrays(GL_POINTS, 0, vertices.size();
Комментарии:
1. Много TNX, я проверю это — но могут ли эти массивы быть большими для многих пиксельных рисунков, скажем, 10k 100k 1M? могу ли я удалить его до 0 и заполнить его своими процедурами рисования пикселей, опять же, каждый кадр?
2. @user982377: Ну, вы не должны использовать его для рисования целых изображений (используйте текстуры для этого), это больше похоже на рисование графика. Технически существует только ограничение типа данных index, но с точки зрения производительности вы не должны объединять более 2 ^ 16 точек по соображениям производительности. Заполнение его новыми данными не является проблемой, однако после изменения размера базовый адрес, вероятно, изменится, поэтому его необходимо сбросить. Дело в том, что манипулирование одиночными пикселями имеет смысл только для разреженных манипуляций с изображениями. Если вы занимаетесь массовым бизнесом, текстуры — это правильный путь.
3. @user982377: Также не забывайте о мощности процессора, необходимой для вычисления этих новых пикселей. Вычисление 1M новых значений для каждого кадра, вероятно, остановит графический процессор, потому что процессор не поспевает за ним. Вы должны просто сказать нам, что вы планируете делать, чтобы мы могли предложить что-то лучше.
4. Я не знаю, можете ли вы взглянуть на мои простые проги (исполняемый файл Windows): dl.dropbox.com/u/42887985/bociaki5.zip и dl.dropbox.com/u/42887985/unpack aeroplane pack.zip Все это делается с помощью setpixel в GDI — это похоже на то, что мне очень нравится способ создания прогов «у меня есть setpixel, я могу подумать, что делать» — я хочу делать 2d-вещи таким образомспособ — не думать о неприкасаемых спрайтах, как в OpenGL untouchable quad textures: Нет, я вижу 2 варианта — с упомянутыми вами массивами или с загрузкой целой четырехъядерной текстуры на gpu в каждом кадре … поэтому я повторяю, что мне нужен «общий способ 2d setpixel» под ogl
5. (иногда это также не должен быть установленный пиксель, это может быть также DrawLine (x, y, x2, y2, color) (для 2d-тестов по физике)
Ответ №2:
Вы действительно не хотите этого делать.
Это хороший (быстрый) способ сделать рисование на пиксель в OpenGL?
Нет хорошего или быстрого способа сделать это. Это крайне не рекомендуется из-за скорости.
Правильный способ, хотя и непростой (или в некоторых случаях возможный) в OGL 1, заключается в использовании пиксельных шейдеров или режимов наложения. Это единственный правильный способ, все остальное взламывает всю систему.
В зависимости от того, как необходимо изменить данные, цвета вершин и режимы наложения могут решить некоторые задачи. Это не будет подкрашивать каждый пиксель по отдельности, но вы можете изменить текстуру быстрее.
Для этого вы можете рисовать однопиксельные квадраты (хотя необходимо соблюдать осторожность, чтобы их смещать и обрабатывать фильтрацию, чтобы предотвратить размытие), или вы можете получить данные текстуры и обработать их позже. Оба будут невероятно медленными, но могут функционировать.
Работа с текстурными данными, вероятно, проще и может быть немного быстрее.
Комментарии:
1. На самом деле это не отвечает на вопрос, тем более, что он хочет OGL 1.0.
2. шейдеры не подходят для меня, потому что я говорю об очень простом dundamental ogl 1.0 или max 1.3; последний вариант, который вы упомянули, если я имею в виду, что это «передача всей текстуры» с графического процессора в ОЗУ и обратно, тоже плох на самом деле — значит ли это, что делать это, возможно, не быстро, а только умереннокаким образом это невозможно? очень плохие новости
3. «На самом деле это не отвечает на вопрос», но это полезно для tnx, но, возможно, можно сделать еще что-то
4. пользователь982377: Если вам нужно вручную редактировать какие-либо данные, нет никаких шансов, что они будут равномерно неопределенно быстрыми, они будут чрезвычайно медленными. Будет еще хуже, если вы используете ограниченную платформу (скажем, мобильную), которая и так работает медленно.
5. В идеале было бы получить «unsigned char PixelBuffer [y] [x] [3]» в ОЗУ и найти эффективный способ «перенести» его на поверхность OGL или лучшую текстуру… (Я использую ПК / Windows, но предполагаю, что очень слабые интегрированные графические карты с OGL max 1.3)