 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Felix
Anmeldungsdatum: 22.01.2008 Beiträge: 41 Wohnort: Breisach
|
Verfasst am: 30.04.2008, 20:23 Titel: Shared lybraries und Screenres |
|
|
Hallöle zusammen,
hab n Problem... Ich versuche gerade, in einer Shared Lybrarie in einem Sub was zu zeichnen und wenn ich dann das Programm ausführe dann zeigts mir nur schwarzen screen an... Hier mal die lybrarie:
Code: |
Public Sub zeichneSpielfeld() export
Dim i As Integer
Dim laengs As Integer
Dim hoehe As Integer
Line(600,0)-(601,600),,b
hoehe = 39
laengs = 39
For i = 0 To 15
Line(laengs,hoehe)-(laengs+102,hoehe+102),,b
laengs = laengs + 140
If i Mod 4 = 3 Then
laengs = 39
hoehe = hoehe + 140
EndIf
Next
End Sub
|
und hier die Test-BAS-Datei
Code: |
'Kontrollprogramm
#include once "bib.bi"
ScreenRes 800,600,16
Dim Shared i As Integer
zeichneSpielfeld()
GetKey |
Kann mir jemand sagen wieso des net funktioniert??
Gruß Felix _________________ Mein Anti-High-End-PC: Pentium 4 1,7Ghz, 512Mbyte DDR, Radeon 9250 128Mbyte DDR-2,
50 Gbyte Seagate HDD, ...  |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 30.04.2008, 23:26 Titel: |
|
|
bib.bi Code: | 'bib.bi
Declare Sub zeichneSpielfeld Lib "bib" Alias "zeichneSpielfeld" () |
bib.bas -> mit 'fbc -lib bib.bas' zu libbib.a kompilieren Code: | 'bib.bas -> 'fbc -lib bib.bas'
#Include "bib.bi"
PUBLIC SUB zeichneSpielfeld() EXPORT
DIM i AS INTEGER
DIM laengs AS INTEGER
DIM hoehe AS INTEGER
LINE(600,0)-(601,600),,b
hoehe = 39
laengs = 39
FOR i = 0 TO 15
LINE(laengs,hoehe)-(laengs+102,hoehe+102),,b
laengs = laengs + 140
IF i MOD 4 = 3 THEN
laengs = 39
hoehe = hoehe + 140
ENDIF
NEXT
END SUB |
Dann dein Kontrollprogramm (-s gui) ausführen! _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Felix
Anmeldungsdatum: 22.01.2008 Beiträge: 41 Wohnort: Breisach
|
Verfasst am: 02.05.2008, 13:29 Titel: |
|
|
Erstmal danke für diene ANtwort,
aber irgendwie funktioniert die Sache doch nicht, ich schreib jetzt nochmal auf dwie ichs genau gemacht habe.... Es funktioniert ja bei allen Funktionen und Subs nur eben nicht beim ZEichnen...
Erstmal habe ich die .bas Datei die ich in .dll kompiliert habe
Code: |
Public Sub zeichneSpielfeld() Export
Line(600,0)-(601,600),,b
End Sub
|
Dann habe ich die Sub in der Headerdatei (.bi) deklariert.
Code: |
#inclib "mylib"
declare Sub zeichneSpielfeld()
|
Und dann eben noch das Kontrollprogramm
Code: |
'Kontrollprogramm
#include once "bib.bi"
ScreenRes 800,600,16
zeichneSpielfeld()
GetKey
|
Wie gesagt nach dem Prinzip funktionieren die Funktionen in denen halt nichts gezeichnet wird.
Sry aber wahrscheinlich bin ich einfach nur zu blöd um deine Anleitung zu verstehn volta  _________________ Mein Anti-High-End-PC: Pentium 4 1,7Ghz, 512Mbyte DDR, Radeon 9250 128Mbyte DDR-2,
50 Gbyte Seagate HDD, ...  |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 02.05.2008, 21:36 Titel: |
|
|
Gugst du unten? _________________ Bis irgendwann... 
Zuletzt bearbeitet von AndT am 02.05.2008, 22:47, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 02.05.2008, 22:00 Titel: |
|
|
Hi,
jetzt wird es etwas kompliziert:
1. In einer statischen Lib kannst du die fbgfx-Anweisungen (Screen, Line etc) benutzen. Sie funktionieren auch nachher in der EXE.
2. In einer dynamischen Lib (dll) kannst du sie auch benutzen, sie kennen aber den Screen den du in deiner EXE bildest nicht. Dll und EXE bilden jede für sich eine eigene Instanz (~Fenster).
Der Vorschlag oben war für eine statische Lib ( fbc -lib bib.bas ) und funktioniert gut.
Der Fehler bei dir:
Auch in der BAS - Datei, die du zu einer Lib kompilierst, muss am Anfang die Sub deklariert werden (siehe oben bib.bas #Include "bib.bi").
In der Deklaration muss der Name der Lib und der Alias angegeben werden (Declare Sub zeichneSpielfeld Lib "bib" Alias "zeichneSpielfeld" () )
Aber auch mit diesen Änderungen funktioniert es in einer DLL nicht, nur in einer statischen Lib. _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 02.05.2008, 22:05 Titel: |
|
|
Eine Lösung:
Die ist Dll für die Grafikausgabe und das Programm gibt der DLL die Befehle
Lib (bib.bas) mit folgenden Code erstellen (-dll):
Code: | declare function ZeichneSpielfeld lib "bib" alias "zeichneSpielfeld" as integer
declare function OpenScreen lib "bib" alias "OpenScreen" as integer
declare function PrintToScreen lib "bib" alias "PrinttoScreen" (byval Text as String) as integer
declare function Check lib "bib" alias "Check" as integer
dim shared checksum as integer 'Eine Prüfsumme um Fehler zu erkennen
function OpenScreen as integer EXPORT
SCREENRES 800,600,16
checksum + = 1
function = 1
end function
function zeichneSpielfeld as integer EXPORT
LINE(600,0)-(601,600),,b
checksum + = 1
function = 1
END function
function PrintToScreen (byval Text as String) as integer EXPORT
Print TEXT
checksum + = 1
function = 1
end function
function Check as integer Export
function = Checksum
end function
|
Programm:
Code: | declare function ZeichneSpielfeld lib "bib" alias "zeichneSpielfeld" as integer
declare function OpenScreen lib "bib" alias "OpenScreen" as integer
declare function PrintToScreen lib "bib" alias "PrinttoScreen" (byval Text as String) as integer
declare function Check lib "bib" alias "Check" as integer
dim as integer dummy
PRINT "DER ZWEITE SCREEN IST GUT VERSTECKT.."
screen 1
Print "WOW DU HAS ES GEFUNDEN =)"
PRINT "DEBUG: ";
If OpenScreen = 0 Then Print "Fehler - Screen erstellen"
If Zeichnespielfeld = 0 Then Print "Fehler - Spielfeld zeichnen"
If PrintToScreen("DAS IST NUR DAS GRAFIK FENSTER IST...") = 0 Then Print "Fehler - Textausgabe"
if Check <> 3 then Print "FEHLER GEFUNDEN!" ELSE PRINT "ALLES OK"
GETKEY |
_________________ Bis irgendwann...  |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 03.05.2008, 17:52 Titel: |
|
|
@AndT
und das hast du wirklich ausprobiert ?
und nur mit -dll als Kompileroption die Dll erstellt ??
und das fbgfx-Fenster aus der Dll kannst du schließen ???
unter Windows ME funktioniert das Alles nicht!!!  _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 03.05.2008, 17:55 Titel: |
|
|
wahrscheinlich hat er es ohne -dll kompiliert und die .exe in .dll umbenannt und dann mit SHELL ausgeführt  _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
Joseph
Anmeldungsdatum: 06.05.2008 Beiträge: 8
|
Verfasst am: 06.05.2008, 16:26 Titel: |
|
|
Hallo,
ein möglicher Lösungsvorschlag für Dein Problem:
Du könntest an die Funktion in der DLL einen Grafik-Puffer übergeben, in den dann gezeichnet wird. Wenn die Funktion ihre Aufgaben erledigt hat und die Kontrolle an das aufrufende Programm zurückgibt, wird der Puffer zur Anzeige gebracht. Eine einfache, aber speicherfressende Variante wäre: Du erstellst mit IMAGECREATE ein Sprite in der Größe des Bildschirms, kopierst den vorhandenen Bildschirminhalt ins Sprite (falls dort schon Grafik vorhanden ist, die Du nicht überschreiben möchtest), übergibst das Sprite an die DLL, lässt dort auf das Sprite zeichnen und lässt dann vom Hauptprogramm das aktualisierte Sprite wieder anzeigen. Sieh Dir dazu in der Befehlsreferenz IMAGECREATE, IMAGEDESTROY, GET, PUT an und bei den Grafikbefehlen die Anweisungen wie man in einen externen Grafik-Puffer zeichnet. Noch wichtig: Die Grafikbefehle in der DLL müssen auf den verwendeten Bildschirm-Modus abgestimmt sein (Farbtiefe). Hoffe, es funzt. |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 06.05.2008, 19:10 Titel: |
|
|
Hi Joseph, willkommen im Forum!
Leider ist dein Vorschlag keine Lösung für dieses Problem.
Auch ImageCreate gehört zu den fbgfx-Anweisungen, wird es im Hauptprogramm gebildet ist dies wieder eine andere Instanz und die fbgfx-Anweisungen aus der DLL können nicht damit arbeiten . _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 06.05.2008, 19:58 Titel: |
|
|
na, immerhin kann man schön mit dem puffer auf direkter basis arbeiten... nur halt nicht mit den typsichen drawing primitives. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 06.05.2008, 20:40 Titel: |
|
|
Also unter XP geht alles  _________________ Bis irgendwann...  |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 06.05.2008, 20:40 Titel: |
|
|
kk _________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Joseph
Anmeldungsdatum: 06.05.2008 Beiträge: 8
|
Verfasst am: 07.05.2008, 19:05 Titel: |
|
|
Hallo,
hatte gestern leider kein FB zur Hand als ich den Vorschlag mit dem Grafikpuffer gemacht habe. Volta, Du hast völlig recht, da EXE und DLL zwei verschiedene Instanzen sind, hat die DLL keine Ahnung, welcher Bildschirmmodus aktiv ist und wohin mit den Grafikdaten.
Hier aber trotzdem eine funktionierende Schritt-für-Schritt-Anleitung, wie man eine DLL dazu bringt, mit den FB-internen Grafikbefehlen etwas auf den Bildschirm zu zeichnen, ob das aber praktisch Sinn macht, ist fraglich:
1. Grafikpuffer in ausreichender Größe anlegen, um den gesamten vorhandenen Bildschirminhalt zu sichern.
2. Bildschirminhalt mit GET im Grafikpuffer sichern.
3. WICHTIG! AUF SCREEN 0 GEHEN!
4. Die gewünschte Function/Sub in der DLL aufrufen und den Grafikpuffer übergeben.
5. WICHTIG! VOR BEGINN DER GRAFIKANWEISUNGEN IN DER FUNCTION/SUB DEN GEWÜNSCHTEN GRAFIK-BILDSCHIRMMODUS DEFINIEREN! (genau davon sollte man in DLLs eher die Finger lassen, hier ist es aber notwendig).
6. Grafikbefehle ausführen und in den Grafikpuffer zeichnen.
7. WICHTIG! VOR VERLASSEN DER DLL AUF SCREEN 0 GEHEN!
8. Zum Hauptprogramm zurückkehren.
9. WICHTIG! JETZT IM HAUPTPROGRAMM WIEDER DEN GEWÜNSCHTEN GRAFIK-BILDSCHIRMMODUS DEFINIEREN!
10. Mit PUT den modifizierten Grafikpuffer am Bildschirm anzeigen lassen.
Das generelle Problem dabei: Beim Umschalten zwischen SCREEN 0 und Grafikmodus flackert es logischerweise. Wenn das nur einmal am Anfang des Spiels geschieht, ist das sicher kein Problem, die Methode ist aber völlig ungeeignet, um während des Spiels den Bildschirm zu aktualisieren. Es geht also jetzt darum, einen Weg zu finden, wie man der DLL mitteilt, welcher Grafikmodus aktiv ist und wo im Bildschirmspeicher die FB-internen Grafikfunktionen die Pixel setzen sollen, ohne in der DLL vor Beginn der Grafikbefehle einen Screen-Modus angeben zu müssen. Das gleichzeitige Definieren eines neuen Screens in der DLL, ohne den bisher aktiven Screen mit SCREEN 0 zu deaktivieren, führt zu unvorhersehbarem Verhalten, da z.B. im Fenster-Modus zwei Screens übereinander liegen, einer davon ist völlig verpixelt, z.B. bei mir mit verzerrten Trümmern der Startleiste (der dahinter liegende Screen enthält aber die gewünschte Grafik) und kann nicht nur zum Absturz des Programms führen, sondern hat bei mir auch Spuren im Bildschirmspeicher hinterlassen, die erst beim nächsten Start des Rechners verschwunden sind. Bin schon neugierig, ob es dafür eine Lösung gibt.
Ansonsten gibt es nur die Alternative, wie Jojo geschrieben hat, direkt im Grafikpuffer die Farbwerte der Pixel zu ändern, das erfordert aber, dass man sich eigene Zeichenfunktionen definiert um die Position jedes Pixels im Datenvektor bestimmen und den Farbwert setzen zu können. In der QB-Monster-FAQ findet sich da z.B. die Anleitung, wie man eine Linie oder Kreis mit dem Bresenham-Algorithmus zeichnet. Auch eine Anleitung, wie man einen ausgleichenden 4-Punkte-Spline nach der de Casteljau-Methode (ist vom Ergebnis her praktisch identisch mit der Bezier-Methode) zeichnen kann, findet man dort. Wichtig dabei: Wenn man mit selbstgeschriebenen Zeichenfunktionen die Farbwerte der Pixel im Grafikpuffer ändert, gibt es kein komfortables, automatisches Clipping, man muss selber prüfen, ob man noch im erlaubten Zeichenbereich ist und den Farbwert setzen darf oder nicht, andernfalls greift man auf eine Speicherstelle ausserhalb des erlaubten Bereichs zu. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 07.05.2008, 19:12 Titel: |
|
|
...oder man malt auf der anderen seite des bildschirms weiter
naja, du hast ja grad schön gezeigt, wie aufwändig und zugleioch auch unnötig es ist, die DLL den krams machen zu lassen - wird ja dadurch schon viel langsamer und nützen tut diese methode auch nix. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
Joseph
Anmeldungsdatum: 06.05.2008 Beiträge: 8
|
Verfasst am: 07.05.2008, 19:41 Titel: |
|
|
@Jojo,
hast Recht, aber zumindest konnte eine Möglichkeit gefunden werden, wie man eine DLL dazu bringt, was am Bildschirm zu zeichnen. Die Frage an sich war trotzdem interessant.
@Felix,
am besten, Du baust Deine Grafikanweisungen ins Hauptprogramm ein oder lagerst sie in eine statische Lib aus, die beim Kompilieren hinzugebunden wird. Die Variante mit der DLL hätte praktisch bestenfalls Sinn, wenn auch andere Programme darauf zugreifen sollen, aber auch dann würde das nur sinnvoll sein, wenn das von der Sub/Function erzeugte Bild je nach Spielsituation anders aussieht (es müssten dann Parameter übergeben werden, die das Aussehen des Bildes bestimmen). Soll z.B. immer nur das selbe Bild gezeichnet werden, könnte man das einmal erzeugen und als Bilddatei speichern, die dann bei Bedarf geladen wird. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 07.05.2008, 19:43 Titel: |
|
|
Praktische Anwendung gibt es durchaus für sowas, ja. Aber dann eher mit der direkten Manipulation des bildpuffers. Das hab ich so z.B. im Hotel-Manager gemacht, da ruft das etwas langsamere VB eine FB-Bibliothek auf, die rasend schnell einen übergebenen Bildpuffer durchwühlt.  _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 25.05.2008, 15:25 Titel: |
|
|
Jojo hat Folgendes geschrieben: | Praktische Anwendung gibt es durchaus für sowas, ja. Aber dann eher mit der direkten Manipulation des bildpuffers. Das hab ich so z.B. im Hotel-Manager gemacht, da ruft das etwas langsamere VB eine FB-Bibliothek auf, die rasend schnell einen übergebenen Bildpuffer durchwühlt.  |
Erwischt
\Data\libalpha.dll |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 25.05.2008, 15:28 Titel: |
|
|
...ist das jetzt was besonderes? _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 25.05.2008, 15:33 Titel: |
|
|
Jojo hat Folgendes geschrieben: | ...ist das jetzt was besonderes? |
Ja.
Wenn du OGL benutzt, warum brauchst du da noch eine extra Alpha-Lib? |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|