Simple graphique avec GDI+

Soyez le premier à donner votre avis sur cette source.

Vue 3 459 fois - Téléchargée 357 fois

Description

Bonjour,
Je vous invite à "améliorer" un peu le code présenté sous "Simple graphique avec GDI" à l'aide de GDI+ (Graphics Device Interface plus).
Pour cela, nous allons utiliser quelques transformations 2D et l'"anti-aliasing".
Voir: Simple graphique avec GDI,    Anticrénelage ou anti-aliasing

Voici quelques propriétés du code présenté ici:
- aucune librairie graphique à installer.
- code sur un seul fichier: GraphicGDIplus.cpp.
- deux includes: <windows.h> et <gdiplus.h>.
- initialisation de GDI+.
- création de fonte.
- écriture de textes (non-horizontale à l'aide de transformations).
- anticrénelage (anti-aliasing) des textes.
- utilisation des transformations 2D GDI+.
- représentation de l'éponge de Sierpinski (appels récursifs).
- l'objet 3D est "calculé" au moment du dessin.
- vraie perspective (alors que GDI+ n'a aucune fonctionnalité 3D).
- projection 3D->2D "fixe".
- élimination des facettes et arêtes cachées.
- anticrénelage (anti-aliasing) des polygones et de ses contours.
- ...
#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

static float cMin,UX=-646.2198F,UY=861.6264F,VX=320,VY=240,VZ=-1000
  ,WX=-0.742781F,WY=-0.557086F,WZ=-0.371391F,Z=1077;
static Pen *pen;
static SolidBrush *bsh,*bshX,*bshY,*bshZ;
static Graphics *g;
static Font *fnt;

static void Prj(float x,float y,float z,PointF *p) { // Proj (x,y,z)-->p
  float w=WX*x+WY*y+WZ*z+Z;
  p->X=(float)((UX*x+UY*y)/w); p->Y=(float)((VX*x+VY*y+VZ*z)/w);
}

static void Cube(float x,float y,float z,float c) {
  if (c>cMin) { // subdivision en 27-7 = 20 petits cubes
    float xa=x+(c/=3),xb=xa+c,ya=y+c,yb=ya+c,za=z+c,zb=za+c;
    Cube(x,y ,z ,c); Cube(xa,y ,z ,c); Cube(x ,ya,z ,c); Cube(xb,y ,z ,c);
    Cube(x,yb,z ,c); Cube(xb,ya,z ,c); Cube(xa,yb,z ,c); Cube(xb,yb,z ,c);
    Cube(x,y ,za,c); Cube(xb,y ,za,c); Cube(x ,yb,za,c); Cube(xb,yb,za,c);
    Cube(x,y ,zb,c); Cube(xa,y ,zb,c); Cube(x ,ya,zb,c); Cube(xb,y ,zb,c);
    Cube(x,yb,zb,c); Cube(xb,ya,zb,c); Cube(xa,yb,zb,c); Cube(xb,yb,zb,c);
  } else { // (c <= cMin): projection et dessin
    PointF fX[4],fY[4],fZ[4]; // 3 facettes visibles
    Prj(x+c,y  ,z  ,fX); Prj(x+c,y+c,z  ,fX+1); fY[3]=fX[1];
    Prj(x  ,y+c,z  ,fY); Prj(x  ,y+c,z+c,fY+1); fZ[3]=fY[1];
    Prj(x  ,y  ,z+c,fZ); Prj(x+c,y  ,z+c,fZ+1); fX[3]=fZ[1];
    Prj(x+c,y+c,z+c,fX+2); fZ[2]=fY[2]=fX[2];
    g->FillPolygon(bshX,fX,4); g->DrawPolygon(pen,fX,4);
    g->FillPolygon(bshY,fY,4); g->DrawPolygon(pen,fY,4);
    g->FillPolygon(bshZ,fZ,4); g->DrawPolygon(pen,fZ,4);
  }
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT mes,WPARAM wParam,LPARAM lParam) {
  PAINTSTRUCT ps;
  switch(mes) {
  case WM_CREATE:
    pen=new Pen(Color(0XFFCCCCCC));
    bsh=new SolidBrush(Color());
    bshX=new SolidBrush(Color(0XFFCC9944));
    bshY=new SolidBrush(Color(0XFF994411));
    bshZ=new SolidBrush(Color(0XFFFFDD77));
    fnt=new Font(L"Times New Roman",20.0); return 0;
  case WM_PAINT:
    BeginPaint(hWnd,&ps); g=new Graphics(ps.hdc);
    g->SetSmoothingMode(SmoothingModeAntiAlias);
    g->DrawString(L"Éponge de Sierpinski (anti-aliasing)"
      ,-1,fnt,PointF(40,720),bsh);
    g->RotateTransform(-9);
    g->SetTextRenderingHint(TextRenderingHintAntiAlias);
    g->DrawString(L"Simple graphique avec GDI+",-1,fnt,PointF(40,60),bsh);
    g->ResetTransform(); g->TranslateTransform(440,320);
    cMin=20; Cube(-240,-240,-240,480);
    EndPaint(hWnd,&ps);
    return 0;
  case WM_DESTROY: PostQuitMessage(0); return 0;
  default: return DefWindowProc(hWnd,mes,wParam,lParam);
  }
}

int WINAPI WinMain(HINSTANCE hI,HINSTANCE,PSTR,int iCmdShow) {
  GdiplusStartupInput gdiplusStartupInput;
  ULONG_PTR gdiplusToken;
  GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,0); // Initialize GDI+

  WNDCLASS wc={CS_HREDRAW|CS_VREDRAW,WndProc,0,0,hI,LoadIcon(0,IDI_APPLICATION)
    ,LoadCursor(0,IDC_ARROW),CreateSolidBrush(0XFFFFFF),0,"cGDI+"};
  RegisterClass(&wc);
  HWND hWnd=CreateWindow("cGDI+","Simple graphique avec GDI+",
    WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,880,800,0,0,hI,0);
  ShowWindow(hWnd,iCmdShow); UpdateWindow(hWnd);
  MSG m;
  while(GetMessage(&m,0,0,0)) {TranslateMessage(&m); DispatchMessage(&m);}
  GdiplusShutdown(gdiplusToken); return (int)m.wParam;
}

Sur la capture, on peut constater une amélioration de la qualité du rendu grâce à l'anticrénelage (anti-aliasing).
En contrepartie, le temps d'affichage est augmenté.

Si vous désirez une représentation sans les lignes de contour des polygones, supprimez toutes les instructions qui concernent la variable pen.

Les éléments de GDI+ non traités ici sont principalement les régions, les images et les "Bitmaps".
 
 
Voir aussi: Fractales, éponge 3d de Sierpinski-Menger
Essai direct: Eponge    Eponge évolution

Bonne lecture

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
226
Date d'inscription
lundi 22 avril 2013
Statut
Membre
Dernière intervention
28 septembre 2020
1
Excellent bonne démonstration facile à comprendre de l'utilisation de l'application interface de Windows pour au moins créer une fenêtre très simplement.
Messages postés
323
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
19 octobre 2020
2
Bonjour,
Chez moi, mon compilateur annonce le message d'erreur suivant :
IntelliSense : initialisation avec '{...}' non autorisée pour un objet de type "Gdiplus::PointF"
pour la ligne : PointF pol[]={{100,100},{200,200},{100,200}};
Mais il accepte : PointF pol[]={PointF(100,100),PointF(200,200),PointF(100,200)};
De toutes façons, il semble que cette ligne ne soit pas utilisée. Et de fait, en la supprimant la compilation et l'exécution fonctionnent très bien. De plus c'est un exemple d'utilisation de GDI+ très démonstratif. Merci.
Messages postés
261
Date d'inscription
mardi 12 décembre 2006
Statut
Membre
Dernière intervention
10 juin 2019
>
Messages postés
323
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
19 octobre 2020

Bonjour,
Merci pour votre message.
En effet, la ligne que vous mentionnez n'a rien à faire dans ce code !
Je vais donc la supprimer encore aujourd'hui.
Toutes mes excuses ...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.