amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > CGX-Anfänger problem [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

25.06.2003, 19:36 Uhr

ZeroG
Posts: 1487
Nutzer
Hallo, ich habe gerade angefangen ein wenig mit CGX-herumzuprobieren und dabei (wie sollte es auch anders sein) auf ein Problem gestossen:
Ich möchte einen Farbverlauf in ein Fenster zeichnen aber das Fenster bleibt komplett grau. Warum?

Ich verwende StormC4.


#include <stdlib.h> /*Für exit()*/
#include <stdio.h> /*Für printf()*/
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <cybergraphx/cybergraphics.h>
#include <clib/cybergraphics_protos.h>

#define Fenster_Links (20)
#define Fenster_Oben (10)
#define Fenster_Breite (300)
#define Fenster_Hoehe (110)
#define IMAGE_BPP (3)

void main(void);
void Fensterbehandeln(struct Window*);
void CreateImageData(UBYTE*,ULONG,ULONG);
void RedrawWindow(struct Window*,UBYTE*);

struct IntuitionBase *IntuitionBase=0;
struct CyberGfxBase *CyberGfxBase=0;
struct TagItem Fenster_tags[]=
{
{WA_Left,Fenster_Links},
{WA_Top,Fenster_Oben},
{WA_InnerWidth,Fenster_Breite},
{WA_InnerHeight,Fenster_Hoehe},
{WA_DragBar, TRUE},
{WA_CloseGadget, TRUE},
{WA_SimpleRefresh,TRUE},
{WA_IDCMP,IDCMP_CLOSEWINDOW},
{TAG_DONE,NULL},
};


void main()
{

UBYTE *ImageData;
struct Window *Fenster=0;
CyberGfxBase=(struct CyberGfxBase*)OpenLibrary("cgxsystem.library",41L);
if (CyberGfxBase)
{
IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",39L);
if (IntuitionBase)
{
Fenster=OpenWindowTagList(NULL,Fenster_tags);
if (Fenster)
{
if ((ImageData=AllocVec(Fenster_Breite*Fenster_Hoehe*IMAGE_BPP,MEMF_PUBLI C))==NULL)
{
CloseWindow(Fenster);
CloseLibrary((struct Library*)IntuitionBase);
CloseLibrary((struct Library*)CyberGfxBase);
printf("Test:n");
printf("Kein Speicher für Bitmap!n");
}
CreateImageData (ImageData,Fenster_Breite,Fenster_Hoehe);
BeginRefresh (Fenster);
RedrawWindow(Fenster,ImageData);
EndRefresh (Fenster,TRUE);
Fensterbehandeln(Fenster);
FreeVec (ImageData);
CloseWindow(Fenster);
CloseLibrary((struct Library*)IntuitionBase);
CloseLibrary((struct Library*)CyberGfxBase);
}
else
{
CloseLibrary((struct Library*)IntuitionBase);
CloseLibrary((struct Library*)CyberGfxBase);
printf("Test:n");
printf("Kann Fenster nicht öffnen!n");
exit(20);
}
}
else
{
CloseLibrary((struct Library*)CyberGfxBase);
printf("Test:n");
printf("Kann Intuition.library Version 37 oder höher nicht öffnen!n");
exit(20);
}
}
else
{
printf("Test:");
printf("Kann cgxsystem.library Version 41 oder höher nicht öffnen!n");
}
}

void Fensterbehandeln(struct Window *fen)
{
WaitPort(fen->UserPort);
}

void CreateImageData(UBYTE *Image,ULONG Width,ULONG Height)
{
ULONG X,Y;

for (Y=0; Y<Height; Y++)
for (X=0; X<Width; X++)
{
*Image++=(UBYTE)X; /* Red */
*Image++=(UBYTE)Y; /* Green */
*Image++=0; /* Blue */
}
}

void RedrawWindow(struct Window *Fens,UBYTE *ID)
{
(void)WritePixelArray(ID,0,0,
Fenster_Breite*IMAGE_BPP,
Fens->RPort,
Fens->BorderLeft,Fens->BorderTop,
Fenster_Breite,
Fenster_Hoehe,
RECTFMT_RGB);
}

[ - Antworten - Zitieren - Direktlink - ]

26.06.2003, 19:36 Uhr

Georg
Posts: 107
Nutzer
Lösch' das BeginRefresh()/EndRefresh() raus. Diese
Funktionen benutzt man wenn ein simple refresh Fenster
eine IDCMP_REFRESHWINDOW Msg bekommt, was bedeutet
daß die app das Fenster neu zeichnen soll, weil durch
eine Window-Operation (Fenster verschieben, usw.)
Inhalte davon "zerstört" wurden. Das BeginRefresh()/EndRefresh()
sorgt dann dafür, daß das Neuzeichnen auf jene Bereiche
geclippt/begrenzt wird, die "zerstört" wurden.




[ - Antworten - Zitieren - Direktlink - ]

26.06.2003, 21:13 Uhr

thomas
Posts: 7717
Nutzer

Überleg dir mal, ob du CGX wirklich brauchst. Ein einfaches Farbmuster bekommt man auch hin, wenn man sich einen Pen allokiert und dann vor jedem Draw() die Farbe ändert.

Ein Beispiel findest du hier: http://home.t-online.de/home/thomas-rapp/download/truecolors.lha


Um so weniger AmigaOS-fremde Funktionen du benutzt, um so kompatibler ist das Programm mit anderen Amigas. Und es ist dann einfacher, es auf eventuelle neue AmigaOS-Versionen umzusetzen (ggf. braucht man gar nichts zu ändern).

Außerdem solltest du vorher prüfen, ob du dich wirklich auf einem High- oder Truecolor-Bildschirm (also Depth >= 16) befindest. Sonst machen die 24bit-Funktionen nämlich wirklich nicht mehr als den Bildschirm löschen.

Und du solltest nach dem WaitPort() auch noch die Messages vom Port abholen. Die werden durch CloseWindow() zwar auch freigegeben, aber das ist unsauber.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

28.06.2003, 23:16 Uhr

Holger
Posts: 8116
Nutzer
Laß Dir keinen Unsinn erzählen. Daß auf einem Truecolor-System daß Zeichnen mit einem Pen, dessen Farbe man beständig ändert, Farbverläufe erzeugen kann, ist ein Seiteneffekt, den man nicht ausnutzen sollte.
Außerdem funktioniert das nur, wenn es sich tatsächlich um einen Truecolor-Bildschirm handelt, und das kann man derzeit ohnehin nur mittels CGX- oder P96-Aufrufen feststellen. Außerdem ist das Zeichnen von Farbverläufen mittels einzelner Draw-Aufrufe die ineffizienteste Variante, die man sich vorstellen kann.
Dein Ansatz ist schon richtig.
Probier das ohne BeginRefresh(...) + EndRefresh (...) und laß den Rest so.

mfg


--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

03.07.2003, 18:02 Uhr

ZeroG
Posts: 1487
Nutzer
Puh, endlich mal wieder Zeit...
Ok, ersteinmal danke an alle die geantwortet haben.

@Georg: OK, ich werde ich mal ausprobieren. Wenn ich dann später z.B. einen anderen Farbverlauf oder ein anderes Bild zeichnen möchte, muß ich das aber innerhalb von BeginRefresh() und EndRefresh() machen, richtig?

@Holger: Ja, diese Idee mit dem einzelnen Pen kommt mir auch SEHR merkwürdig vor...

@thomas: - die Idee mit einem Pen: siehe @Holger

- prüfen ob der Screen wirklich 24Bit hat: Da meine WB mit 24Bit läuft, hab ich zum rumprobieren diese kleine Überprüfung weggelassen - soll später aber noch ins Programm...

- Ups, die Messages hatte ich ganz vergessen:glow: Danke, kommt nicht wieder vor...schäm...

- Wieso OS-Fremde-Funktionenen??? Wenn ich mich nicht ganz täusche ist seit OS3.5 P96 Teil vom OS, P96 wird in OS4 auch benutzt und letzten Endes ist P96 doch CGX kompatible? Oder nicht?

[ - Antworten - Zitieren - Direktlink - ]

03.07.2003, 18:24 Uhr

thomas
Posts: 7717
Nutzer
Zitat:
Original von ZeroG:
@thomas: - die Idee mit einem Pen: siehe @Holger


Du solltest dir eine eigene Meinung bilden. Je nach Zweck ist das eine oder das andere sinnvoll. Das Programm von fremden Libraries abhängig zu machen, nur weil es einfacher ist, ist schlechter Stil.

Zitat:
- Wieso OS-Fremde-Funktionenen??? Wenn ich mich nicht ganz täusche ist seit OS3.5 P96 Teil vom OS, P96 wird in OS4 auch benutzt und letzten Endes ist P96 doch CGX kompatible? Oder nicht?

P96 und CGX sind nach wie vor kommerzielle Produkte, die nicht zum AmigaOS gehören. P96 hat eine CGX-Emulation, die aber an einigen Stellen nicht ganz kompatibel ist. Und wer keine Grafikkarte hat, kann mit dem Programm dann nichts mehr anfangen, denn er hat weder CGX noch P96 installiert.

Was mit OS4 ist, muß sich erst noch herausstellen. Sicher wird ein Programm, das P96 oder CGX benutzt, darauf laufen. Aber ein Programm, das ohne P96 oder CGX auskommt hat den größten Benutzerkreis, denn es läuft auf Classic-Amigas ab OS3.0, auf OS4.0 und auf MorphOS.

Am besten fährst du, wenn du das Programm von der Bildschirmtiefe unabhängig machst. D.h. z.B. Grafiken mit der datatyes.library laden und automatisch auf die Bildschirmtiefe rastern lassen. Dann mit BltBitMap oder so in das Fenster bringen. Das funktioniert auf jedem Screen und nutzt ggf. 24bit aus, ohne es im Programm besonders berücksichtigen zu müssen.

Kommt natürlich auch auf den Zweck des Programms an und ob Geschwindigkeit eine Rolle spielt.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

04.07.2003, 14:31 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von ZeroG:
Wenn ich dann später z.B. einen anderen Farbverlauf oder ein anderes Bild zeichnen möchte, muß ich das aber innerhalb von BeginRefresh() und EndRefresh() machen, richtig?

Nein, Du benutzt diese Funktionen, wenn das Betriebssystem Dir eine Message schickt, die Dir mitteilt, daß Du das Fenster neu zeichnen sollst. Und in diesem Fall solltest Du auch genau das zeichnen, was Du vorher in dem Fenster gezeichnet hattest. Sonst passend die Teile, die in dem Bereich sind, der vorher verdeckt gewesen war, nicht zu dem Rest der Grafik.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

08.07.2003, 16:25 Uhr

Tessien
Posts: 55
Nutzer
Bin grade reingestolpert, will nur kurz eine Bemerkung machen:

Versuche, dieses ganze PEN-Elend soweit wie möglich zu vermeiden. Nur weil es noch im System drin ist, heißt es nicht, daß es gut ist. Ich hoffe, daß neuere OS-Versionen davon abkommen. CGfx-Funktionen dagegen kannst Du als gegeben annehmen, wenn Du sowieso auf Hi- oder TrueColour-Screens arbeitest. Picasso emuliert CGfx intern, also so lange Du Dich nur an CGfx-Funktionen hälst, läuft es auf allen Systemen mit Grafikkarten. Problematisch wird es höchstens, wenn Du tatsächlich noch die AGA-only-Nutzer mit ansprechen willst. Davon gibt es noch einige, und manche davon haben erstaunlich unverschämte Ansprüche an Programmierer und ihre antiqirierte Technik.

Sorry, wenn das frustriert klingt. Schlechte Erfahrungen mit CrossfireII-Kunden...

Bye, Thomas
--
Thomas Schulze - programmer at Dreamworlds Development - http://www.dreamworlds.de

[ - Antworten - Zitieren - Direktlink - ]

08.07.2003, 17:40 Uhr

ZeroG
Posts: 1487
Nutzer
Hi Leute,
ich finde es doch ganz interressant wie leicht man hier eine mittelschwere Grundsatzdiskussion vom Zaun brechen kann;) ;) .

Ich habe letzte Woche mal die beiden Zeilen mit Begin- und EndRefresh gelöscht - UND - das Fenster ist immernoch grau...:dance3:
Hat noch jemand einen Vorschlag was nun Falsch läuft?

@Holger: Danke...Bevor ich das ausprobiere möchte ich aber ersteinmal überhabt etwas zeichnen:) :( .

[ - Antworten - Zitieren - Direktlink - ]

08.07.2003, 21:13 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von ZeroG:
Ich habe letzte Woche mal die beiden Zeilen mit Begin- und EndRefresh gelöscht - UND - das Fenster ist immernoch grau...:dance3:
@Holger: Danke...Bevor ich das ausprobiere möchte ich aber ersteinmal überhabt etwas zeichnen:) :( .

Na ja, ich habe leider kein entsprechendes System mehr, um das zu testen. Kann nur sagen, daß Fenster-öffen, auf-Meldung-warten, zeichnen-bei-Aufforderung die übliche Reihenfolge sind. Ich weiß nicht, wie weit die asynchrone Behandlung bei intuition tatsächlich ist, aber u.U. ist das Fenster noch gar nicht offen, wenn Du direkt nach dem Aufruf von OpenWindow hineinzeichnest.
Setze doch in die Zeichenroutine ein paar konventionelle Zeichenaufrufe (originale graphics-lib), um den Fehler einzugrenzen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

09.07.2003, 00:08 Uhr

Holger
Posts: 8116
Nutzer
So, vergiß mein letztes Posting,
nimm dieses:

Habe mir jetzt in mühevoller Kleinarbeit ein cgx-system inkl. devel-files für cgx zusammengestrickt (was tut man nicht alles :rotate: ) und getestet.

Um den eigentlich ziemlich simplen Fehler zu finden:

Du öffnest die cgxsystem.library, die eigentlich nicht von Anwendungen benutzt werden soll. Die richtige Bibliothek heißt cybergraphics.library. Eigentlich hätte Dir das ganze System um die Ohren fliegen müssen, hast Du Glück gehabt, oder auch nicht, denn vielleicht hättest Du dann den Fehler schneller gefunden.

Wenn Du das korrigierst, sollte es laufen.

Der Vollständigkeit halber hier nochmal das ganze etwas übersichtlicher und inklusive des Refresh-Handlings.
Die include-Anweisungen müssen evtl. etwas angepaßt werden, hatte sie für meine gcc-Installation geändert.

code:
#include <stdio.h> /*Für printf()*/
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <intuition/intuition.h>
#include <cybergraphics/cybergraphics.h>
#include <clib/cybergraphics_protos.h>
#include <inline/cybergraphics.h>

#define Fenster_Links (20)
#define Fenster_Oben (10)
#define Fenster_Breite (300)
#define Fenster_Hoehe (110)
#define IMAGE_BPP (3)

int init(void);
void cleanup(void);
int main(void);
void Fensterbehandeln(struct Window*);
void CreateImageData(UBYTE*,ULONG,ULONG);
void RedrawWindow(struct Window*,UBYTE*);

struct IntuitionBase *IntuitionBase=0;
struct CyberGfxBase *CyberGfxBase=0;
UBYTE *ImageData=0;
struct Window *Fenster=0;
struct TagItem Fenster_tags[]=
{
  {WA_Left,Fenster_Links},
  {WA_Top,Fenster_Oben},
  {WA_InnerWidth,Fenster_Breite},
  {WA_InnerHeight,Fenster_Hoehe},
  {WA_DragBar, TRUE},
  {WA_CloseGadget, TRUE},
  {WA_SimpleRefresh,TRUE},
  {WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW},
  {TAG_DONE,NULL},
};

int init(void)
{
  ImageData=AllocVec(Fenster_Breite*Fenster_Hoehe*IMAGE_BPP,MEMF_PUBLIC) ;
  if(!ImageData) return 10;
  CyberGfxBase=(struct CyberGfxBase*)OpenLibrary("cybergraphics.library",41L);
  if(!CyberGfxBase) return 10;
  IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",39L);
  if(!IntuitionBase) return 10;
  Fenster=OpenWindowTagList(NULL,Fenster_tags);
  return 0;
}

void cleanup(void)
{
  if(ImageData) FreeVec(ImageData);
  else printf("Test:nKein Speicher für Bitmap!n");
  if(Fenster) CloseWindow(Fenster);
  else if(IntuitionBase) printf("Test:nKann Fenster nicht öffnen!n");
  if(CyberGfxBase) CloseLibrary((struct Library*)CyberGfxBase);
  else printf("Test:nKann cgxsystem.library Version 41 oder höher nicht öffnen!n");
  if(IntuitionBase) CloseLibrary((struct Library*)IntuitionBase);
  else printf("Test:nKann Intuition.library Version 37 oder höher nicht öffnen!n");
}

int main(void)
{
  int error;

  error=init();

  if(!error)
  {
    CreateImageData (ImageData,Fenster_Breite,Fenster_Hoehe);
    RedrawWindow(Fenster, ImageData);
    Fensterbehandeln(Fenster);
  }

  cleanup();
  return error;
}

void Fensterbehandeln(struct Window *fen)
{
  int quit;
  for(quit=0; !quit; )
  {
    struct IntuiMessage *msg;
    WaitPort(fen->UserPort);
    msg=(struct IntuiMessage *)GetMsg(fen->UserPort);
    switch(msg->Class)
    {
      case IDCMP_CLOSEWINDOW:
        quit=1;
        break;
      case IDCMP_REFRESHWINDOW:
        BeginRefresh(Fenster);
        RedrawWindow(Fenster, ImageData);
        EndRefresh(Fenster, TRUE);
        break;
    }
    ReplyMsg(&msg->ExecMessage);
  }
}

void CreateImageData(UBYTE *Image,ULONG Width,ULONG Height)
{
  ULONG X,Y;

  for (Y=0; Y<Height; Y++)
    for (X=0; X<Width; X++)
    {
      *Image++=(UBYTE)X; /* Red */
      *Image++=(UBYTE)Y; /* Green */
      *Image++=0; /* Blue */
    }
}

void RedrawWindow(struct Window *Fens,UBYTE *ID)
{
  (void)WritePixelArray(ID,0,0,
            Fenster_Breite*IMAGE_BPP,
            Fens->RPort,
            Fens->BorderLeft,Fens->BorderTop,
            Fenster_Breite,
            Fenster_Hoehe,
            RECTFMT_RGB);
}


Zu beachten: es fehlt immer noch der Test, ob es sich tatsächlich um einen cgx-screen handelt, aber für die ersten Versuche geht's erst mal.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

09.07.2003, 18:33 Uhr

Holger
Posts: 8116
Nutzer
Kleine Korrektur.

In die init()-Funktion muß natürlich noch ein if(!Fenster) return 10; vor dem return 0; eingefügt werden.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

10.07.2003, 18:25 Uhr

ZeroG
Posts: 1487
Nutzer
Vielen danke Holger!
Werde ich am Wochenende mal ausprobieren und mich dann hier melden ob es geklappt hat oder nicht.

[ - Antworten - Zitieren - Direktlink - ]

15.07.2003, 17:35 Uhr

ZeroG
Posts: 1487
Nutzer
Hat geklappt, vielen Dank!:)

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > CGX-Anfänger problem [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.