Показать пиксель на экране в C - PullRequest
15 голосов
/ 11 ноября 2010

Как бы я изменил пиксель на дисплее, в C?

Предположим, НИЧЕГО: я использую Linux-машину из консоли, чтобы сделать это. Я не хочу использовать GUI инструментарий или рамки для рисования пикселя. Я не хочу рисовать пиксель в окне. Я хочу нарисовать пиксель прямо на экране.

РЕДАКТИРОВАТЬ: у меня есть экран. Я на ноутбуке под управлением Linux с консоли. Я бы предпочел решение, не использующее X, так как я бы лучше изучил, как работает X, чем как использовать X.

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

РЕДАКТИРОВАТЬ 2: Вы можете использовать любые библиотеки, связанные с X11, при условии, что вы сможете объяснить, как они работают.

Ответы [ 7 ]

13 голосов
/ 11 ноября 2010

C не имеет графических возможностей - для этого вам понадобится сторонняя библиотека.

12 голосов
/ 11 ноября 2010

Если мы действительно ничего не предполагаем, можем ли мы предположить, что X работает? В этом отношении, мы можем даже предположить, что есть видеокарта? Возможно, Linux работает без головы, и мы обращаемся к нему через последовательную консоль.

Если нам позволено предположить несколько вещей, давайте предположим, что Linux загрузился с поддержкой кадрового буфера. (Прошло пару лет с тех пор, как я работал с кадровыми буферами Linux, некоторые детали могут быть неверными.) Будет создано устройство, вероятно, /dev/fb или /dev/fb0. Откройте этот файл и начните записывать значения RGB со смещением, и экран изменится, практически независимо от чего-либо: текстовой консоли, графической консоли, полноценного рабочего стола и т. Д. Если вы хотите увидеть, работает ли поддержка кадрового буфера, выполните dd if=/dev/zero of=/dev/fb в командной строке, и дисплей должен стать черным.

6 голосов
/ 11 ноября 2010

Вы не можете предполагать отображение на C. Нет буквально никакого способа сделать то, что вы просите.

Редактировать: Хорошо, у вас есть дисплей, но опять же, вы можете получить не так много. Дело в том, что существует TON конкурирующих стандартов для графических дисплеев, и хотя некоторые из них (например, интерфейсы VGA) стандартизированы, многие другие (например, интерфейсы драйверов дисплея) НЕ. Многое из того, что делает X (и другие драйверы устройств отображения, такие как Windows или тому подобное), имеет специальный интерфейсный код для связи с драйверами дисплея; они абстрагируются от сложности работы с драйверами дисплея. Системы окон, тем не менее, имеют ОГРОМНЫЕ библиотеки сложного и специального кода для работы с драйверами дисплея; тот факт, что эти вещи относительно прозрачны, свидетельствует о том, сколько работы они вложили в эти вещи с течением времени.

5 голосов
/ 11 ноября 2010

Очень примитивно и делает много предположений:

fd = open("/dev/fb0", O_RDWR);
lseek(fd, 640*y+x, SEEK_SET);
write(fd, "\377\377\377\377", 4);

В действительности вы бы использовали mmap вместо write и использовали бы соответствующий ioctl для запроса режима экрана, а непри условии 640xHHH 32bpp.Есть также проблемы с порядком байтов и т. Д.

Так что в реальной жизни вы можете использовать какой-то библиотечный код, который обрабатывает такие вещи для вас.

1 голос
/ 11 ноября 2010

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

Упс, я принял терминал. : P

0 голосов
/ 27 февраля 2013

Ваш лучший друг будет printf. В основном напечатанная сетка с некоторым символом (таким как '.') Будет означать все пиксели на. А напечатанная сетка с символом пробела (например, '') будет означать отключение всех пикселей. Например, вот как мы можем нарисовать функцию sine() в простом потоке вывода:

#include <stdio.h>

#define MAXY 20
#define MAXX 75
static char display[MAXY][MAXX];

void setGraph(void) {
    memset(display, ' ', sizeof(display));

    int i;
    // draw Y axis
    for (i=0; i < MAXY; i++)
      display[i][3] = '|';
    // draw X axis
    for (i=0; i < MAXX; i++)
      display[1][i] = '-';
    // draw origin
    display[0][0] = '0';
    display[0][1] = ',';
    display[0][2] = '0';
    // draw arrows
    display[1][MAXX-1] = '>';
    display[MAXY-1][3] = 'v';
    // draw labels
    display[0][MAXX-3] = 'X';
    display[MAXY-3][2] = 'Y';
}

void plotSine() {
    int i;
    int y;
    for (i=4; i < MAXX; i++) {
        y = 2 + (int)7.0*(1.0 + sin(0.45*(float)i));
        display[y][i] = '.';
    }
}

void drawDisplay(void) {
    int x,y;
    for (x=0; x < MAXY; x++) {
      for (y=0; y < MAXX; y++) {
        printf("%c", display[x][y]);
      }
      printf("\n");
    }
}

int main () {
    setGraph();
    plotSine();
    drawDisplay();
    return 0;
}

Который будет генерировать такой вывод:

0,0|                                                                    X
-------------------------------------------------------------------------->
   |      **            **            **            **            **
   |     *  *          *  *          *  *          *  *          *  *
   |
   |    *             *             *             *             *
   |         *             *             *             *             *
   |
   |   *             *             *             *             *
   |          *             *             *             *             *
   |
   |  *             *             *             *             *
   |           *             *             *             *             *
   |
   | *          *  *          *  *          *  *          *  *          *
   |*            **            **            **            **            **
   |
  Y|
   |
   v
0 голосов
/ 11 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...