@database "Entwickler.dok" @master "Entwickler.dok" @node MAIN "Entwickler.dok" @{b}MaxonCINEMA 4D Developing Package MaxonCINEMA 4D@{ub}®@{b} Professional V3.0@{ub} Datum : 5.11.1995 (c) Copyright 1989-1995 MAXON Computer GmbH, @{"Einleitung" link Einleitung} @{"Dateiformat" link Dateiformat} Programmieren von Erweiterungen @{"C-Includes " link C-Includes} @{"Modula-Includes" link Modula-Includes} @{"Anmerkungen " link Anmerkungen} @{"Erweiterungen " link Erweiterungen} Bildschirmtreiber - C4D.library @{"Autodocs " link c4d.doc} @{"FD " link c4d.fd} @{"Includes " link c4d.h} @{"Pragmas " link c4d_pragmas} @{"Protos " link c4d_protos} @{"Änderungen 3.0 " link c4dchanges} @endnode @node "Einleitung" Um auf die Daten von MaxonCINEMA4D zuzugreifen gibt es mehrere Möglichkeiten: Zuerst einmal können Sie abgespeicherte Szenendateien laden und modifizieren. Zusätzlich können Sie über Erweiterungen (Extensions) direkt während dem Programmablauf eingreifen und beliebige Daten verändern. Auch hier ist die Schnittstelle in der Datei 'Entwickler.dok' beschrieben. Auch wenn diese Datei sehr umfangreich ist, können einfache Erweiterungen in sehr kurzer Zeit entwickelt werden, zumal schon ein paar Beispiele mitgeliefert werden. Da es leider noch kein RTG gibt, muß jeder seine eigene Grafikschnittstelle definieren. MaxonCINEMA4D greift dabei auf die c4d.library zu. Jede Grafikkarte kann unterstützt werden, wenn eine c4d.library nach den hier definierten Richtlinien programmiert wird. @endnode @node "Anmerkungen" Das Koordinatensystem von MaxonCINEMA4D ist so definiert, daß X- und Y- Achse in der Monitorebene liegen und die Z-Achse dazu senkrecht nach hinten zeigt. MaxonCINEMA4D verwendet bei Dateien zur Speicherung von Koordinaten ausschließlich FFP-Variablen, wodurch die Kompatibilität des Dateiformats zur 68881-er Version, die intern mit LONGREAL-Variablen arbeitet, gewährleistet ist. MaxonCINEMA4D-Erweiterungen dagegen müssen wie das Hauptprogramm in zwei Versionen vorliegen: eine 68000-er und eine 68881-er Version. Bei der Erstellung von eigenen Programmen ist unbedingt darauf zu achten, daß alle Spezifikationen, die in dieser Dokumentation angegeben sind, erfüllt werden. Ist dies nicht der Fall, kann es zu unerwarteten Effekten oder sogar Systemabstürzen führen. Der Datentyp 'Vektor' wird als Vektor, Punkt und Farbe eingesetzt. Wird er als Farbe verwendet, entspricht die x-Komponente dem Rotanteil, die y-Komponente dem Grünanteil und die z-Komponente dem Blauanteil. Jede Komponente muß größer oder gleich null und kleiner gleich eins sein. Wird 'Vektor' als Punkt verwendet, so sollten die einzelnen Komponenten zwischen -MAXREAL und +MAXREAL liegen. Dies gilt nicht nur für Punkte, sondern auch für Abstände, Radien usw.. 'String' ist die Zeichenkette für den Objektnamen. Jedes Polygon muß ein 'PolyInfo' haben. Dort sind nur die Werte 'art' und 'geschlossen' von Bedeutung, alles Andere wird vom Programm verwaltet. Das 'Tag' ist eine in MaxonCINEMA 4D ausgiebig verwendete Datenstruktur. Im Objekt gibt es die Struktur 'tag', die auf eine linear verkettete Liste von Tags zeigt. Die Art eines Tags ist in der 'Tag'-Struktur durch den 'typ' festgelegt. In 'len' steht die Länge der Tag-Daten, in 'data' die Adresse der Daten. 'next' zeigt auf das nächste Tag bzw. NIL. 'len' kann auch 0 sein, zum Beispiel beim Tag 'Tphong'. Das Tag 'Tphong' ist ein sogenanntes Boolean-Tag. Ist es vorhanden, dann ist das Phong-Shading aktiviert. Ist es nicht da, dann wird ein Objekt ohne Phongshading gerendert. Nun zur wichtigen 'Objekt'-Struktur: 'typ' spezifiert den Objekttyp. 'Kamera', 'Boden' und 'Himmel' dürfen NIE gelöscht oder erzeugt werden; das ist dem Programm vorbehalten. Alle anderen Objekte dürfen erzeugt, manipuliert, gelöscht und neu verkettet werden. 'next' zeigt auf das nächste Objekt auf gleicher Hierarchieebene, 'down' auf das untergeordnete Objekt. In 'darst' steht, wie das Objekt im Editor gezeichet wird. 'anim' zeigt auf die Animationsadresse, die nur vom Programm gesetzt bzw. verändert werden darf. Bei neuerzeugten Objekten muß immer NIL eingetragen werden. 'mpos' gibt den Objektursprung an, 'mskal' die Achsenlängen und 'mrot' die Schwenk-, Neig- und Kipp-Winkel (x,y,z). Die Winkel sind im Bogenmaß angegeben. Aus 'mskal' und 'mrot' gewinnt man folgendermaßen die Objektachsen: PROCEDURE Objektachsen(op:ObjektPtr; VAR vx,vy,vz:Vektor); VAR cn,sn,ck,sk,cs,ss : FLOAT; BEGIN ss:=Sin(op^.mrot.x); sn:=Sin(op^.mrot.y); sk:=Sin(op^.mrot.z); cs:=Cos(op^.mrot.x); cn:=Cos(op^.mrot.y); ck:=Cos(op^.mrot.z); vx.x:=op^.mskal.x*(ck*cs-sk*sn*ss); vx.y:=op^.mskal.x*(-sk*cn); vx.z:=op^.mskal.x*(ck*ss+sk*sn*cs); vy.x:=op^.mskal.y*(sk*cs+ck*sn*ss); vy.y:=op^.mskal.y*(ck*cn); vy.z:=op^.mskal.y*(sk*ss-ck*sn*cs); vz.x:=op^.mskal.z*(-cn*ss); vz.y:=op^.mskal.z*(sn); vz.z:=op^.mskal.z*(cn*cs); END Objektachsen; 'mittelpunkt' und 'radius' geben eine zum Objektkoordinatensystem parallele Bounding-Box vor, die das Objekt umhüllt. 'mittelpunkt' wird in Weltkoordinaten angegeben. 'radius' gibt mit seinen drei Komponenten die "Radien" der Bounding-Box in Richtung der drei Objektkoordinatensystemvektoren vx,vy und vz vor. Beim Objekttyp 'Kugel' legt 'mittelpunkt' den Kugelmittelpunkt fest und 'radius' den Kugelradius. Bei Kugeln muß der Radius immer für alle drei Komponenten gleich sein. Nun die einzelnen Tags: Tfileend : Gibt beim Laden/Speichern an, daß das Ende der Tag-Liste vorhanden ist. Im Hauptspeicher existiert kein derartiges Tag Tpunkte : Zeigt auf die Punkte eines Objekts. Die Punkte sind vom Typ Vektor. In der Coprozessor-Version haben sie eine Größe von 24 Bytes, ansonsten 12 Tdreiecke : Zeigt auf die Dreiecke eines Objekts. Ein Dreieck ist eine Folge von drei CARDINAL-Werten. Jeweils ein CARDINAL-Wert steht für einen Punkt (beginnend mit 0) Tvierecke : Zeigt auf die Vierecke eines Objekts. Ein Viereck ist eine Folge von vier CARDINAL-Werten. Jeweils ein CARDINAL-Wert steht für einen Punkt (beginnend mit 0) Tkanten : Zeigt auf die Kanten eines Objekts. Eine Kante ist eine Folge von zwei CARDINAL-Werten. Jeweils ein CARDINAL-Wert steht für einen Punkt (beginnend mit 0) Es ist umbedingt wichtig, daß die Kanten korrekt angelegt werden, daß heißt jede Kante darf nur einmal vorkommen. Außerdem muß jede Kante eines Vierecks bzw. Dreiecks vorhanden sein. WICHTIG: Bei den Kanten muß der erste Punktwert immer der kleinere sein. D.h. bei einer Kante darf nicht 5/2 eingetragen werden, sondern es muß 2/5 darin stehen Tpolyinfo : Zeigt auf die PolyInfo-Struktur. Die PolyInfo-Struktur wird von MaxonCINEMA 4D freigegeben, daher muß sie bei Benutzung alloziiert werden Tphong : Boolean-Tag mit 'len'=0. Ist nur vorhanden, wenn Phong für ein Objekt berechnet werden soll @endnode @node Modula-Includes CONST MAXPOLYPNTS = 2500; (* Maximale Anzahl von Polygonpunkten *) MAXELEMENTS = MAX(CARDINAL)-15; (* Maximale Anzahl an Dreiecken, Vierecken, Punkten und Kanten *) MAXREAL = 10000000.0; (* Maximaler Wertebereich für Punkte, Vektoren... *) TYPE (*$ IF m68881 *) FLOAT = LONGREAL; (*$ ELSE *) FLOAT = FFP; (*$ ENDIF *) STRUKTUR = SET OF (next_o,down_o); Darst = (Dvoll,Dleicht,Dmittel,Dstark,Dquader,Dkeine); Vektor = RECORD x,y,z : FLOAT; END; String = ARRAY [0..15] OF CHAR; PolyTyp = (Linear,Kubisch,Akima,BSpline); PolyInfoPtr = POINTER TO PolyInfo; PolyInfo = RECORD art : PolyTyp; geschlossen : BOOLEAN; reserved1 : SHORTINT; reserved2 : ARRAY [0..3] OF ADDRESS; END; ObjektTyp = (Kugel,Flaechen,Licht,Polygon,Kamera,Himmel,Boden); TagTyp = (Tfileend, Tpunkte, Tdreiecke, Tvierecke, Tkanten, Tpolyinfo, Tintern0, Tintern1, Tintern2, Tphong, Tintern3); TagPtr = POINTER TO Tag; Tag = RECORD empty : BOOLEAN; typ : TagTyp; len : LONGINT; data : ADDRESS; next : TagPtr; END; ObjektPtr = POINTER TO Objekt; Objekt = RECORD typ : ObjektTyp; name : String; next, down : ObjektPtr; darst : Darst; anim : ADDRESS; mpos,mskal,mrot, mittelpunkt,radius : Vektor; tag : TagPtr; END; @endnode @node "C-Includes" /* * Header-Datei für Maxon Cinema 4D v2.0 * * Portierung von Modula 2 nach C von Jan-Claas Dirks * * Der Compiler muß auf das Mathematikmodell * entweder auf FFP oder 68881 gestellt werden, * beim SAS/C also Math=ffp oder Math=881. */ #include #include #include #include #define MAXPOLYPNTS 2500 /* Maximale Anzahl von Polygonpunkten */ #define MAXELEMENTS (USHRT_MAX-15) /* Maximale Anzahl an Dreiecken, Vierecken, Punkten und Kanten */ #define MAXREAL 10000000.0 /* Maximaler Wertebereich für Punkte, Vektoren... */ enum Darst { Dvoll, Dleicht, Dmittel, Dstark, Dquader, Dkeine }; enum PolyTyp { Linear, Kubisch, Akima, BSpline }; enum ObjektTyp { Kugel, Flaechen, Licht, Polygon, Kamera, Himmel, Boden }; enum TagTyp { Tfileend, Tpunkte, Tdreiecke, Tvierecke, Tkanten, Tpolyinfo, Tintern0, Tintern1, Tintern2, Tphong, Tintern3 }; typedef char String[16]; typedef struct { double x, y, z; } Vektor; typedef struct sPolyInfo PolyInfo; typedef PolyInfo *PolyInfoPtr; struct sPolyInfo { BYTE PolyTyp; /* aus PolyTyp */ BYTE geschlossen; /* Boolscher Wert */ short reserved1; APTR reserved2[4]; }; typedef struct sTag TAG; typedef TAG *TagPtr; struct sTag { BYTE empty; /* Boolscher Wert */ BYTE typ; /* aus TagTyp */ long len; APTR data; TagPtr next; }; typedef struct sObjekt Objekt; typedef Objekt *ObjektPtr; struct sObjekt { BYTE typ; /* aus ObjektTyp */ BYTE pad1; String name; ObjektPtr next, down; BYTE darst; /* aus Darst */ APTR anim; Vektor mpos, mskal, mrot, mittelpunkt, radius; TagPtr tag; }; typedef struct { struct WBStartup wb; /* read-only! */ struct Screen sp; /* read-only! */ ObjektPtr nextobjekt; ObjektPtr aktuobjekt; /* read-only! */ BYTE requester, undo; /* read-only! Boolsche Werte */ Vektor center; /* read-only! */ BYTE refresh; /* Boolscher Wert */ BYTE pad1; ObjektPtr neuesobjekt; ObjektPtr verwirbeln; ObjektPtr matrizenanpassen; ObjektPtr rethinkpolygon; APTR reserved[25]; /* read-only! */ } NEWSTARTUPMSG; @endnode @node "Dateiformat" Das Dateiformat von MaxonCINEMA4D ist ein IFF-Format. Die FORM-ID heißt 'MC4D'. Der 'OBJS'-Chunk enthält die Objekte. Da Objekte Unterobjekte enthalten können, ist der 'OBJS'-Chunk rekursiv verschachtelt. Nach dem Aufruf von LadeObjekt muß abgetestet werden, ob die Chunklänge ungerade war. In diesem Fall muß noch ein Dummy-Byte gelesen werden. PROCEDURE LadeObjekt():ObjektPtr; VAR s : STRUKTUR; typ : TagTyp; long,len : LONGINT; BEGIN s:=STRUKTUR{next_o}; WHILE (next_o IN s) DO Lese op^.typ (1 Byte) Lese op^.darst (1 Bytes) Lese op^.name (16 Bytes) Lese op^.mpos (12 Bytes) Lese op^.mskal (12 Bytes) Lese op^.mrot (12 Bytes) Lese op^.mittelpunkt (12 Bytes) Lese op^.radius (12 Bytes) Lese struktur (1 Byte) REPEAT Lese long (4 Bytes) typ:=SHIFT(long,-24); len:=long MOD (2^24); IF typ#Tfileend THEN CASE typ OF | Tpunkte : Lese punkte (len Bytes) | Tkanten : Lese kanten (len Bytes) | Tdreiecke : Lese dreiecke (len Bytes) | Tvierecke : Lese vierecke (len Bytes) | Tphong : Lese keine weiteren Bytes (Boolean-Tag!) | Tpolyinfo : Lese 'art' (1 Byte) und 'geschlossen' (1 Byte) (len Bytes) ELSE Überlese len Bytes END; END; UNTIL typ=Tend; IF (down_o IN s) AND mem AND weiter THEN op^.down:=LadeObjekt(); ELSE op^.down:=NIL; END; END; Gebe das zuerst gelesene Objekt dieser Hierarchieebene zurück END LadeObjekt; @endnode @node "Erweiterungen" Jede Erweiterung ist ein selbstständiges Programm. Sind die Erweiterungen in den Ordner "Erweiterungen" des Cinema-Hauptverzeichnisses gelegt, dann werden sie automatisch erkannt und in das Extension-Popup-Menü aufgenommen. Erweiterungen für die 68881-er Version müssen die Endung .881 haben, Erweiterungen für die 68000-er und 68020-er Version sollten keine Endung haben. Bitte beachten Sie, daß wenn Sie eine Erweiterung für die 68881-er Version von Cinema 4D programmieren, überall LONGREAL-Werte anstelle von FFP-Werten verwenden müssen! Erweiterungen werden von MaxonCINEMA4D aus aufgestartet. Sie bekommen eine WBStartup-Message übergeben (siehe AMIGA ROM Kernel Manuals). Nach den Daten der Startup-Message folgen spezifische Daten, die MaxonCINEMA4D der aufgestarteten Erweiterung zur Verfügung stellt. Diese Daten können von der Erweiterung geändert werden. Bei Programmstart muß abgetestet werden, daß die übergebene Message genau so groß wie definiert ist, um Abstürze zu verhindern, falls die Erweiterung von der Workbench oder einem anderen Programm aufgestartet wird. Die erweiterte Startup-Message sieht folgendermaßend aus: TYPE NEWSTARTUPMSG = RECORD wb : WBStartup; (READ-ONLY!) sp : ScreenPtr; (READ-ONLY!) nextobjekt : ObjektPtr; aktuobjekt : ObjektPtr; (READ-ONLY!) requester,undo : BOOLEAN; (READ-ONLY!) center : Vektor; (READ-ONLY!) refresh : BOOLEAN; neuesobjekt : ObjektPtr; verwirbeln : ObjektPtr; matrizenanpassen : ObjektPtr; rethinkpolygon : ObjektPtr; reserved : ARRAY [0..24] OF ADDRESS; (READ-ONLY!) END; 'sp' ist der ScreenPtr des Cinema-Bildschirms. Es kann sich dabei z.B. um den WB-Screen handeln. 'nextobjekt' ist ein Zeiger auf das ersten Objekt auf höchster Hierarchie- Ebene. Die Elemente der 'nextobjekt'-Liste sind nie vom Typ 'Kamera', 'Boden' oder 'Himmel. 'aktuobjekt' ist ein Zeiger auf das aktive Objekt. Das Aktuobjekt kann vom Typ 'Kamera', 'Boden' und 'Himmel' sein und ist in diesen Fällen nicht in die Objekthierarchie eingebunden. 'requester' gibt an, ob des Menü mit Shift angewählt wurde. Falls eine Erweiterung irgendwelche Eingabeparameter benötigt, dann sollte das MaxonCINEMA4D-Konzept beibehalten werden: Aufruf ohne Shift-->kein Requester, Aufruf mit Shift-->Requester. 'undo' sollte von der Erweiterung auf TRUE gesetzt werden, wenn eine Aktion rückgängig machbar ist. Nur dann kann der Benutzer den Menüpunkt Rückgängig anwählen. Nur Aktionen, die das aktiven Objekt verändern dürfen das 'undo'-Flag setzen. In 'center' steht der Mittelpunkt, in dem neue Objekte erzeugt werden sollten. Mit 'refresh' teilen Sie MaxonCINEMA4D mit, was nach der Beendigung der Erweiterung passieren soll. Standardmäßig steht der Wert auf FALSE, so daß gar nichts passiert. Wird 'refresh' auf TRUE gesetzt, dann wird die Szene komplett neu aufgebaut. Wird in 'neuesobjekt' ein Objekt eingetragen, dann wird dieses Objekt aktiviert ('refresh' muß nicht gesetzt werden). Soll ein Objekt verwirbelt werden, dann tragen Sie das Objekt unter 'verwirbeln' ein. Wenn Ihre Erweiterung die Punkte eines Objekts verändert hat, dann müssen die Werte 'mittelpunkt' und 'radius' neu angepaßt werden. Tragen Sie dazu das entsprechende Objekt in 'matrizenanpassen' ein. Bei veränderten oder neuen Polygonen müssen programmintern einige Koeffizienten angepaßt werden. Dies kann nur das Hauptprogramm erledigen. Tragen Sie dazu das Polygon in 'rethinkpolygon' ein. Es gibt einige Dinge, die Sie keinesfalls tun dürfen: 1.) Objekte löschen 2.) Die Punktadresse oder -anzahl eines nichtlinearen Polygons ändern. Neue Polygone dürfen aber beliebig erzeugt werden 3.) Irgendwelche Speicherbereiche freigeben, ohne den neuen Speicher erhalten zu haben. Wenn Sie beispielsweise das Punktfeld eines Objekts vergrößern wollen, müssen Sie zuerst den neuen Speicher alloziieren und dürfen erst dann den alten Speicherbereich freigeben. Ansonsten kann es passieren, daß nicht genügend Speicher für den neuen Speicherbereich zur Verfügung steht und der alte schon freigegeben wurde. 4.) READ-ONLY-Werte verändern @endnode @node c4d.doc TABLE OF CONTENTS c4d.library/C4D_CloseDisplay c4d.library/C4D_DisplayToBack c4d.library/C4D_DisplayToFront c4d.library/C4D_GetDisplayInfo c4d.library/C4D_GetEvent c4d.library/C4D_GetSignalNum c4d.library/C4D_NextDisplayInfo c4d.library/C4D_OpenDisplay c4d.library/C4D_Refresh c4d.library/C4D_CloseDisplay c4d.library/C4D_CloseDisplay NAME C4D_CloseDisplay -- Bildschirm der angesprochenen Grafikkarte schließen SYNOPSIS C4D_CloseDisplay(dp) A0 void C4D_CloseDisplay(void*) FUNCTION C4D_CloseDisplay schließt das zuvor mit C4D_OpenDisplay geöffnete Display. INPUTS dp - Zeiger auf Display, zurückgegebener Wert von der Funktion C4D_OpenDisplay SEE ALSO C4D_OpenDisplay c4d.library/C4D_DisplayToBack c4d.library/C4D_DisplayToBack NAME C4D_DisplayToBack -- Bildschirm in den Hintergrund bringen SYNOPSIS C4D_DisplayToBack(dp) A0 void C4D_DisplayToBack(void *) FUNCTION C4D_DisplayToBack bringt den in 'dp' angegebenen Bildschirm nach vorne. INPUTS dp - Zeiger auf Display, zurückgegebener Wert von der Funktion C4D_OpenDisplay SEE ALSO C4D_DisplayToFront c4d.library/C4D_DisplayToFront c4d.library/C4D_DisplayToFront NAME C4D_DisplayToFront -- Bildschirm in den Vordergrund bringen SYNOPSIS C4D_DisplayToFront(dp) A0 void C4D_DisplayToFront(void *) FUNCTION C4D_DisplayToFront bringt den in 'dp' angegebenen Bildschirm nach hinten. INPUTS dp - Zeiger auf Display, zurückgegebener Wert von der Funktion C4D_OpenDisplay SEE ALSO C4D_DisplayToBack c4d.library/C4D_GetDisplayInfo c4d.library/C4D_GetDisplayInfo NAME C4D_GetDisplayInfo -- Informationen über einen Bildschirmmodus auslesen. SYNOPSIS ok = C4D_GetDisplayInfo(id,max,idinfo); D0 D0 D1 A0 BOOL C4D_GetDisplayInfo(ULONG,BOOL,IDInfo*); FUNCTION Diese Funktion liest Informationen über den Bildschirmmodus der Nummer 'id' aus. Diese Nummer wurde zuvor mit C4D_NextDisplayInfo ermittelt. Wurde der Bildschirmmodus zwischenzeitlich entfernt, gibt die Funktion 0 zurück. 'max' gibt an, ob in IDInfo die maximalen oder die standardmäßigen Werte eingetragen werden sollen. Außerdem wird in 'idinfo' der Name des Bildschirmmodus und die Farbtiefe eingetragen. INPUTS id - eine Nummer, die mit C4D_NextDisplayInfo ermittelt wurde max - gibt an, ob in 'idinfo' die maximale Auflösung eingetragen werden soll RESULT idinfo - ein Zeiger auf eine IDInfo-Struktur, in die die Werte eingetragen werden EXCEPTIONS D0 steht auf 0, falls der Bildschirmmodus mit der Nummer 'id' nicht vorhanden war SEE ALSO C4D_NextDisplayInfo c4d.library/C4D_GetEvent c4d.library/C4D_GetEvent NAME C4D_GetEvent -- Abfragen, ob eine Benutzeraktion anliegt SYNOPSIS event = C4D_GetEvent(dp); D0 A0 LONG C4D_GetEvent(void*); FUNCTION Diese Funktion gibt zurück, was der Benutzer für eine Aktion gestartet hat. Grafikkartentreiber, die solche Möglichkeiten nicht bieten, geben hier immer 'EV_Keiner' zurück. Es können folgende Werte zurückgegeben werden: EV_Keiner : keine Aktion EV_Abbruch : Berechnungsabbruch (Taste "Esc") EV_Bild : Bildschirmwechsel (Taste "b","B" oder Mausklick mit der linken Taste) EV_Save : Speichern (Taste "s" oder "S") Bitte keine anderen Tastatur/Mausbelegungen verwenden als vorgegeben! INPUTS dp - Zeiger auf Display, zurückgegebener Wert von der Funktion C4D_OpenDisplay RESULT event - Nummer der Benutzeraktion c4d.library/C4D_GetSignalNum c4d.library/C4D_GetSignalNum NAME C4D_GetSignalNum -- Abfragen der Signalnummer des Ausgabefensters SYNOPSIS num = C4D_GetSignalNum(dp); D0 A0 LONG C4D_GetSignalNum(void*); FUNCTION Diese Funktion gibt die Signalnummer des Message-Ports des Ausgabefensters zurück, auf die Cinema 4D warten soll. Existiert kein Ausgabefenster, so wird -1 zurückgegeben. INPUTS dp - Zeiger auf Display, zurückgegebener Wert von der Funktion C4D_OpenDisplay RESULT num - Signalnummer EXCEPTIONS D0 steht auf -1, falls es kein Ausgabefenster gibt c4d.library/C4D_NextDisplayInfo c4d.library/C4D_NextDisplayInfo NAME C4D_NextDisplayInfo -- Nächste Bilschirmmodus-ID auslesen SYNOPSIS result = C4D_NextDisplayInfo(id) D0 D0 ULONG C4D_NextDisplayInfo(ULONG); FUNCTION C4D_NextDisplayInfo ermittelt die nächste Bildschirmmodus-ID. Gibt es keine nächste ID, dann wird INVALID_ID zurückgegeben. INPUTS id - letzte mit NextDisplay ausgelesene Nummer oder anfangs Null RESULT result - ID des nächsten Bildschirmmodus c4d.library/C4D_OpenDisplay c4d.library/C4D_OpenDisplay NAME C4D_OpenDisplay - Einen neuen Bildschirm auf der unterstützten Grafikkarte öffnen SYNOPSIS dp = C4D_OpenDisplay(buffer,xauf,yauf,id,hidden) D0 A0 D0 D1 D2 D3 void *C4D_OpenDisplay(void*,LONG,LONG,ULONG,BOOL); FUNCTION Diese Funktion öffnet auf der Grafikkarte ein Display mit mindestens der in 'xauf' und 'yauf' angegebenen Auflösung. (Achtung: die Auflösungen können unter der Mindestgröße des Screens liegen!) Die ID des Bildschirmmodus ist in 'id' angegeben. 'hidden' gibt an, ob der Bildschirm im Hintergrund geöffnet werden soll. 'buffer' ist die Adresse des internen C4D-24Bit-Buffers. Der Buffer ist (xauf+3)/4*4*yauf Pixel zu je 3 Bytes groß (Anordnung: RGB). Ein Zeilenanfang liegt somit bei buffer + (xauf+3)/4*4*3 * yauf ^- bpz = Bytes per Zeile Cinema zeichnet direkt in diesen Buffer. Die Treiber sollten so programmiert werden, daß sie *KEINEN* eigenen 24-Bit-Speicher anfordern, sondern den Cinema-Buffer verwenden - auch wenn das Grafikkarten-Pixelformat anders als RGBRGBRGB... aussehen sollte. Nur so kann gewährleistet werden, daß für den eigenlichen Raytracingvorgang auf durchschnittlich ausgerüsteten Maschinen noch genügend Speicher frei ist (640*480*24 Bit benötigen ca. 1,5 MB!!) INPUTS buffer - Adresse des Cinema 24Bit-Bildpuffers xauf - X-Auflösung yauf - Y-Auflösung id - Bildschirm-ID hidden - Gibt an, ob das Display im Hintergrund geöffnet werden soll RESULTS D0 ist 0, wenn das Display nicht geöffnet werden konnte. c4d.library/C4D_Refresh c4d.library/C4D_Refresh NAME C4D_Refresh - Eine Zeile auf dem Bildschirm setzen SYNOPSIS C4D_Refresh(dp, ystart, yend); A0 D0 D1 C4D_Refresh(DisplayHandle*,LONG,LONG); FUNCTION Diese Funktion löst einen C4D_Refresh der Grafikdaten aus. Es müssen die Zeilen ystart bis yend neu dargestellt werden. Die Breite der Zeilen wurde bei 'C4D_OpenDisplay' übergeben. Die Daten für den C4D_Refresh stehen in 'buffer' (ebenfalls von 'C4D_OpenDisplay'). C4D_Refresh wird nach jeder berechnetet Bildzeile und einmal am Anfang der Bildberechnung (nachdem der Buffer auf Schwarz gesetzt wurde) aufgerufen. INPUTS dp - DisplayHandle des Bildschirms ystart - Anfangszeile yend - Endzeile @endnode @node "c4d.h" #ifndef PROTO_C4D_H #define PROTO_C4D_H #include extern struct Library *C4DBase; #include "c4d_protos.h" #include "c4d_pragmas.h" #endif @endnode @node "c4d.fd" ##base _C4DBase ##bias 30 ##public C4D_CloseDisplay(a0) C4D_DisplayToBack(a0) C4D_DisplayToFront(a0) C4D_GetDisplayInfo(d0/d1,a0) C4D_GetEvent(a0) C4D_GetSignalNum(a0) C4D_NextDisplayInfo(d0) C4D_OpenDisplay(a0,d0/d1/d2/d3) C4D_Refresh(a0,d0/d1) ##end @endnode @node "c4d_pragmas" #pragma libcall C4DBase C4D_CloseDisplay 1e 801 #pragma libcall C4DBase C4D_DisplayToBack 24 801 #pragma libcall C4DBase C4D_DisplayToFront 2a 801 #pragma libcall C4DBase C4D_GetDisplayInfo 30 81003 #pragma libcall C4DBase C4D_GetEvent 36 801 #pragma libcall C4DBase C4D_GetSignalNum 3c 801 #pragma libcall C4DBase C4D_NextDisplayInfo 42 001 #pragma libcall C4DBase C4D_OpenDisplay 48 3210805 #pragma libcall C4DBase C4D_Refresh 4e 10803 @endnode @node "c4d_protos" #ifndef C4D_PROTOS_H #define C4D_PROTOS_H /* ** $VER: c4d.h 3.00 (19.9.95) ** ** c4d.library: Strukturen und Konstanten ** ** (C) Copyright 1989-1995 MAXON Computer GmbH */ #ifndef EXEC_TYPES_H #include #endif #define NO_SIGNAL -1 // Events #define EV_Keiner 0 #define EV_Abbruch 1 #define EV_Bild 2 #define EV_Save 3 typedef struct { WORD xauf; WORD yauf; WORD tiefe; BYTE name[34]; } IDInfo; void C4D_CloseDisplay(void *dp); void C4D_DisplayToBack(void *dp); void C4D_DisplayToFront(void *dp); long C4D_GetDisplayInfo(unsigned long id, long max, IDInfo *info); long C4D_GetEvent(void *dp); long C4D_GetSignalNum(void *dp); unsigned long C4D_NextDisplayInfo(unsigned long id); void *C4D_OpenDisplay(void *buffer, long xauf, long yauf, unsigned long id, long hidden); void C4D_Refresh(void *dp, long ystart, long yend); #endif /* C4D_PROTOS_H */ @endnode @node "c4dchanges" Änderungen der c4d.library (Version 3 und höher) zur cinemaausgabe.library (Versionen 1 und 2) Wenn Sie schon für die Version 1 oder 2 von Cinema4D eine Cinemaausgabe-Library geschrieben haben, ergeben sich einige wichtige Änderungen, die allerdings innerhalb kürzester Zeit durchführbar sein sollten: - Es fallen viele (unter anderem alle komplexen) Routinen weg - Der Treiber SOLLTE KEINEN EIGENEN 24-BIT-SPEICHER ANLEGEN, dafür bekommt er Zugriff auf den Cinema-internen Speicher - Sämtliche Übergaberegister haben sich geändert (teilweise auch die Reihenfolge der Parameter) - Das Eventhandling sollte den Standardvorgaben entsprechen (siehe Funktion GetEvent) - Die neue Library heißt "c4d.library" - Die bei GetDisplayInfo zurückgelieferten DisplayMode-Namen sollten die Farbtiefe enthalten (z.B. Picasso 800x600x24) @endnode