View Full Version : [C++] Accendere pixel su linux
Ciao ragazzi :D
vorrei fare un programmino che una volta avviato accenda dei pixel che scelgo io fin quando non viene terminato...
questo su linux :)
solo che non ho la piu pallida idea di che libreria e che funzioni utilizzare :asd:
qualcuno saprebbe indicarmi la strada? :D
io lo so fare su Windows :O
Ciao ragazzi :D
vorrei fare un programmino che una volta avviato accenda dei pixel che scelgo io fin quando non viene terminato...
questo su linux :)
solo che non ho la piu pallida idea di che libreria e che funzioni utilizzare :asd:
qualcuno saprebbe indicarmi la strada? :D
ma con X avviato?
senza far partire x potresti usare il frame buffer.
oppure con X avviato puoi usare le xlib:
http://en.wikipedia.org/wiki/Xlib
io lo so fare su Windows :O
beh se me lo dici sapere una cosa in piu non mi fa male :D
ma con X avviato?
senza far partire x potresti usare il frame buffer.
si con x avviato :D
oppure con X avviato puoi usare le xlib:
http://en.wikipedia.org/wiki/Xlib
potresti indicarmi la funziona da usare? perchè ce ne sono un casino e non riesco a capure quale fa al caso mio :eek:
potresti indicarmi la funziona da usare? perchè ce ne sono un casino e non riesco a capure quale fa al caso mio :eek:
a dir il vero non le ho mai usate, ma leggendo il manual reference penso che dovrebbe essere XDrawPoint(display, drawable, gcontex, x, y).
http://tronche.com/gui/x/xlib/graphics/drawing/XDrawPoint.html
a dir il vero non le ho mai usate, ma leggendo il manual reference penso che dovrebbe essere XDrawPoint(display, drawable, gcontex, x, y).
http://tronche.com/gui/x/xlib/graphics/drawing/XDrawPoint.html
ok, si dovrebbe fare al caso mio...
guardandone pero una simile forse mi semplifica ancora piu le cose perchè dovrei in realtà fare un paio di linee rosse sullo schermo...
http://www.tronche.com/gui/x/xlib/graphics/drawing/XDrawLine.html
XDrawLine(display, d, gc, x1, y1, x2, y2)
ma non capisco cosa devo passare a parte le coordinate e come...
cioe a display, d, gc cosa devo passare? io devo semplicemente dare le coordinate ed il colore rosso oppure a scelta dell'utente...
penso che a display debba passare il numero del display, poi gc è di tipo struct ma ha tantissimi parametri a sua volta :(
Guardando gli esempi dovrebbe venire cosi:
Display *display = XOpenDisplay(NULL);
int screen = DefaultScreen(display);
Window window = XCreateSimpleWindow(display, RootWindow(display, screen), 1, 1, 640, 480, 1, BlackPixel(display, screen), WhitePixel(display, screen));
XDrawLine(display, window, DefaultGC(display, screen), 50, 50, 100,100);
prova a guardare questo tutorial:
http://tronche.com/gui/x/xlib-tutorial/
beh se me lo dici sapere una cosa in piu non mi fa male :D banalisssssimo: http://msdn2.microsoft.com/en-us/library/ms532304.aspx
come DC (primo parametro) basta che usi quello che ottieni dalla chiamata GetDC(NULL), che sarebbe quello associato allo schermo:
http://msdn2.microsoft.com/en-us/library/ms533241.aspx
ok grazie ad entrambi...
su linux devo vedere con calma il nome del pacchetto da installare su ubuntu
su windows invece ho fatto cosi
#include <windows.h>
[...]
SetPixel( GetDC(NULL), i, j, RGB(255,0,0) );
ma eclipse cdt mi da errore: undefined reference to 'SetPixel@16'
penso cio sia dovuto ad una mancata lettura corretta da parte del linker di windows.h o qualcosa del genere, e presuppongo che debba passare qualche cosa al linker ma non saprei neanche come fare:asd:
lo stesso errore lo da anche code::blocks... come risolvo :D ?
su windows sono riuscito a compilarlo con code::blocks creando un nuovo progetto: applicazione grafica win32... su eclipse non ho ancora capito come fare e sono in attesa di delucidazioni.
con code::blocks sono riuscito a compilarlo, ma innanzi tutto mi crea un eseguibile di 1.3 mb che mi sembra un pochino tanto per il codice che ho scritto :eek: poi appena avviato si rallenta tutto in una maniera indicibile...
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
int main(int argc, char* argv[]) {
int width = 1280,
height = 800,
size = 10;
if( argc == 3) {
width = atol(argv[1]);
height = atol(argv[2]);
size = atol(argv[3]);
}
while(1) {
for(int i = width/2 - size; i <= width/2 + size; i++ )
SetPixel( GetDC(NULL), i, height/2, RGB(255,0,0) );
for(int j = height/2 - size; j <= height/2 + size; j++ )
SetPixel( GetDC(NULL), width/2, j, RGB(255,0,0) );
}
system("PAUSE");
return 0;
}
se non metto il while(1) prima dei due for mi appaiono i pixel per un secondo e poi l'applicazione si chiude, io invece vorrei rimanessero sempre fin quando io non chiudo l'applicazione, come fa ora insomma, ma senza rallentare in questo modo il sistema e creando se possibile un eseguibile piu piccolo :eek:
banryu79
07-04-2008, 09:49
se non metto il while(1) prima dei due for mi appaiono i pixel per un secondo e poi l'applicazione si chiude, io invece vorrei rimanessero sempre fin quando io non chiudo l'applicazione, come fa ora insomma, ma senza rallentare in questo modo il sistema e creando se possibile un eseguibile piu piccolo :eek:
Bhe, quel while infinito contenente due cicli for ti va un pochino a monopolizzare la CPU, ci vorrebbe uno sleep di 1 microsec. :fagiano:
Bhe, quel while infinito contenente due cicli for ti va un pochino a monopolizzare la CPU, ci vorrebbe uno sleep di 1 microsec. :fagiano:
ho messo uno Sleep(250) precedentemente, perchè solo a partire da quel numero riesco ad abbassare un po' la cpu portandola a 11-14%, aumentando troppo poi si vede...
ma mi sembra ancora troppo, e credo ci sia un modo migliore, perchè ho scaricato un altro programma che fa la stessa cosa e prende lo 0% di cpu :cry:
Slash, potevi dirlo prima che volevi colorare una linea e non solo un pixel :D
colorare un pixel alla volta a suon di SetPixel è estremamente inefficiente perché ciascuna SetPixel richiede uno switch in kernel mode e un bel po' di altre operazioni (tipo la mappatura dei colori di sistema se per caso il colore che gli hai dato è un colore di sistema) per poi alla fine... settare pochi bytes :muro:
tutto quel popo' di operazioni puoi farlo solo O(1) volte anziché O(N) volte (N lunghezza della linea in pixels) usando le funzioni MoveToEx e LineTo:
http://msdn2.microsoft.com/en-us/library/ms534247(VS.85).aspx
http://msdn2.microsoft.com/en-us/library/ms534256(VS.85).aspx
inoltre non serve che cerchi il DC ogni volta: chiama GetDC una volta sola, salvati l'HDC e usalo per le chiamate seguenti.
per quanto riguarda le dimensioni dell'eseguibile, ad ingigantirle oltremodo è il codice di inizializzazione del runtime del C++ che la maggior parte dei compilatori del mondo includono automaticamente (pensa ad esempio al costruttore dell'oggetto cout, oggetto che è sempre presente in un programma C++; questo è solo un esempio).
per rimuovere tale codice (una volta che sei sicuro che non lo userai mai, ma ti consiglierei di lasciarlo) devi cercare tra le opzioni della linea di comando del MinGW.
ok grazie, ho modificato usando le due funzioni e seguendo l'esempio sul sito msdn...
ma non esce niente :(
#define WINVER 0x0501
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
int main(int argc, char* argv[]) {
int width = 1280,
height = 800,
size = 10;
if( argc == 3) {
width = atol(argv[1]);
height = atol(argv[2]);
size = atol(argv[3]);
}
HDC hdc;
HWND hwnd;
hdc = GetDC(hwnd);
while(1) {
MoveToEx(hdc, (width/2) - 10, height/2, NULL);
LineTo(hdc, (width/2) + 10, height/2);
MoveToEx(hdc, width/2, (height/2) - 10, NULL);
LineTo(hdc, width/2, (height/2) + 10);
}
ReleaseDC(hwnd, hdc);
system("PAUSE");
return 0;
}
anche sostituendo hwnd con null :(
e poi non ho capito come passo il colore :D
sostituendo hwnd con NULL a me funziona perfettamente...
per passare il colore a questo punto devi usare un oggetto Pen; lo crei con CreatePen e lo imposti del DC con SelectObject:
http://msdn2.microsoft.com/en-us/library/ms535467.aspx
http://msdn2.microsoft.com/en-us/library/ms533272(VS.85).aspx
alla fine ricordati di deselezionarlo (sempre con SelectObject) e di distruggerlo con DeleteObject:
http://msdn2.microsoft.com/en-us/library/ms533225.aspx
rettifico il mio post precedente: ho scoperto questa utile funzione:
http://msdn2.microsoft.com/en-us/library/ms533237(VS.85).aspx
grazie ad essa non ti serve di creare un nuovo oggetto Pen; inoltre chiarisco meglio un punto: SelectObject non offre un modo per deselezionare un oggetto, ma semplicemente per selezionarne un altro al posto suo (cosa che provoca la "deselezione" del primo).
in effetti funziona, evidentemente si era incantato prima, perchè non funzionava :eek:
l'unica cosa che non va è il colore, il codice è il seguente ma è sempre nero... perdonami per la mia stoltezza :asd:
#define WINVER 0x0501
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
int main(int argc, char* argv[]) {
int width = 1280,
height = 800,
size = 10;
if( argc == 3) {
width = atol(argv[1]);
height = atol(argv[2]);
size = atol(argv[3]);
}
HDC hdc;
hdc = GetDC(NULL);
SetDCPenColor(hdc,RGB(255, 0, 0));
while(1) {
Sleep(1);
MoveToEx(hdc, (width/2) - (size/2), height/2, NULL);
LineTo(hdc, (width/2) + 1 + (size/2), height/2);
MoveToEx(hdc, width/2, (height/2) - (size/2), NULL);
LineTo(hdc, width/2, (height/2) + 1 + (size/2));
}
ReleaseDC(NULL, hdc);
system("PAUSE");
return 0;
}
poi non ho capito bene il fatto della riduzione della dimensione... :O
grazie per la pazienza, poi dopo spero di riuscirlo a fare su linux :asd:
SetDCPenColor(hdc,RGB(255, 0, 0));
:D
SetDCPenColor(hdc,RGB(255, 0, 0));
:D
se vedi sopra l'ho messo identico, ma a me è sempre nero il colore :D
mah, in effetti devo dire che sta funzione non... funziona ( :asd: ) neanche a me... per qualche motivo credo non sia possibile usarla in questo contesto (la penna selezionata non è modificabile?). crea manualmente un nuovo oggetto Pen.
banryu79
09-04-2008, 18:30
Invece di cercare di impostare il colore della penna "di default" del Device Context prova così:
- ti crei una nuova penna impostandole il colore desiderato (vedi funzione createPen (http://msdn2.microsoft.com/en-us/library/ms535467(VS.85).aspx))
- salvi la "penna di default" e la sostituisci nel Device Context con la nuova penna creata (vedi funzione selectObject (http://msdn2.microsoft.com/en-us/library/ms533272(VS.85).aspx))
- fai quello che devi fare con quella penna, e quando hai finito ripristini la "penna di default" (sempre con la funzione selectObject)
Ciao ;)
ok grazie ragazzi, funziona :D
ma non capisco perchè appena avvio un gioco scompare :cry:
il mio intento era di quello di usarlo nei giochi ed averlo sempre in primo piano :(
banryu79
10-04-2008, 14:23
ok grazie ragazzi, funziona :D
ma non capisco perchè appena avvio un gioco scompare :cry:
il mio intento era di quello di usarlo nei giochi ed averlo sempre in primo piano :(
Perchè il gioco crea e gestisce un suo Device Context su cui tu non puoi metterci le manine, no?
Ma che ti serve avere una linea rossa che ti taglia in due il monitor sempre e comunque :confused:
Perchè il gioco crea e gestisce un suo Device Context su cui tu non puoi metterci le manine, no?
Ma che ti serve avere una linea rossa che ti taglia in due il monitor sempre e comunque :confused:
mi serve per fare da mirino negli sparatutto :asd:
siccome ho un programmino che fa questo per windows volevo farne uno stesso per linux ed imparare a farlo per windows per sfizio ;)
DanieleC88
10-04-2008, 21:57
mi serve per fare da mirino negli sparatutto :asd:
:eekk:
...
Sorvoliamo. :D
Una cosa fatta in fretta per Xlib (perdonatemi eventuali errori, non le conosco, ho fatto giusto questo per l'occasione):
#include <X11/Xlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define SIZE 10
int main(int argc, char *argv[])
{
unsigned int hwidth, hheight;
Display *xdisp;
Window wroot;
XColor red;
GC gc;
if ((xdisp = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "Couldn't open the default display.\n");
return EXIT_FAILURE;
}
wroot = DefaultRootWindow(xdisp);
gc = XCreateGC(xdisp, wroot, 0, NULL);
hwidth = XDisplayWidth(xdisp, 0) / 2;
hheight = XDisplayHeight(xdisp, 0) / 2;
XParseColor(xdisp, DefaultColormap(xdisp, 0), "#FF0000", &red);
XAllocColor(xdisp, DefaultColormap(xdisp, 0), &red);
XSetForeground(xdisp, gc, red.pixel);
while (1) {
XDrawLine(xdisp, wroot, gc, hwidth - (SIZE / 2), hheight, hwidth + (SIZE / 2), hheight);
XDrawLine(xdisp, wroot, gc, hwidth, hheight - (SIZE / 2), hwidth, hheight + (SIZE / 2));
XSync(xdisp, False);
}
XCloseDisplay(xdisp);
return EXIT_SUCCESS;
}
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.