2010-11-11 11 views
13

Jak zmienić piksel na wyświetlaczu, w C?Wyświetl piksel na ekranie w C

Założenie NIC: używam komputera z systemem Linux w tym celu. Nie chcę używać zestawów narzędzi lub frameworków GUI do rysowania pikseli. Nie chcę narysować piksela w oknie. Chcę narysować piksel bezpośrednio na ekranie.

EDYCJA: Mam ekran. Jestem na laptopie z linuxem z konsoli. Wolałbym rozwiązanie, które nie używa X, ponieważ wolałabym się nauczyć, jak działa X, niż używać X.

Jeśli jest więcej informacji, zapytaj, ale nie zakładaj. Nie próbuję tworzyć GUI, a to było głównym celem blokowania założeń, ponieważ nie chcę, aby ludzie zakładali, że robię rzeczy tak długo, kiedy w rzeczywistości po prostu majstruję.

EDYCJA 2: Możesz używać dowolnych bibliotek powiązanych z X11, pod warunkiem, że potrafisz wyjaśnić, jak działają.

+1

Dobrze, przypuszczam, że masz rację Kos. Po prostu nie chciałem, aby ludzie zakładali, że chcę podjąć długą drogę tylko po to, aby stworzyć graficzny interfejs użytkownika bez zestawu narzędzi, podczas gdy w rzeczywistości wolałbym dowiedzieć się, jak działają wyświetlacze. – DavidJFelix

+2

Jeśli nie możemy niczego założyć, nie mogę założyć, że pytanie jest po angielsku, ani nawet, że wyświetlane znaki opisujące pytanie mają związek z postaciami wpisanymi przez OP. OK, to głupie, ale jest to jedna z moich domowych gier, które mówią "nie zakładaj niczego!" kiedy w rzeczywistości oznaczają po prostu kilka podstawowych założeń, które chcą usunąć. – LarsH

+0

To jedna z moich domowych gier, kiedy ludzie przyjmują założenia. :) – DavidJFelix

Odpowiedz

10

Jeśli naprawdę nic nie zakładamy, czy możemy założyć, że X działa? Jeśli o to chodzi, czy możemy założyć, że istnieje karta wideo? Być może Linux działa bez głowy, a my uzyskujemy dostęp do niego przez konsolę szeregową.

Jeśli możemy założyć kilka rzeczy, załóżmy, że Linux został uruchomiony z obsługą bufora ramki. (Minęło kilka lat, odkąd pracowałem z framebufferami Linuksa, niektóre szczegóły mogę zepsuć.) Zostanie utworzone urządzenie, prawdopodobnie /dev/fb lub /dev/fb0. Otwórz ten plik i zacznij zapisywać wartości RGB z przesunięciem, a ekran zmieni się, prawie bez względu na wszystko: konsola tekstowa, konsola graficzna, pełnowartościowe środowisko pulpitu itp. Jeśli chcesz sprawdzić, czy obsługa bufora ramki działa, wykonaj dd if=/dev/zero of=/dev/fb w linii poleceń, a wyświetlacz powinien przejść cały czarny.

+1

'/ dev/urandom' lub' ~/naughty.pnm' jest o wiele bardziej zabawny niż '/ dev/zero' ... –

+0

Testowany. Ekran jest czarny. – DavidJFelix

+0

Czy to jest bezpieczne, ktoś? – Abdillah

13

C nie ma żadnych możliwości graficznych - do tego celu należy użyć biblioteki innej firmy.

+0

C jest językiem i nie ma żadnych * rzeczywistych * możliwości na własną rękę. Może chciałeś powiedzieć libc? – cdhowie

+2

OP podany Linux. Oznacza to, że masz dużo więcej niż zwykły C. –

+4

Biblioteka strony trzeciej będzie używała jakiegoś języka programowania (być może Zgromadzenia), ORAZ/LUB wsparcia z systemu operacyjnego i sterowników urządzeń. Oczywistym jest, że pytanie, w jaki sposób napisać taką bibliotekę osób trzecich, jest tutaj zadawane. Szkoda, że ​​te śmieci stają się bardziej popularne niż częściowo przydatna odpowiedź. –

6

Nie można przyjąć ekranu w C. Nie ma mowy, aby zrobić to, o co prosisz.

Edycja: OK, masz wyświetlacz, ale znowu nie ma wiele rzeczy, które można uzyskać stamtąd. Chodzi o to, że istnieje TON konkurencyjnych standardów dla wyświetlaczy graficznych i chociaż niektóre z nich (na przykład interfejsy VGA) są ustandaryzowane, wiele innych (na przykład interfejsy sterownika ekranu) NIE są. Wiele z tego, co robią X (i inne sterowniki urządzeń wyświetlających, takie jak Windows lub podobne), ma specyficzny kod interfejsu, który pozwala rozmawiać ze sterownikami ekranu; eliminują złożoność radzenia sobie ze sterownikami wyświetlacza. Systemy okienne mają jednak OGROMNE biblioteki skomplikowanego i specyficznego kodu do obsługi sterowników ekranu; fakt, że te rzeczy są względnie przejrzyste, świadczy o tym, ile pracy włożyli w te rzeczy w czasie.

+0

Możesz to zakładać. Używam linuksa z konsoli na laptopie. – DavidJFelix

+0

Następna rzecz, którą powinieneś mi powiedzieć, zakładam, że działa. :) –

+1

Dobrze więc przejść przez minimalne wymagania dotyczące sposobu, w jaki chciałbym przejść do ekranu. Możesz założyć wszystko, co dokładnie wyjaśnisz. – DavidJFelix

0

Myślę, że to, czego szukasz, to informacje o tym, jak pisać do bufora ramki. Najprostszym sposobem byłoby użycie SDL i renderowanie do bufora ramek, albo użycie GTK + z DirectFB, chociaż to jest sprzeczne z edyktem, jeśli nie używasz narzędzi ani frameworków.

+0

Zakłada się także, że istnieje framebuffer. Praca bez głowy jest całkowicie normalna. –

+3

McWafflestix: Chociaż pedantycznie prawdziwy, myślę, że to trochę nieszczere stwierdzenie, że nie można założyć ekranu. W końcu bez jakiegoś rodzaju wyświetlania pytanie nie ma żadnego sensu. – Cercerilla

+0

Tak, to pedantyczny. Ale trzeba mocno podkreślić, ponieważ to OP sugeruje, że zakłada "NIC". – dmckee

5

bardzo prymitywne i czyni wiele założeń:

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

W rzeczywistości należałoby użyć mmap zamiast write i zastosować odpowiednią ioctl kwerendy trybu ekranu zamiast zakładając 640xHHH 32bpp. Istnieją również problemy endianów itp.

Tak więc w prawdziwej rzeczywistości możesz użyć jakiegoś kodu biblioteki, który obsługuje takie rzeczy.

1

Przypuszczam, że można malować do programu terminalowego, którego używasz jako konsoli. Wszystko, co musisz zrobić, to dowiedzieć się, który to jest i sprawdzić.

Whoops Założyłem terminal. : P

+0

Zobacz także: ['aalib'] (http://aa-project.sourceforge.net/). – dmckee

-3

Twoim najlepszym przyjacielem będzie printf. Zasadniczo drukowana siatka z pewnym symbolem (np. ".") Oznaczałaby wszystkie piksele włączone. A drukowana siatka z białymi znakami (np. "") Oznaczałaby wyłączenie wszystkich pikseli. Na przykład to, jak możemy wyciągnąć sine() funkcji w zwykłym strumienia wyjściowego:

#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; 
} 

Który wygeneruje taki wynik:

0,0|                 X 
--------------------------------------------------------------------------> 
    |  **   **   **   **   ** 
    |  * *   * *   * *   * *   * * 
    | 
    | *    *    *    *    * 
    |   *    *    *    *    * 
    | 
    | *    *    *    *    * 
    |   *    *    *    *    * 
    | 
    | *    *    *    *    * 
    |   *    *    *    *    * 
    | 
    | *   * *   * *   * *   * *   * 
    |*   **   **   **   **   ** 
    | 
    Y| 
    | 
    v