Hallo,
dies ist mehr oder weniger die Fortsetzung von
Beitrag "[C] Win7: Console in Vollbildmodus - SetConsoleDisplayMode not implemented" ...
Kurz: Ich hab ein kleines Spiel ("2D-Shooter" oder so ähnlich)
programmiert. Für die Grafik hab ich einfach die DOS-Konsole maximiert
und nutze ASCII-Zeichen. Geht unter XP prima, unter Windows 7 aufgrund
anderer API nicht. Der Versuch der Sache mit GTK+ und einer Art
Eigenbaukonsole Herr zu werden ist bisher an der Komplexität dieses
Frameworks gescheitert.
Aber: Ich habe mittlerweile ein kleines Programm "entwickelt"
(Guttenbergmethode = Code aus dem Internet zusammenkopiert) welches sich
als Ersatz für eine maximierte DOS-Konsole eignet. Darin lässt sich
mittels Pfeiltasten eine Spur zeichnen.
Problem: Das ganze ist viel zu langsam, obwohl ich den Timer auf 1ms
gestellt habe. Hat jemand einen Vorschlag wie ich die Sache deutlich
schneller kriege? Ich hatte schon testweise den Buffer als String-Array
definiert
(
1
typedefcharstring_t[XMAX+1];
2
string_tbuffer[YMAX];
3
//...
4
for(y=0;y<YMAX;y++)
5
buffer[y][80]='\0';
6
//...
7
cairo_show_text(cr,buffer[y]);
), macht die Sache aber nicht merklich schneller.
Vorschläge?
PS: Das Programm lässt sich mit Alt+F4 beenden.
Ja, zeichne alles in ein Bild.
Danach zeichnest du das Bild auf den Bildschirm. Wenn sich etwas ändert
zeichnest du nur das neu was sich geändert hat.
Ist bei deiner Konsole alles schwarz / weiss oder verwendest du Farben?
Ggf. wäre ein Textfeld oder ein Label Besser geieignet für dich, habe
ich aber selbst noch nie ausprobiert.
mfg Andreas
Aja, ich lese gerade noch von einem Timer mit 1ms?
Was ist das für ein Timer? Codestück?
Du wirst wohl kaum 1ms hinkriegen, da macht der Scheduler bei weitem
nicht mehr mit.
Viellicht solltest du mal genauer beschreiben was der Ablauf deines
Programms ist, warscheinlich hast du noch einen Groben Denkfehler
drin...
mfg Andreas
Ahh, Anhang ist ja da!
Sorry, dann noch ein Post...
http://developer.gnome.org/glib/2.26/glib-The-Main-Event-Loop.html#g-timeout-add
Note that timeout functions may be delayed, due to the processing of
other event sources. Thus they should not be relied on for precise
timing. After each call to the timeout function, the time of the next
timeout is recalculated based on the current time and the given interval
(it does not try to 'catch up' time lost in delays).
Also dieser Timeout wird sicher nicht alle 1ms auftreten.
Dann weiter:
gtk_widget_queue_draw(window); //neuzeichnen auslösen
da steht queue drin, also dein neuzeichnen wird in die Warteschlange
gestellt.
neu gezeichnet wird dann wenn er Zeit hat. Leider hat er aber keine
Zeit, da die ganze Zeit dein Timer auslöst, und ihm sagt er soll dann
mal neu zeichnen...
Versuche mal den Timer höher zu stellen, und nur neu zeichnen was
wirklich nötig ist.
Zudem geht das rendern von Text relativ lange, ggf. könntest du ein Bild
machen (dynamisch) und dann dieses Zeichnen, das könnte noch einen
Performance Vorteil bringen.
Mit den richtigen Parametern ist das dann sicher kein Problem, ich
stelle PDFs so dar, und da lässt sich flüssig scrollen...
mfg Andreas
Oh - das ging schnell!
Andreas B. schrieb:> Ja, zeichne alles in ein Bild.>> Danach zeichnest du das Bild auf den Bildschirm. Wenn sich etwas ändert> zeichnest du nur das neu was sich geändert hat.
Da werd ich erstmal googeln müssen, die GTK bzw Cairo-Doku ist imho
fürchterlich unübersichtlich und kompliziert. :-(
> Ist bei deiner Konsole alles schwarz / weiss oder verwendest du Farben?
Nur S/W.
> Ggf. wäre ein Textfeld oder ein Label Besser geieignet für dich, habe> ich aber selbst noch nie ausprobiert.
Kann man das auf weiße Schrift mit schwarzem Hintergrund stellen? Die
Idee gefällt mir, ich guck mal ob das so geht.
Andreas B. schrieb:> Aja, ich lese gerade noch von einem Timer mit 1ms?>> Was ist das für ein Timer? Codestück?
show_image() ist die Callbackfunktion und der Timer steckt hier:
1
g_timeout_add(1,show_image,NULL);//Timer
> Du wirst wohl kaum 1ms hinkriegen, da macht der Scheduler bei weitem> nicht mehr mit.
Schon klar, 1ms heißt "so schnell wie möglich", testweise. Eigentlich
reicht alle 20 ms oder so, aber das ist eben viel zu langsam, deshalb
hatte ich mal am Timer gedreht.
> Viellicht solltest du mal genauer beschreiben was der Ablauf deines> Programms ist, warscheinlich hast du noch einen Groben Denkfehler> drin...
Das eigentliche Programm welches halt nur unter XP läuft funktioniert
prima, der Ablauf ist ganz einfach (Pseudocode):
1
volatileinttimertick;
2
3
CALLBACKvoidtimer(void)
4
{
5
timertick++;
6
}
7
8
intmain(void)
9
{
10
initkrempel();
11
setzeTimer:timer()jedemsaufrufen
12
13
timertick=0;
14
while(!ende)
15
{
16
while(timertick<20)
17
Sleep(1);
18
19
Gegnerbewegen();
20
TastenabfragenundSpielfigurbewegen();
21
usw.
22
23
AllesneuinverstecktenBufferzeichnen();
24
25
Bufferanzeigen();
26
}
27
}
Ob der Timer jetzt wirklich jede ms aufgerufen wird ist mir egal, das
ganze ist schnell genug mit viel Spielraum in Richtung schneller. Den
Timer auf 20ms zu setzen ginge auch, ich war bisher nur zu faul den Code
zu ändern.
Mit GTK geht das aufgrund von gtk_main() so nicht, also hab ich die
Spiellogik (Tastenabfrage und Bewegung) in eine Callbackfunktion gepackt
welche per Timer regelmäßig aufgerufen wird. Um die Änderungen sichtbar
zu machen feuere ich dann noch ein passendes event ab, die
Zeichenfunktion steckt in der Callbackfunktion welche aufgerufen wird.
Das klappt auch, ist nur eben zu langsam.
Allein für die paar Codezeilen hab ich ewig gegoogelt...
Der Weise schrieb:> Wie wäre es mit OpenGL? Dann hättest du Hartwarebeschleunigung und es> wäre schneller.
Nein, da du bei OpenGL den Text auf der CPU renderst, dann als Textur
einfügen musst und dann erst dargestellt wird wirst du nicht schneller
sein.
Von der Komplexität wollen wir garnicht sprechen...
mfg Andreas
Der Weise schrieb:> Wie wäre es mit OpenGL? Dann hättest du Hartwarebeschleunigung und es> wäre schneller.
Das ist wahrscheinlich wieder hochkompliziert und was vollkommen neues,
jetzt wo ich gerade anfange das Prinzip von GTK so ein ganz kleines
bisschen zu verstehen...
Andreas B. schrieb:> gtk_widget_queue_draw(window); //neuzeichnen auslösen>> da steht queue drin, also dein neuzeichnen wird in die Warteschlange> gestellt.>> neu gezeichnet wird dann wenn er Zeit hat. Leider hat er aber keine> Zeit, da die ganze Zeit dein Timer auslöst, und ihm sagt er soll dann> mal neu zeichnen...
Das ist nicht doof... Ich hab mal gtk_widget_queue_draw durch den
eigentlichen Code fürs neuzeichnen ersetzt, die Callbackfunktion redraw
geleert und den Timer auf 20ms gestellt: Fehlanzeige, das zeichnet nur
mit ein paar Hertz, von 50 sind wir weit entfernt...
> Zudem geht das rendern von Text relativ lange, ggf. könntest du ein Bild> machen (dynamisch) und dann dieses Zeichnen, das könnte noch einen> Performance Vorteil bringen.
Das verstehe ich jetzt nicht, was meinst du mit "Bild machen"?
xpler schrieb:> Oh - das ging schnell!
Zu schnell, ich musste 3 mal Posten bis ich alles gesagt hatte=)
> Allein für die paar Codezeilen hab ich ewig gegoogelt...
Jaja, kenne ich.
Mein Projekt ist OpenSource, da du aber wohl Anfänger bist nützt es dir
nichts wenn ich dir das gebe...
Ich gebe hier ein paar Codeschnipsel, und hoffe die bringen dir was:
Die Variable in die neu gezeichnet wird:
Hier die Position einstellen, also willst nur (40,40) / (60, 60) neu
zeichnen, so verschibst du du einfach um -40, -40, und oben bei der
Grösse gibst du 20, 20 an.
1
cairo_translate(crRect,-x,-y);
Hier zeichnen.
1
cairo_destroy(crRect);
Hier wird dann tatsächlich auf das Fenster gezeichnet, das geht schnell!
In etwa so geht das ziemlich gut, Timing nicht zu schnell machen!
Schnelles Timing wird dich negativ, nicht positiv beeinflussen!
Du sollste ggf. eher KeyEvents auf dem Window abfangen, anstatt zu
Pollen, das braucht viel Leistung.
mfg Andreas
Ich habe dein Beispiel etwas angepasst, so läufts.
Das mit der Grafik bringt sicher was, wenn du das Multihtreaded und
korrekt machst, mein Auszug oben reicht nicht, aber wenn du nur den
geänderten Bereich neu zeichnest ist es viel schneller.
IST NUR EIN EINFACHES BEISPIEL.
Am besten machst du Setter die dann die Daten korrekt handeln etc.
mfg Andreas
Andreas B. schrieb:> Ich habe dein Beispiel etwas angepasst, so läufts.
Irgendwie steig ich da nicht durch. Wenn ich das laufen lasse sehe ich
nur ein ganz kleines Stückchen schwarzen Hintergrund, ich will doch das
ganze Fenster schwarz haben... Naja, vielleicht brauch ich eine Pause.
80*50 Labels zu erstellen klappt übrigens auch nicht wirklich, das
Ändern der Beschriftung braucht seine Zeit.
Wenn ich meinen Code so abändere dass nur noch geänderte Teile des
Bildes neu gezeichnet werden
funktioniert es schnell genug, aber eben nur so lange nur nur wenig
geändert wird, das ist auch keine Lösung.
Ich geb die Suche nach der schnellsten Funktion für heute auf, bis
morgen...
xpler schrieb:> Ich geb die Suche nach der schnellsten Funktion für heute auf,> bis morgen...
Eventuell statt mal nach der "schnellen einfachen unkomplizierten
Funktion" zu suchen mal einen geeigneten Algorithmus/Datenstruktur
wählen?
Wenn du wirklich "nur" eine Textkonsole haben willst, würde ich:
- char array als Schnittstelle zwischen "Konsole" und Programm
- Ein großes Canvas
- Alle zu verwendenden Zeichen als Bild einmalig erstellen (dynamisch
oder statisch)
- Immer wenn sich ein Buchstabe ändert das vorgerechnete Bild an die
passende Stelle malen
- das Ganze noch in passenden Model/View/Controller Klassen kapseln
fertig ist deine Konsole und auch noch bestimmt unschlagbar schnell als
die Variante "immer alles malen".
Ich weiss das nicht alles neu gezeichnet wird, ist auch nur ein
Beispiel, und nicht die fertige Lösung.
Mach folgendes:
Erstelle dir eine Grafik, in der legst du das ganze Alphabet ab.
Wie siehst du oben, dann zeichnest du keine Buchstaben mehr sondern
kopierst Stücke des Bildes auf deinen Bildschirm.
Zudem zeichnest du nur neu was du wirklich musst, siehe GdkEventExpose
*event, da drin hats ein Area oder so.
Dann erreichst du diese Performance locker.
Falls nicht, oder du Probleme hast: melde dich einfach nochmal hier.
Warum so: Schriften sind Vektorgrafiken, um diese auf den Bildschirm zu
bringen müssen diese gerendert werden, also es müssen Bezierkurven etc.
berechnet werden, das braucht viel Zeit. Das kopieren eines
Speicherbereiches geht schneller.
Und ich muss meine obige Aussage nochmals korrigieren: am schnellsten
wärst du wenn du das mit OpenGL machen würdest, alle möglichen Zeichen
als Texturen auf die Grafikkarte lädst und dann das Bild so
zusammenbaust. Kannst du aber vergessen, da viel zu aufwändig, und das
einfache "Text schreiben" mit OpenGL ist nicht schneller wie das hier.
Würde natürlich so nur mit proportionalen Schriften funktionieren;-)
mfg Andreas
Andreas B. schrieb:> Mach folgendes:> [...]
Genau das habe ich versucht zu basteln (s. Anhang), so wirklich schnell
ist es aber auch nicht... Verbesserungsvorschläge?
Es gibt einen kleinen Schönheitsfehler bei der Darstellung, das liegt
aber nur an der verwendeten Bilddatei (auf die Schnelle mit Paint
gemacht).
xpler schrieb:> so wirklich schnell> ist es aber auch nicht
Definiere wirklich schnell.. wieso lädst du z.B. das PNG ständig neu?
Eine Sinnvolle Kapselung ist auch nicht zu erkenne und daher auch schwer
zu durchschauen ob du nun wirklich nur den benötigten Bereich
neuzeichest/neuzeichnen lässt...
Läubi .. schrieb:> xpler schrieb:>> so wirklich schnell>> ist es aber auch nicht> Definiere wirklich schnell..
Der Timer steht auf 20ms, das heißt wenn man eine der Pfeiltasten drückt
müsste das Ding im Idealfall innerhalb einer Sekunde quer über den
Monitor flitzen. Tut es aber nicht, subjektiv ist es also zu langsam.
> wieso lädst du z.B. das PNG ständig neu?
Weil ich Anfänger bin? ;-) Ich änder das mal schnell.
> Eine Sinnvolle Kapselung ist auch nicht zu erkenne und daher auch schwer> zu durchschauen ob du nun wirklich nur den benötigten Bereich> neuzeichest/neuzeichnen lässt...
Mit Kapselung meinst du irgendwas Objektorientertes oder? Da bin ich
überfragt, hab im Gegensatz zu dir kein Informatikstudium im Lebenslauf
stehen...
xpler schrieb:> Mit Kapselung meinst du irgendwas Objektorientertes oder?
Nicht zwangsläufig, aber bei C++ böte es sich zumindest an.
Du hast aber wenigstens zweilaml eine gleiche/sehr ähnliche Codestückke,
das sollte man besser in eine Funktion auslagern.
Auch so was:
1
buffer[Px][Py]='x';
ist unschön, besser
1
functionsetChar(intx,inty,charc){
2
buffer[x][y]=c;
3
}
dann ist klar was passiert, und falls nachher noch irgendwelche
Umrechnungen machen muss hat man nur eine Stelle ändern und man hat den
Code nicht mehrmals, wenn dir jetzt auffällt das die indizierung besser
umgekehrt geschehen sollte.
xpler schrieb:> Der Timer steht auf 20ms
Kenne mich mit GTK nicht so aus, aber das ist eine Schlechte Idee, es
muss für Keyevents bei GTK bestimmt spezielle Eventhandler geben, so
verbrätst du unnötig Rechenzeit, auch das zeichnen im Timerevent scheint
mir etwas suspekt.
Läubi .. schrieb:> xpler schrieb:>> Mit Kapselung meinst du irgendwas Objektorientertes oder?>> Nicht zwangsläufig, aber bei C++ böte es sich zumindest an.
Ich programmier aber in C...
> Du hast aber wenigstens zweilaml eine gleiche/sehr ähnliche Codestückke,> das sollte man besser in eine Funktion auslagern.
Ja, stimmt. Das was ich da erzeugt habe ist Testcode, da kommen solche
Unschönheiten schonmal vor. Wenn alles funktioniert mach ich das
ordentlich (schlechte Vorgehensweise, ich weiß).
> Auch so was:
1
buffer[Px][Py]='x';
ist unschön, besser
1
function
2
>setChar(intx,inty,charc){
3
>buffer[x][y]=c;
4
>}
dann ist klar was passiert, und falls nachher noch irgendwelche
> Umrechnungen machen muss hat man nur eine Stelle ändern und man hat den> Code nicht mehrmals, wenn dir jetzt auffällt das die indizierung besser> umgekehrt geschehen sollte.
S.o.
> xpler schrieb:> Kenne mich mit GTK nicht so aus, aber das ist eine Schlechte Idee, es> muss für Keyevents bei GTK bestimmt spezielle Eventhandler geben,
Ich wühl mich mal weiter durch die Doku, mal sehen
> auch das zeichnen im Timerevent scheint> mir etwas suspekt.
Das ist mir auch suspekt, aber ich sehe bisher keine andere Möglichkeit
das neue Zeichen auf den Monitor zu bringen. Es müsste eine Funktion
gtk_widget_queue_draw() geben die nur für einen bestimmten Bereich eine
"neu zeichnen"-Anforderung stellt (ich krieg es nicht besser erklärt).
> Kenne mich mit GTK nicht so aus, aber das ist eine Schlechte Idee, es> muss für Keyevents bei GTK bestimmt spezielle Eventhandler geben,
Habe ich mittlerweile gefunden:
http://developer.gnome.org/gtk/2.24/GtkWidget.html#GtkWidget-key-press-event
Problem: schnarchlangsam! Code kann ich wenn gewünscht hochladen, ist ja
nur eine neue Callbackfunktion und ein paar Abfragen.
xpler schrieb:> Problem: schnarchlangsam! Code kann ich wenn gewünscht hochladen, ist ja> nur eine neue Callbackfunktion und ein paar Abfragen.
Kein Wunder!
Ich habe frühestens Freitag Abend Zeit, habe gerade Prüfungen.
Mach mal folgendes (oder versuchs zumindest, wenns nicht klappt bin ich
schon hilfsbereit;-))
1. Verwende GTK Events, entferne dein windows.h include (dann kann ich
es unter Linux problemlos Testen...)
2. Entferne deinen Timer, den brauchst du nicht mehr da du ja events
kriegst.
3. mach eine Funktion setChar(int x, int y, char c), diese setzt den
Char im Array. NUR DA darfst du ins Array schreiben.
4. Die Funktion setChar sagt das neu gezeichnet werden muss, und zwar
mit
1
voidgtk_widget_queue_draw_area(GtkWidget*widget,
2
gintx,
3
ginty,
4
gintwidth,
5
gintheight);
5. In deinem Draw zeichnest du nur neu was verlangt wird. Du findest das
heraus über
Tipp: gboolean gdk_rectangle_intersect(GdkRectangle *src1, GdkRectangle
*src2, NULL);
So findest du einfach heraus ob was du neu zeichnen musst und was nicht,
du musst auch die angeschnittenen Teile neu zeichnen.
mfg Andreas
Andreas B. schrieb:> xpler schrieb:>> Problem: schnarchlangsam! Code kann ich wenn gewünscht hochladen, ist ja>> nur eine neue Callbackfunktion und ein paar Abfragen.>> Kein Wunder!
Wieso?
> Ich habe frühestens Freitag Abend Zeit, habe gerade Prüfungen.
Oh Oh, viel Erfolg!
> 5. In deinem Draw zeichnest du nur neu was verlangt wird. Du findest das> heraus über>
Das ist wohl die Callbackfunktion oder? Google kennt den Namen nämlich
nicht.
Ich hab jetzt alle Tipps umgesetzt (inkl. event->area beim neu
zeichnen), aber es ist immer noch viel zu langsam. :-(
> Tipp: gboolean gdk_rectangle_intersect(GdkRectangle *src1, GdkRectangle> *src2, NULL);> So findest du einfach heraus ob was du neu zeichnen musst und was nicht,> du musst auch die angeschnittenen Teile neu zeichnen.
Hab ich jetzt nicht gebraucht, hab das anders gelöst (s. Code).
xpler schrieb:> Andreas B. schrieb:>> xpler schrieb:>>> Problem: schnarchlangsam! Code kann ich wenn gewünscht hochladen, ist ja>>> nur eine neue Callbackfunktion und ein paar Abfragen.>>>> Kein Wunder!> Wieso?
Du hast bei jedem Tastendruck ein komplettes neuzeichnen erzwungen.
Dein Auge ist jedoch garnicht in der Lage diese Geschwindigkeit zu
sehen.
Und dein PC weigert sich das zu rendern;-)
>>> Ich habe frühestens Freitag Abend Zeit, habe gerade Prüfungen.> Oh Oh, viel Erfolg!
Danke.
>>> 5. In deinem Draw zeichnest du nur neu was verlangt wird. Du findest das>> heraus über>>
> Das ist wohl die Callbackfunktion oder? Google kennt den Namen nämlich> nicht.
Sorry, natürlich;-) Aber hast du ja korrekt erkannt, soweit ich das auf
der kürze beurteilen kann.
>> Ich hab jetzt alle Tipps umgesetzt (inkl. event->area beim neu> zeichnen), aber es ist immer noch viel zu langsam. :-(>>> Tipp: gboolean gdk_rectangle_intersect(GdkRectangle *src1, GdkRectangle>> *src2, NULL);>> So findest du einfach heraus ob was du neu zeichnen musst und was nicht,>> du musst auch die angeschnittenen Teile neu zeichnen.> Hab ich jetzt nicht gebraucht, hab das anders gelöst (s. Code).
Auch gut, was ist dein Problem jetzt? Ich habs gerade getestet, ich
würde sagen läuft flüssig?
Ggf. ist für dich die Keywiderholungsfrequenz noch das Problem, oder was
ist das Problem?
Du kannst auf Release und Press reagieren, dann ignorierst du mehrere
Press events, und reagierst erst wider beim Loslassen.
Intern verwendest du einen Timer, bei dem du dann nichts machst als die
Variable zu verändern und ein queue draw oder sowas aufrufst.
Warscheinlich ist das was du willst.
1
structGdkEventKey{
2
GdkEventTypetype;
3
GdkWindow*window;
4
gint8send_event;
5
guint32time;
6
guintstate;
7
guintkeyval;
8
gintlength;
9
gchar*string;
10
guint16hardware_keycode;
11
guint8group;
12
guintis_modifier:1;
13
};
GdkEventType type;
the type of the event (GDK_KEY_PRESS or GDK_KEY_RELEASE).
mfg Andreas
Andreas B. schrieb:> Du hast bei jedem Tastendruck ein komplettes neuzeichnen erzwungen.>> Dein Auge ist jedoch garnicht in der Lage diese Geschwindigkeit zu> sehen.>> Und dein PC weigert sich das zu rendern;-)
Ah, ok.
> Auch gut, was ist dein Problem jetzt? Ich habs gerade getestet, ich> würde sagen läuft flüssig?
Naja, bei mir läuft es zwar "flüssig" aber eben mit einer Refreshrate
von ein paar Hertz, für ein Spiel ein bisschen langsam. So ein Bilder
mehr pro Sekunde sollten es schon sein. Wenn du ein Windowsystem (<=XP)
hast kann ich mal ein Testcode der alten Version (ohne GTK) hochladen,
das flitzt wie geölt.
> Ggf. ist für dich die Keywiderholungsfrequenz noch das Problem, oder was> ist das Problem?
Ach so, Moment... Das Neuzeichnen wird ja jetzt durch Key-Events
ausgelöst, wenn diese also nur mit begrenzter Geschwindigkeit
verarbeitet werden bremst das auch die Framerate. Moment mal... (Test
Test Test) OK, wenn ich GetAsyncKeyState() und einen Timer verwende sind
die Wiederholungsfrequenz der Tastendrücke und die Framerate der Anzeige
hoch genug. Da ich kein Linux brauche kann ich das so machen, dann würde
ich mal sagen Problem erstmal gelöst. :-)
Danke für die Hilfe!
xpler schrieb:> dann würde> ich mal sagen Problem erstmal gelöst. :-)
nein! Wieso soll der PC den alle paar hunder ms ein Bild neuzeichnen
wenn sich nix ändert? Das ist doch der Witz, wenn sich nur alle 10 sek
was ändert zeichnet man auch nur dann neu, eine "Framerate" macht bei
einer Konsole überhaut keinen Sinn.
xpler schrieb:> Ach so, hat vielleicht jemand einen Tipp wie ich ein PNG mit allen> Zeichen vom DOS-Zeichensatz erstellen kann?http://acspro.atari.org/KeyTab/Modern/0604.html
Läubi .. schrieb:> xpler schrieb:>> dann würde>> ich mal sagen Problem erstmal gelöst. :-)>> nein! Wieso soll der PC den alle paar hunder ms ein Bild neuzeichnen> wenn sich nix ändert? Das ist doch der Witz, wenn sich nur alle 10 sek> was ändert zeichnet man auch nur dann neu, eine "Framerate" macht bei> einer Konsole überhaut keinen Sinn.
Aber er zeichnet doch nur neu wenn sich etwas ändert!
>> xpler schrieb:>> Ach so, hat vielleicht jemand einen Tipp wie ich ein PNG mit allen>> Zeichen vom DOS-Zeichensatz erstellen kann?>> http://acspro.atari.org/KeyTab/Modern/0604.html
Sieht gut aus, Danke.
xpler schrieb:> Läubi .. schrieb:>> nein! Wieso soll der PC den alle paar hunder ms ein Bild neuzeichnen>> wenn sich nix ändert? Das ist doch der Witz, wenn sich nur alle 10 sek>> was ändert zeichnet man auch nur dann neu, eine "Framerate" macht bei>> einer Konsole überhaut keinen Sinn.> Aber er zeichnet doch nur neu wenn sich etwas ändert!
Ne, halt, stimmt nicht. setChar() wird durch die Timerfunktion in der
die Tastenabfrage läuft ja doch wieder regelmäßig aufgerufen. :-(
xpler schrieb:> In setChar() wird auch das neu zeichnen ausgelöst. Was meint ihr/du> (Läubi), kann man das so lassen oder ist es all zu großer Murks?
In setChar solltest du wenigstens noch prüfen ob an der stelle eventuell
schon das passende Zeichen steht.
So, mittlerweile funktioniert das Ganze fast zufriedenstellend. "Fast"
weil es durch die Größe der Buchstaben nicht bildschirmfüllend ist.
Cairo hat ja eine scale-Funktion aber damit bekomme ich die Sache nicht
hin, kann mir jemand einen Tipp geben?
Also, am einfachsten machst du dir eine Variable, in der du den
zoomfaktor speicherst. (Wenn du Vollbild startest machst du das ein mal
beim Starten, sonst beim Resizen des Fensters)
Der Zoomfaktor ist ganz einfach: 1.0 = 1:1 Abbild, 0.5 = Halb so gross,
2.0 = doppelt so gross.
also
Dies hebt sich dann schlussendlich wider auf. Du musst es aber trotzdem
machen, GTK optimiert das ganze, und dann kann es sein das sonst
Artefakte entstehen könnten.
Und wenns nicht gleich klappt: Denk mal darüber nach ob ggf. etwas
verkehrt herum ist, ich habs nicht ausprobiert, und bei dem Zoom zeugs
hat man schnell mal ein 1/x zuviel oder zuwenig...
mfg Andreas
xpler schrieb:> Ich bekomme ständig folgende Meldung wenn ich cairo_scale benutze:>>
1
Assertion failed: status == CAIRO_STATUS_SUCCESS, file
2
> cairo-pattern.c, line 224
3
> 9
4
>
5
> This application has requested the Runtime to terminate it in an unusual
6
> way.
7
> Please contact the application's support team for more information.
8
>
9
> Process returned 3 (0x3) execution time : 1.687 s
10
> Press any key to continue.
>> ?
Dann musst du einfach Debuggen, also "Steop Over", bis abschmiert,
nachher schaust du dir die Zeile an die nicht funktioniert hat und
denkst darüber nach warum nicht.
Wenn du selbst nicht darauf kommst was das Problem ist fragst du hier
nochmals nach, natürlich die entsprechende Zeile angeben, sonst wirds
schwierig...
mfg Andreas
Andreas B. schrieb:> Also, am einfachsten machst du dir eine Variable, in der du den> zoomfaktor speicherst. (Wenn du Vollbild startest machst du das ein mal> beim Starten, sonst beim Resizen des Fensters)>> Der Zoomfaktor ist ganz einfach: 1.0 = 1:1 Abbild, 0.5 = Halb so gross,> 2.0 = doppelt so gross.
Ok, soweit war ich schon gekommen. Erstmal testweise für meine
Auflösung:
> Und wenns nicht gleich klappt: Denk mal darüber nach ob ggf. etwas> verkehrt herum ist, ich habs nicht ausprobiert, und bei dem Zoom zeugs> hat man schnell mal ein 1/x zuviel oder zuwenig...
Also in X-Richtung funktioniert es prima, aber sobald zoomY einen
anderen Wert als 1 hat kommt nur noch Käse raus. Irgendwo ist da noch
der Wurm drin, ich geh dann mal auf die Suche...
Andreas B. schrieb:> xpler schrieb:>> Ich bekomme ständig folgende Meldung wenn ich cairo_scale benutze:>>>>
1
Assertion failed: status == CAIRO_STATUS_SUCCESS, file
2
>> cairo-pattern.c, line 224
3
>> 9
4
>>
5
>> This application has requested the Runtime to terminate it in an unusual
6
>> way.
7
>> Please contact the application's support team for more information.
8
>>
9
>> Process returned 3 (0x3) execution time : 1.687 s
10
>> Press any key to continue.
>>> Dann musst du einfach Debuggen, also "Steop Over", bis abschmiert,> nachher schaust du dir die Zeile an die nicht funktioniert hat und> denkst darüber nach warum nicht.
Stimmt natürlich, nur habe ich keine cairo-pattern.c...
xpler schrieb:>> Dann musst du einfach Debuggen, also "Steop Over", bis abschmiert,>> nachher schaust du dir die Zeile an die nicht funktioniert hat und>> denkst darüber nach warum nicht.> Stimmt natürlich, nur habe ich keine cairo-pattern.c...
Bei "Step Over" brauchst du das auch nicht.
Du musst nur DEIN code Debuggen, denn mit ziemlicher Sicherheit liegt
der Fehler da.
mfg Andreas
Andreas B. schrieb:> Du musst nur DEIN code Debuggen, denn mit ziemlicher Sicherheit liegt> der Fehler da.
Ach so, manchmal sieht man den Wald vor lauter Bäumen nicht mehr...
Ich komm nicht drauf. Der Code läuft fehlerlos durch, in X-Richtung
passt es mit dem Zoom aber sobald ZoomY einen anderen Wert als 1 hat
bekomme ich nur Streifen auf dem Monitor. Argh.
Gibt mal die Zoomfaktoren aus.
Hier könnte das Problem liegen, ich bin mir gerade nicht sicher mit den
Prioritäten.
double zoomX=(double)1280/(XMAX*SZ_PIC_X),
zoomY=(double)1024/(YMAX*SZ_PIC_Y);
Schreibe lieber:
double zoomX=1280.0/(XMAX*SZ_PIC_X);
double zoomY=1024.0/(YMAX*SZ_PIC_Y);
mfg Andreas
Hm... Die Zoomfaktoren sind mit beiden Methoden korrekt (zoomX=2 und
zoomY=1,28), das Problem bleibt.
Aber: Wenn ich zoomY auf eine Ganzzahl (2) setze funktioniert es (aber
ist natürlich zu groß). Offensichtlich gibt die Gleitkommazahl irgendwo
Probleme. Hab mal testweise ein paar Casts eingebaut, das löst das
Problem leider auch nicht. Hätte mich auch gewundert, ich sehe keine
Stelle (außer der Faktorenberechnung) wo Casts nötig wären.
setze mal beide auf 1.2x und schaue obs dann geht...
Ich habe immer zwei mal den gleichen Wert verwendet.
(Etwas anderes macht bei einem PDF auch keinen Sinn)
mfg Andreas
Andreas B. schrieb:> setze mal beide auf 1.2x und schaue obs dann geht...
Es geht nicht, ich bekomme horizontale und vertikale Streifen. Ist das
vielleicht eine Einschränkung in der Library dass die Werte Ganzzahlen
sein müssen?!?
Andreas B. schrieb:> Mit Ganzzahlen funktioniert es?
Ja. Mit zoomX=2 (berechneter Wert) und zoomY=1 oder zoomY=2 funktioniert
es. Mit zoomX=2 und zoomY=1.28 funktioniert es nicht.
in der Schleife und siehe da, ich bekomme immer vernünftige Rechtecke,
auch mit zoomY!=1. Es liegt also am Befehl cairo_set_source_surface()
oder am Bild.
Ich kann machen was ich will, cairo_scale() und
cairo_set_source_surface() vertragen sich nicht. Was meint ihr, könnte
es eine Lösung sein die Buchstaben erst in ein PNG zu schreiben, dieses
irgendwie zu zoomen (ohne cairo_scale) (wie?) und anzuzeigen oder gibt
das wieder andere Probleme? Ich weiß langsam nicht mehr weiter.
Habs jetzt gerade nicht mehr im Kopf, nim mal für x und y den gleichen
Faktor.
Wenns dann nicht geht lade nochmals den kompletten Code hoch. Dann
schaue ich nochmals rein.
mfg Andreas
Andreas B. schrieb:> Habs jetzt gerade nicht mehr im Kopf, nim mal für x und y den gleichen> Faktor.
Geht auch nicht.
> Wenns dann nicht geht lade nochmals den kompletten Code hoch. Dann> schaue ich nochmals rein.
Ist im Anhang, Dankeschön.
Mailinglist sind normalerweise auf Englisch.
Wenn du kein Englisch kannst schreibe auf Deutsch, lasse es von Google
Translator übersetzten und sende beides auf die Mailinglist;-)
Es werden sich warscheinlich ein paar Leute beschweren, aber es hat
ziemlich sicher auch Deutschsprachige Dabei...
Ansonsten, schaue dir doch mal noch Gnome-terminal an...
http://git.gnome.org/browse/gnome-terminal/tree/src?h=gnome-2-30
Ich habe momentan keine Zeit um mehr zu helfen...
mfg Andreas
Autor: Andreas B. (andreasb)
Datum: 18.02.2012 17:20
>Schreibe direkt auf die GTK Mailinglists.
Na ja, wenn es um Cairo geht wohl eher
cairo@cairographics.org
Aber für wirklich schnelle Animation ist Cairo nicht so gut geeignet, da
wäre wohl OpenGL besser. Achje, Windows -- warum muss man da GTK und
Cairo verwenden, haben die nichts eigenes?
Salewski, Stefan schrieb:> Autor: Andreas B. (andreasb)> Datum: 18.02.2012 17:20>>>Schreibe direkt auf die GTK Mailinglists.>> Na ja, wenn es um Cairo geht wohl eher>> cairo@cairographics.org
Hast du natürlich recht...
> Aber für wirklich schnelle Animation ist Cairo nicht so gut geeignet, da> wäre wohl OpenGL besser. Achje, Windows -- warum muss man da GTK und> Cairo verwenden, haben die nichts eigenes?
Vergiss OpenGL, dafür hat er 1. zuwenig Erfahrung und 2. ist der
Performance Unterschied zu gering.
Was würdest du denn unter Windows verwenden?
Ich denke vom Komfort her ist Cairo definitiv eine sehr gute Wahl...
mfg Andreas
Im übrigen handelt es sich um einen einen Programierfehler, nicht um ein
Cairo Problem.
Ich bin gerade am suchen. Kann doch nicht so schwer sein:-/
mfg Andreas
Hier die Lösung
Es waren mehrere Problem, das wichtigste: Cairo Zeichnet das Zeichen
Oberhalb der angegebenen Koordinate, und das war ausserhalb des neu
gezeichneten Bereiches.
ps. wenn ich mich nicht irre macht auch Java das so...
Bei mir funktioniert das jetzt flüssig, ich habe noch ein Rechteck um
den Buchstaben gezeichnet, das ist nur zum Debuggen, kannst du ja wider
raus nehmen.
mfg Andreas
xpler schrieb:> Öhh Moment, du nutzt ja das PNG gar nicht sondern hast das wieder auf> Text umgestrickt. Warum? Geht es mit dem PNG nicht?
weil so das Problem mit der Skalierung weg ist.
Optimieren könntest du es indem du zur Laufzeit am Anfang die Bilder
zeichnest, und im Speicher behälst, aber die Performance auch so reicht
denke ich sollte das für dich OK sein...
In solchen Dingen hilft oft nur experimentieren, und ich bin der Meinung
es läuft genug schnell;-)
mfg Andreas
Andreas B. schrieb:> xpler schrieb:>> Öhh Moment, du nutzt ja das PNG gar nicht sondern hast das wieder auf>> Text umgestrickt. Warum? Geht es mit dem PNG nicht?>> weil so das Problem mit der Skalierung weg ist.
Stimmt natürlich, aber irgendwie wüsste ich schon gerne wie es mit dem
PNG geht. Zumal dein Quellcode zwar prima funktioniert aber eine zu
kleine Fläche (ich brauche 80x50 Zeichen) erzeugt und ich gerade nicht
so durchblicke was ich da ändern müsste.
Ich hab mich mal bei der Cairo Mailinglist angemeldet und werde mal
meine drei Englischkentnisse zusammenfegen um nach dem PNG-scale-Problem
zu fragen. Ich berichte dann hier wenn es was neues gibt.
Danke für die Hilfe!
Es geht, ich habe nur den Fehler in deinem Code nicht gesehen.
Als Referenz kann ich sonst meine Applikation noch angeben.
http://xournal.svn.sourceforge.net/viewvc/xournal/trunk/xournalpp/
Hier wird zwar ein PDF gerendert, aber ob das von einem PDF oder von
einem PNG geladen wurde ist beim Skalieren egal, da schlussendlich
beides beim Anzeigen nur noch ein Cairo image sourface ist.
mfg Andreas
>Ich hab mich mal bei der Cairo Mailinglist angemeldet
Ich habe zwar keine Ahnung um was es eigentlich geht, verstehe die
Bildchen nicht, und kann auch nichts probieren, da ich kein Windows
verwende...
Aber nach
>As long as i not use cairo_scale() or use>only integer values for scaling this works great
würde ich Integer/Float Rechenprobleme vermuten, etwa bei
int x1,x2,y1,y2;
int x,y;
x1=event->area.x/SZ_PIC_X/zoomX;
cairo_rectangle(cr,x*SZ_PIC_X,y*SZ_PIC_Y,SZ_PIC_X*zoomX,SZ_PIC_Y*zoomY);
Erst Teilen durch zoomX, dann wieder multiplizieren, mit Integer
Beteiligung -- da muss man aufpassen.
Und grundsätzlich braucht man bei Cairo ja oft gar nicht so viel
Rechnungen, durch scale() und translate() lässt sich ja viel direkt
erschlagen, siehe etwa die Beispiele
http://cairographics.org/threaded_animation_with_cairo/
Cairo sieht schon ganz nett aus, aber man muss sich schon überlegen was
man wie tut, sonst wird es etwas langsam, wie derzeit bei meiner
Spielerei
http://www.ssalewski.de/PetEd.html.en
Salewski, Stefan schrieb:>>Ich hab mich mal bei der Cairo Mailinglist angemeldet>> Ich habe zwar keine Ahnung um was es eigentlich geht, verstehe die> Bildchen nicht, und kann auch nichts probieren, da ich kein Windows> verwende...
Da du aufgrund deiner Homepage Ahnung davon hast noch ein Tipp;-)
gcc -Wall -g main.c -o main `pkg-config --cflags --libs gtk+-2.0` &&
./main
Zumindest meine Version kompiliert so ohne Probleme unter Ubuntu...
>> Aber nach>>>As long as i not use cairo_scale() or use>>only integer values for scaling this works great>> würde ich Integer/Float Rechenprobleme vermuten, etwa bei
Wird auch so etwas gewesen sein, aber ich habs nicht gesehen...
> Erst Teilen durch zoomX, dann wieder multiplizieren, mit Integer> Beteiligung -- da muss man aufpassen.>> Und grundsätzlich braucht man bei Cairo ja oft gar nicht so viel> Rechnungen, durch scale() und translate() lässt sich ja viel direkt> erschlagen, siehe etwa die Beispiele
Ich habs jetzt absichtlich OHNE scale gemacht, da beim redraw die
Faktoren auch eingerechnet werden müssen, und das ist dann wieder eine
Potenzielle Fehlerquelle...
>> http://cairographics.org/threaded_animation_with_cairo/>> Cairo sieht schon ganz nett aus, aber man muss sich schon überlegen was> man wie tut, sonst wird es etwas langsam, wie derzeit bei meiner> Spielerei> http://www.ssalewski.de/PetEd.html.en
Sieht gut aus;-)
Wobei da sollte es eigentlich noch kein Problem sein, ich habs
unterdessen geschafft bei 300 PDF Seiten noch eine brauchbare
Scrollgeschwindigkeit zu erreichen;-)
Einfach in Images rendern und dann die Images auf den Bildschirm
zeichnen, dann geht es relativ schnell...
http://xournal.svn.sourceforge.net/viewvc/xournal/trunk/xournalpp/
ps. nicht lauffähig unter Windows;-)
mfg Andreas
Hi!
Bin über deinen Post auf der mailing list hier drauf gestoßen.
Zu der Sache mit dem png: du könntest doch beim Start stattdessen ein
cairo_surface_t* array erstellen, in welches du alle Buchstaben
reinrenderst und dann müsstest du beim Neuzeichnen immer jeweils nur die
entsprechende surface malen. Dann hättest du dir die png gespart und den
selben Effekt erreicht.
Und generell: cairo_scale manipuliert in erster Linie die
Transformationsmatrix, sprich es wirkt sich auf alles aus, was irgendwie
mit Koordinaten zutun hat. Was es nicht beeinflusst, ist das Skalieren
von Bildern bzw. surfaces. (Hoffe ich sag jetzt nichts was schon gesagt
wurde..)
Ich hab mal bei der neusten Version hier (von Andreas) in process_keys()
am Anfang
1
intoldX=Px,
2
oldY=Py;
und vor dem setChar am Ende
1
setChar(oldX,oldY,' ');
eingefügt, damit das x nicht so ne Spur von sich hinterlässt..
Andreas B. schrieb:> Es geht, ich habe nur den Fehler in deinem Code nicht gesehen.
Ok, kein Problem.
> Als Referenz kann ich sonst meine Applikation noch angeben.> http://xournal.svn.sourceforge.net/viewvc/xournal/trunk/xournalpp/
Wow, so gut möchte ich auch programmieren können!
Salewski, Stefan schrieb:> Erst Teilen durch zoomX, dann wieder multiplizieren, mit Integer> Beteiligung -- da muss man aufpassen.
Da hast du wohl Recht, allerdings kann ich einfach keinen Fehler finden.
Das ganze ist vermutlich sowieso suboptimal, aber auf eine
Division/Multiplikation kommt es beim PC nicht an...
> http://www.ssalewski.de/PetEd.html.en
Nett.
Jonas K. schrieb:> Hi!> Bin über deinen Post auf der mailing list hier drauf gestoßen.
Herzlich Willkommen. Wenigstens war also mein Post erfolgreich, hab
bisher nie zuvor eine Mailinglist benutzt...
> Zu der Sache mit dem png: du könntest doch beim Start stattdessen ein> cairo_surface_t* array erstellen, in welches du alle Buchstaben> reinrenderst und dann müsstest du beim Neuzeichnen immer jeweils nur die> entsprechende surface malen. Dann hättest du dir die png gespart und den> selben Effekt erreicht.
Puh, mal gucken ob ich das in Code umgesetzt bekomme. Du meinst also
sowas wie
?
> Und generell: cairo_scale manipuliert in erster Linie die> Transformationsmatrix, sprich es wirkt sich auf alles aus, was irgendwie> mit Koordinaten zutun hat. Was es nicht beeinflusst, ist das Skalieren> von Bildern bzw. surfaces.
Das heißt es gibt für Bilder noch eine andere scale-Funktion?
> Zu der Sache mit dem png: du könntest doch beim Start stattdessen ein> cairo_surface_t* array erstellen, in welches du alle Buchstaben> reinrenderst und dann müsstest du beim Neuzeichnen immer jeweils nur die> entsprechende surface malen. Dann hättest du dir die png gespart und den> selben Effekt erreicht.
Hab ich ausprobiert (Code auf Wunsch), bringt leider nix, Zoomproblem
bleibt. Ach Mensch dass das so kompliziert sein muss. Ich warte auf
Antworten in der Mailinglist, mal schauen.
xpler schrieb:>> Hi!>> Bin über deinen Post auf der mailing list hier drauf gestoßen.> Herzlich Willkommen. Wenigstens war also mein Post erfolgreich, hab> bisher nie zuvor eine Mailinglist benutzt...>
Kann dich verstehen (; Bin bei meinem ersten Post auf einer direkt
gebannt worden, hab seit dem glaub ich nie wieder auf eine geschrieben..
>> Zu der Sache mit dem png: du könntest doch beim Start stattdessen ein>> cairo_surface_t* array erstellen, in welches du alle Buchstaben>> reinrenderst und dann müsstest du beim Neuzeichnen immer jeweils nur die>> entsprechende surface malen. Dann hättest du dir die png gespart und den>> selben Effekt erreicht.> Puh, mal gucken ob ich das in Code umgesetzt bekomme. Du meinst also> sowas wiecairo_surface_t pattern[256];> foreach pattern do> zeichne einen(!) Buchstaben vom png nach pattern[buchstabe];>> ...>> redraw: kopierere pattern[buchstabe] nach cr;> ?
So ähnlich. Meine Idee war: zeichne in jede surface einen char mit
'cairo_show_text()'.
Mir fällt aber gerade auf dass du ja genau die DOS Font haben wolltest,
von daher vergiss bitte wieder, was ich da gesagt habe (; Die png Lösung
ist da wohl doch am angebrachtesten.
>> Und generell: cairo_scale manipuliert in erster Linie die>> Transformationsmatrix, sprich es wirkt sich auf alles aus, was irgendwie>> mit Koordinaten zutun hat. Was es nicht beeinflusst, ist das Skalieren>> von Bildern bzw. surfaces.> Das heißt es gibt für Bilder noch eine andere scale-Funktion?
Ahh sry hab da was verwechselt. Tut mir Leid, vergiss das auch bitte
wieder..
Andreas B. (andreasb) schrieb:
>gcc -Wall -g main.c -o main `pkg-config --cflags --libs gtk+-2.0` &&
./main
>Zumindest meine Version kompiliert so ohne Probleme unter Ubuntu...
Ja, Deine Version sicher, aber die funktioniert ja wohl eh.
Seine Version, auf die er sich auf der Cairo Mailing-Liste bezieht,
nutzt aber Windows-Funktionen, dass kann ich so nicht kompilieren.
Was mir eben beim Durchscrollen ins Auge fiel, bei seiner Version:
>gtk_widget_queue_draw_area(window,x*SZ_PIC_X*zoomX, y*SZ_PIC_Y*zoomY, >SZ_PIC_X*zoomX, SZ_PIC_Y*zoomY);
Ich kann mir kaum vorstellen, dass da Double als Parameter akzeptiert
wird (durch zoomX), dass ist ja nicht Cairo, sondern GTK, sollte also
Int sein.
Ist wohl auch so
http://developer.gnome.org/gtk/2.24/GtkWidget.html#gtk-widget-queue-draw-area
Aber unter C geht wohl fast aller Blödsinn.
Autor: Jonas K. (jonas_k56)
>Und generell: cairo_scale manipuliert in erster Linie die>Transformationsmatrix, sprich es wirkt sich auf alles aus, was irgendwie>mit Koordinaten zutun hat. Was es nicht beeinflusst, ist das Skalieren>von Bildern bzw. surfaces. (Hoffe ich sag jetzt nichts was schon gesagt>wurde..)
Nein, die Transformationen können durchaus auf Bilder, Patterns usw.
angewendet werden -- meist sieht das aber nicht gut aus, weil man dann
eine bereits gerasterte Grafik skaliert. Wobei, ich habe das noch nicht
gemacht, aber soweit ich die Doku richtig verstanden habe...
>> bisher nie zuvor eine Mailinglist benutzt...>>>Kann dich verstehen (; Bin bei meinem ersten Post auf einer direkt>gebannt worden, hab seit dem glaub ich nie wieder auf eine geschrieben..
Komisch, die Listen, die ich kenne dulden auch Dummschwätzer, nur wird
dann eben meist nicht geantwortet.
>Ist wohl auch so>http://developer.gnome.org/gtk/2.24/GtkWidget.html...>Aber unter C geht wohl fast aller Blödsinn.
Ist wohl aber auch nicht das Problem und auch kein wirklicher Blödsinn,
bei Zuweisung von float/double an int wird wohl automatisch konvertiert,
wie ich eben ausprobiert habe. Wusste ich nicht, ich kannte für C nur
die erlaubte Zuweisung von int an float und habe sonst wenn nötig stets
explizite Typumwandlung genutzt.
>Also in X-Richtung funktioniert es prima, aber sobald zoomY einen>anderen Wert als 1 hat kommt nur noch Käse raus.
Da wohl auf der Cairo-Liste keiner geantwortet hat, habe ich doch noch
mal einen kurzen Blick in diesen Thread geworfen. Wobei es für mich
schon etwas verwirrend ist, erst geht es um zu langsam, dann um scale()
mit double, dann wieder um...
Und Andreas hat ja schon versuch Dir gut zu helfen -- wenn Du wirklich
Interesse hättest würdest Du dich systematisch selber etwas bemühen.
Wenn es letztlich nur Probleme mit double für zoomY gibt, könnte man ja
mal an einigen Stellen 1.01 und anderswo 1 verwenden, um die kritische
Stelle zu finden. Aber was mir einfiel nach Deiner obigen Aussage: Du
weist schon, wie das bei Cairo mit dem Koordinatennullpunkt ist? Der ist
vorgabemäßig unter links! Und sonst: Eines Deiner Bildchen PNG war ja
extrem lang in X-Richtung, könnte die Länge das Problem sein?
Jetzt aber Schluss.
Salewski, Stefan schrieb:> Wobei es für mich> schon etwas verwirrend ist, erst geht es um zu langsam, dann um scale()> mit double, dann wieder um...
Ja, langsam wird es unübersichtlich. Also mal kurz von vorne: Zuerst
hatte ich das Problem das mein Code (noch ohne scale) viel zu langsam
war. Das Geschwindigkeitsproblem habe ich dann mit der png-Methode
gelöst was auch prinzipiell funktioniert hat (noch immer ohne scale).
Dann wollte ich das ganze noch über den ganzen Monitor strecken, habe
scale eingebaut und festgestellt dass es damit nicht richtig
funktioniert. Das ist auch das aktuelle Problem weswegen ich die
Mailinglist angeschrieben habe. Soweit alles klar?
> Und Andreas hat ja schon versuch Dir gut zu helfen -- wenn Du wirklich> Interesse hättest würdest Du dich systematisch selber etwas bemühen.
Ich habe Interesse und habe schon viel alleine gesucht und probiert
(systematisch und unsystematisch), das Problem bleibt aber. Für die
Hilfe von Andreas habe ich mich (mehrfach) bedankt.
> Wenn es letztlich nur Probleme mit double für zoomY gibt, könnte man ja> mal an einigen Stellen 1.01 und anderswo 1 verwenden, um die kritische> Stelle zu finden.
Die kritische Stelle ist der scale-Aufruf, sobald dort eine
Gleitkommazahl für ZoomY eingesetzt wird kommt nur noch Käse raus.
> Aber was mir einfiel nach Deiner obigen Aussage: Du> weist schon, wie das bei Cairo mit dem Koordinatennullpunkt ist? Der ist> vorgabemäßig unter links!
Äh... nicht eher oben links? Das passt eher zu dem was ich beobachtet
habe.
> Und sonst: Eines Deiner Bildchen PNG war ja> extrem lang in X-Richtung, könnte die Länge das Problem sein?
Es gibt nur ein Bild, das ist in der Tat extrem lang. Wenn ich es
testweise verkürze bleibt das Problem mit scale.
Die Konvertierungsissues auf die du mich in der Mailinglist hingewiesen
hast habe ich testweise korrigiert (auf int gecastet), bringt leider
nichts.
xpler schrieb:> sobald dort eine Gleitkommazahl für ZoomY> eingesetzt wird kommt nur noch Käse raus
Auch wenn du es bisher geflissentlich überlesen hast: Man kann nicht ein
Bild ohne Verluste/Artefakte auf beliebige Faktoren skalieren!
Wieso machst du nicht erst mal eine Konsole die einen "fixen" Font hat
(von miraus mit 2 oder 3 möglichen Auflösungen)?
Wenn du wirklich beliebige Zoomfaktoren haben willst (was spätestens
dann schwer wird wenn du eigentlich einen 80x40 Konsole erwartest und
das Bild 500x20 Pixel hat) musst du (wie vorgeschlagen) einen passenden
Font wählen und bei jeder Größenänderung dein Alphabet neu aufbauen.
xpler schrieb:> Hilfe von Andreas habe ich mich (mehrfach) bedankt.
Schon OK, wenn mich die Leute nerven oder so ist ziemlich schnell die
Mailbenachrichtigung abgeschaltet;-)
>> Aber was mir einfiel nach Deiner obigen Aussage: Du>> weist schon, wie das bei Cairo mit dem Koordinatennullpunkt ist? Der ist>> vorgabemäßig unter links!> Äh... nicht eher oben links? Das passt eher zu dem was ich beobachtet> habe.
Naja, beide haben recht, und das verursacht ggf. etwas Verwirrung.
Auf dem Bildschirm / Bild wird tatsächlich von oben links her gezählt.
Beim Text wird von unten links her gezählt, also der Text wird
oberhalb der Koordinate gezeichnet.
Ich verweise hiermit mal auf
http://zetcode.com/tutorials/cairographicstutorial/cairotext/
Hier ein Beispiel zu cairo_text_extents_t.
Das ganze ist am Anfang ziemlich unübersichtlich, aber ist bei Java oder
auch anderen Libraries oft ähnlich...
(Bei genauer Betrachtung macht es im übrigen auch Sinn!)
>> Und sonst: Eines Deiner Bildchen PNG war ja>> extrem lang in X-Richtung, könnte die Länge das Problem sein?
Ich schliesse das aus, da ich selbst für Xournal++ bei 400 fachem Zoom
und 300 DPI bilder mit ca. 3'500px Breite durchaus noch darstellen kann,
und im übrigen auch Skalieren=)
> Die Konvertierungsissues auf die du mich in der Mailinglist hingewiesen> hast habe ich testweise korrigiert (auf int gecastet), bringt leider> nichts.
@xpler
Nim den Code der läuft, und leg de alten einfach weg.
Theoretisch funktioniert das ganze mit dem PNG. Der Fehler liegt mit
Sicherheit in deinem Code.
Da aber weder ich noch Stefan und wer auch immer noch in den Code
geschaut hat den Fehler auch nicht sehen ist er wohl sehr gut getarnt...
Wenn du jetzt etwas Erfahrung sammelst mit GTK oder so, dann kannst du
in einem halben Jahr noch mal einen Blick auf deinen Code werfen, wenn
du etwas Abstand hast, und nicht mehr so genau weisst wie das ganze
funktioniert, dann nochmals genauer hinschaust siehst du plötzlich was
bis jetzt verborgen blieb;-)
mfg Andreas
>Äh... nicht eher oben links? Das passt eher zu dem was ich beobachtet>habe.
Ja, da habe ich mich mal wieder vertan, ich hatte bei meiner Anwendung
ganz zu Anfang
cr.translate(0, @darea.allocation.height)
cr.scale(1, -1)
um den Ursprung von links oben nach links unten zu setzen.
>Die kritische Stelle ist der scale-Aufruf, sobald dort eine>Gleitkommazahl für ZoomY eingesetzt wird kommt nur noch Käse raus.
Da müsste man ein Minimalbeispiel machen und dann auf der Mailingliste
fragen. Je überschaubarer es ist, um so eher bekommt man Antwort, oder
man sieht das Problem sogar selbst. (Das Beispiel sollte auf Linux
lauffähig sein, denn die Meisten Entwickler haben eher Linux.) Zu PNG
scaling gibt es ein Beispiel
http://www.cairographics.org/samples/clip_image/
damit könntest du etwas experimentieren.
Aber wie gesagt, Skalierung einer Rastergrafik ist von der Qualität nie
gut. Du könntest das PNG-Bild auch einfach mit Gimp skalieren, wenn Du
nur eine feste größere Größe willst. Oder Du könntest dann mehrere
PNG-Bildchen nehmen, oder verschiedene Font-Größen in einem PNG.
Und hier noch das von Andreas erwähnte Beispiel von Zetcode
http://zetcode.com/tutorials/cairographicstutorial/cairoimages/
um scale() erweitert und mit deinem Bildchen getestet.
Unter Linux funktioniert alles, vielleicht ist das ja auch ein
Windows-Problem?
So, nach weiterem Debuggen: Der Fehler liegt irgendwo zwischen
gtk_widget_queue_draw_area() und dem event dazu. Ich habe mal den ganzen
PNG-Krempel durch
ersetzt, ZoomX=1, ZoomY=1.01, Bild siehe Anhang. Irgendwie scheinen sich
da die Koordinaten zu verschieben, wenn ich statt
gtk_widget_queue_draw_area() gtk_widget_queue_draw() (ohne Area!) nehme
passt alles.
ABER: Ich kann verstehen wenn die Helfer langsam genug haben und mir
stinkt es auch gewaltig nicht weiterzukommen. Ich hasse es zwar wenn ich
etwas nicht gelöst kriege und bin auch eigentlich ziemlich ausdauernd,
aber das hier hat ja keinen Sinn mehr. Deshalb mache ich jetzt wie von
Läubi vorgeschlagen einen fixen Font für 1024x768 oä und schalte dann
einfach mittels WinAPI die Auflösung um, halt so wie es jedes normale
Spiel macht. Auf die Idee hätte ich vor zig Wochen auch schon kommen
können... Ich will grundsätzlich bei der PNG-Methode bleiben um den
vollen DOS-Zeichensatz nutzen zu können.
Nochmals Danke für die Hilfe!
over and out...