Page 1 sur 2

Je souhaite afficher un triangle SANS OpenGL NI DirectX...

Publié : mar. 22/févr./2011 22:09
par Ollivier
Bonjour à vous,

Voilà, ma demande n'est pas plus compliquée que ça: je souhaite user de l'accélération matérielle pour afficher un triangle mais sans ces trucs OpenGL et DirectX.

Pour l'instant, pas de texture, rien: juste des pixels d'une couleur identique qui s'affichent très vite et très nombreux sans faire intervenir le CPU juste pour faire une unité graphique sur le plan(par ex le triangle).

Des idées?

Ollivier

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : mar. 22/févr./2011 22:21
par Ar-S
Des idées?
Oui plein, mais aucune ne concernant ce sujet. Mais je suis curieux de lire les idées en question.

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : mar. 22/févr./2011 22:34
par falsam
Par exemple ce code

Code : Tout sélectionner

; 'initPoly(..)' sets the initial coordiantes for a new polygon.
; you can also set a color (default is white)
; set 'relative_' to #FALSE if following calls of 'setPoly(..)'
; use absolute coordinates. if set to #TRUE (default) 'setPoly(..)'
; moves relative to its current position
Macro initPoly(x_, y_, color_=$FFFFFF, relative_=#True)
  _poly\p0\x = x_
  _poly\p0\y = y_
  _poly\p\x  = x_
  _poly\p\y  = y_
  _poly\Color = color_
  _poly\relative = relative_
  _poly\angle = 0
EndMacro

; 'setPoly(..)' sets a new point / adds a segment.
; paramters 'x_'/'y_' are used as absolute (i.e.:screen-coordinates)
; or relaitve to the current position, according to what was defined
; in 'initPoly(..)'
; you can choose a optional color for this segment.

Macro setPoly(x_, y_, color_=_poly\Color)
  _poly\go\x = (x_)+(0 Or _poly\relative)*_poly\p\x
  _poly\go\y = (y_)+(0 Or _poly\relative)*_poly\p\y
  LineXY( _poly\p\x, _poly\p\y, _poly\go\x, _poly\go\y, color_)
  _poly\p\x =  _poly\go\x
  _poly\p\y =  _poly\go\y
EndMacro

; 'closePoly()' is not required, but can be used to easily close
; a polygon, that is to say to draw a line from the current postion
; back to the initial position.
; you can choose an optional color for this segment.
Macro closePoly(color_=_poly\Color)
  LineXY(_poly\p\x, _poly\p\y, _poly\p0\x, _poly\p0\y, color_)
EndMacro


Enumeration
  #MainForm
  #Image
  #RImage
EndEnumeration

Structure _S_poly
  p0.POINT
  p.POINT
  go.POINT
  center.POINT
  radius.l
  angle.f
  Color.l
  relative.l
  temp.f
EndStructure
Global _poly._S_poly

Procedure MainFormShow()
  OpenWindow(#MainForm,0,0,800,600,"Un trinagle",#PB_Window_ScreenCentered |#PB_Window_SizeGadget | #PB_Window_SystemMenu)
  ImageGadget(#Image,0,0,0,0, CreateImage(#RImage, 800, 600), #PB_Image_Border)
  
  ;Un triangle
  StartDrawing(ImageOutput(#RImage))
  initPoly(50,300,$0F18F0)
  setPoly(100,0)
  setPoly(-100,100)
  closePoly()  
  
  StopDrawing()
   SetGadgetState(#Image, ImageID(#RImage))
EndProcedure

MainFormShow()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Gadget

    Case #PB_Event_CloseWindow
      End
  EndSelect
ForEver
Source complet
http://forums.purebasic.com/french/view ... 6dc#p87953

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : mer. 23/févr./2011 1:17
par Backup
......................

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : ven. 25/févr./2011 21:39
par Ollivier
@Falsam et Dobro

Merci pour vos propositions. Malheureusement, elles ne suffisent pas...

Je m'explique. Il y a plusieurs méthodes pour écrire en mémoire Vidéo. La plus simple c'est d'y aller "cash" >> on a un exemple dans notre documentation. Je crois que c'est DirectScreen.PB le fichier d'exemple. On cherche l'adresse mémoire du buffer Vidéo puis on lit et/ou modifie pixel après pixel avec Peek et Poke.

Mais il n'y a pas d'accélération matérielle.

Et c'est ce qui m'intéresse vraiment. J'entends par accélération matérielle Vidéo le fait d'écrire dans un premier temps (en faisant appel au CPU central, de manière conventionnelle) en mémoire Vidéo sa texture ou sa couleur et d'offrir, dans un second temps, à sa carte Vidéo un ensemble d'instructions pour qu'elle aille d'elle-même (sans le CPU central) transférer de la mémoire Vidéo à celle du buffer Vidéo (l'affichage) avec x sortes de transformations (agrandissement, déformation, rotation tangentielle, etc...).

Ces transformations se multiplient au fur et à mesure que les cartes se "sophistiquent". Et deux support logiciels tiennent tête pour traiter ces transformations : DirectX et OpenGL.

Quand on veut jouir de toutes les possibilités de la carte Vidéo que l'on possède, il est normal de disposer de DirectX et OpenGL, puisque la gamme d'instructions Vidéo est consistantes mais surtout les marques de fabricant de carte Vidéo sont nombreuses donc le programmeur n'a pas à se soucier de la manière dont il faut accéder aux différentes possibilités Vidéo: c'est DirectX ou OpenGL qui s'en charge.

Or, moi, je ne veux pas jouir de toutes les possibilités de ma carte Vidéo! Je veux seulement les bases de géométrie d'affichage. Et mon petit doigt me dit que ces bases sont désormais "standardisées". C'est-à-dire que je pense (mais attention, ceci n'est que mon avis personnel et donc sans aucun fondement) qu'il y a désormais une petite douzaines de type d'accès mémoire à 3 étages* qui suffisent dans l'électronique informatique d'aujourd'hui pour afficher un triangle monochrome (complètement de la même couleur) à une vitesse phénoménale, même sur une petite configuration récente (carte vidéo standard agée de moins de 3 ans).

(*): J'entends par «accès mémoire à 3 étages» un tableau de données qu'il faut aller "pécher" (une première fois) dans sa carte Vidéo pour pécher (une seconde fois) un ensemble d'autres tableaux de données toujours dans la carte Vidéo qui donne enfin accès à une troisième pèche qu'est l'architecture Vidéo "en live" (=en direct).

Si ce tissu d'hypothèses peut éclairer la lanterne de personnes audacieuses et partageuses, ce serait le bonheur!

Dans un autre domaine, voici l'impasse technique sur laquelle j'ai buté et qui m'a poussé à faire la demande ici. J'ai récupéré l'exemple de la documentation sur l'accès direct à l'écran et ai utilisé une instruction de transfert ASM SSE. C'est certes une accélération matérielle. Mais, après quelques mesures de chronométrie, je me suis bien rendu compte que ce n'était pas l'accélération matérielle qui me convenait. Il y en a bien une autre, beaucoup plus performante que celle-ci. Je vous laisse maître de juger par vous-même.

Dans cet exemple, voici un équivalent de ClearScreen() (je ne me suis pas foulé à aller jusqu'à tracer un triangle...), mais j'ai beau tâter, le CPU reste bel et bien chargé de faire le transfert mémoire, ce qui ne me convient pas. Attention les yeux, car pour "observer" la vitesse de transfert, j'ai différencié un "ClearScreen(Rouge)" d'un "ClearScreen(Bleu)".

Code : Tout sélectionner

;
; ------------------------------------------------------------
;
;   PureBasic - Drawing via Direct Screen Access (DSA) 
;
;    (c) 2006 - Fantaisie Software
;
; ------------------------------------------------------------
;
; Note: disable the debugger to run at full speed !
;
; La note d'Olliv : ai modifié l'écriture VIDEO pour tester
; l'instruction SSE qui ne suffit malheureusement pas...



      ExamineDesktops()
      ScreenWidth  = DesktopWidth(0)
      ScreenHeight = DesktopHeight(0)
      ScreenDepth = DesktopDepth(0)

      InitSprite()
      InitKeyboard()

Structure Pixel
  Pixel.l
EndStructure

Procedure.f GSin(angle.f)
  ProcedureReturn Sin(angle*(2*3.14/360))
EndProcedure

; Pre-calculated values are faster than realtime calculated ones...
; ... so we save them in an array before starting gfx operations
Dim CosTable(ScreenWidth*2)
Dim ColorTable(255)

For i = 0 To ScreenWidth*2
  CosTable(i) = GSin(360*i/320)* 32 + 32
Next
OpenWindow(0,0,0,400,300,Str(ScreenWidth) + " x " + Str(ScreenHeight) + " x " + Str(ScreenDepth) , $CF0001)
StringGadget(1, 10, 10, 350, 24, "Fenêtre de déboguage (Alt+F4 pour fermer)")

If OpenScreen(ScreenWidth, ScreenHeight, 32, "PB Plasma")

  StartDrawing(ScreenOutput())
        Buffer1     = DrawingBuffer()             ; Get the start address of the screen buffer
        Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
        PixelFormat = DrawingBufferPixelFormat()  ; Get the pixel format. 
  StopDrawing()
  FlipBuffers()
  StartDrawing(ScreenOutput())
        Buffer2     = DrawingBuffer()             ; Get the start address of the screen buffer
        Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
        PixelFormat = DrawingBufferPixelFormat()  ; Get the pixel format. 
  StopDrawing()
  FlipBuffers()
  
*Alloc = AllocateMemory(32)
*Alloc + 15
*Alloc & ~15

For I = 0 To 15 Step 4
      PokeL(*Alloc + I, $FF007FFF)
Next

Define Count.L
Define Sourc.L = *Alloc  
Define Desti.L = Buffer1
Define Desti2.L

Count = Pitch * ScreenHeight / 16     / 2 / 2

      Repeat
            Delay(16)
            
            
            Flip ! 1
            If Flip
                  Desti = Buffer1
                  Desti2 = (Desti + Count * 16)
                  Desti3 = (Desti2 + Count * 16)
                  Desti4 = (Desti3 + Count * 16)
                  For I = 0 To 15 Step 4
                        PokeL(*Alloc + I, $FF007FFF)
                  Next
            Else
                  Desti = Buffer2
                  Desti2 = (Desti + Count * 16)
                  Desti3 = (Desti2 + Count * 16)
                  Desti4 = (Desti3 + Count * 16)
                  For I = 0 To 15 Step 4
                        PokeL(*Alloc + I, $FFFF0000)
                  Next
            EndIf
        

            !     Mov         ESI,        [v_Sourc]
            !     Movaps      XMM0,       [ESI]
            !     Movaps      XMM1,       [ESI]
            !     Movaps      XMM2,       [ESI]
            !     Movaps      XMM3,       [ESI]
            !     Mov         ECX,        [v_Count]
            !     Mov         EDI,        [v_Desti]
            !     Mov         EDX,        [v_Desti2]
            !     Mov         EAX,        [v_Desti3]
            !     Mov         EBX,        [v_Desti4]
            !Loop1:
            !     Movaps      [EDI],      XMM0
            !     Movaps      [EDX],      XMM1
            !     Movaps      [EAX],      XMM2
            !     Movaps      [EBX],      XMM3
            !     Add         EDI,        16
            !     Add         EDX,        16
            !     Add         EAX,        16
            !     Add         EBX,        16
            !     Dec         ECX
            !     Jnz         Loop1        

    
            ExamineKeyboard()
    
            FlipBuffers()
     
      Until KeyboardPushed(#PB_Key_Escape)
      
CloseScreen()
;SetWindowTitle(0, Str(Align) + " " + Str(PitchEqu) )
Repeat
Until WaitWindowEvent() = 16

Else
  MessageRequester("Error","Can't open the screen !",0)
EndIf

End

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : ven. 25/févr./2011 22:23
par Warkering
Tu peux toujours faire de l'art ASCII. :roll: :arrow:

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : ven. 25/févr./2011 23:06
par djes
Désolé Ollivier, mais tu vas être très déçu. A notre époque il n'est plus possible de se passer de DirectX ou d'OpenGL sous Windows pour profiter de l'accélération matérielle, sauf à :
  • écrire son propre driver. Certains sources sont dispo, et ça fonctionne toujours de la même façon, avec des registres, mais c'est spécifique à une configuration.
  • utiliser des routines qui profitent d'une accélération comme certaines fonctions 2D des API. C'est pour ça que tracer une ligne est parfois plus rapide que de tracer un point! Pour savoir si elles sont câblées il faut les "tester" avec d'autres fonctions API. De nos jours, beaucoup de cartes graphiques ne proposent plus ces services, mais avec Vista et Seven, de toutes façons, c'est obsolète.
Si tu veux tracer un triangle vraiment rapidement, ne t'embête pas, OpenGL est ce qu'il y a de plus simple.

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 0:25
par falsam
Un triangle en mode console :p

Code : Tout sélectionner

If OpenConsole()
  Define i, j
  For i=1 To 5
    For j=1 To i
      Print("*")
    Next j
    PrintN("")
  Next i
  Print(#LFCR$+"Press ENTER to quit"): Input()
  CloseConsole()
EndIf
Ok je sors ..... hahahaha

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 0:42
par Backup
@Falsam :

alors je repete encore une fois
lorsque tu fais :

Code : Tout sélectionner

Define i, j
, ça ne sert a rien !

Define ne sert pas a declarer une variable !!
ça sert a declarer un type !!

comme ça

Code : Tout sélectionner

Define.s  i, j
pour dire que dorenavant i et j seront des variables Chaines

si tu ne met pas de type , pas la peine d'utiliser "Define" !! :wink:
en basic ont est pas obligé de declarer une variable

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 0:49
par falsam
Ooops !!! j'oublie à chaque fois que ça ne sert à rien, surtout dans cet exemple.

Code corrigé

Code : Tout sélectionner

if OpenConsole()
  For i=1 To 5
    For j=1 To i
      Print("*")
    Next
    PrintN("")
  Next
  Print(#LFCR$+"Press ENTER to quit"): Input()
  CloseConsole()
EndIf
Pas taper hein ? :p

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 0:57
par Warkering
Lol!
Sinon, pour OpenGL, un p'tit tour côté SdZ dans la section tutoriel C++ et ce sera un bon aperçu. :wink:

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 1:16
par falsam
@Warkering :Ollivier ne souhaite PAS jouir des possibilités DirectX ou OpenGL que lui offre sa carte vidéo.

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 5:51
par Warkering
Oui mais Djes a été plutôt clair, je trouve. Et son avis, je la respecte, puisqu'il semble bien sûr de son affirmation! :wink:

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 10:42
par falsam
@Warkering : Bien entendu que je suis d'accord avec Djes, sauf qu'Ollivier ne veut pas utiliser d'accélération matériel et que répondre à un sujet par le contraire de ce que souhaite l'auteur du sujet ne fait qu'encombrer ce sujet.

Re: Je souhaite afficher un triangle SANS OpenGL NI DirectX.

Publié : sam. 26/févr./2011 20:30
par Ollivier
Djes a écrit :Désolé Ollivier, mais tu vas être très déçu. A notre époque il n'est plus possible de se passer de DirectX ou d'OpenGL sous Windows pour profiter de l'accélération matérielle, sauf à :


écrire son propre driver. Certains sources sont dispo, et ça fonctionne toujours de la même façon, avec des registres, mais c'est spécifique à une configuration.
Quelles configurations? Et quelles sources aussi?