fxmeta2d
Metaballs 2D
Les metaballs sont ces objets vaguement circulaires qui se fondent les uns dans les autres lorsqu’ils sont a proximité de leurs semblables. Cet effet graphique est très simple à implanter et c’est pourquoi ce tuteur sera relativement court. Malgré sa simplicité, il est très agréable à regarder et il permet, avec un peu d’imagination, de réaliser des effets superbes.
INITIALISATION DES METABALLS
Une metaball est un objet en motion, circulaire, possédant donc une origine et un rayon. Il nous faudra donc une structure de donnée pouvant contenir les informations pertinentes sur nos metaballs. Voici la structure META qui répond à ces critères :
typedef struct
{
int X, // Centre x
Y, // Centre y
Rayon, // Rayon de cette metaball
Vx, // Velocité x
Vy; // Velocité y
} META;
Les informations sur nos metaballs seront contenues dans un tableau, dont la mémoire sera alloué dynamiquement selon le nombre de metaballs que l’usager désire voir sur son écran :
META *Metaball = NULL; // Tableau dynamique pour les metaballs
Pour représenter nos metaballs graphiquement, il nous faudra une texture. Cette texture devra être semblable à une environment map, c’est à dire que plus son sqrt(x^2 + y^2) est petit (donc plus prêt de l’origine du cercle), plus sa couleur sera brillante. On pourrait charger un bitmap de ce genre, mais il est très facile de générer dans notre code cette texture. On utilisera une taille de 256 x 256, très pratique pour les bit-shifting. Lorsque nous dessinerons une metaball, nous interpolerons dans la texture selon le rayon de cette metaball :
void InitMetaballs()
{
int x,y;
float d,c;
for (x =-128; x<128; x++)
for (y =-128; y <128; y++)
{
d = (float) sqrt(x*x + y*y);
if (d <= 128)
{
c = (float) (160*cos(d*3.1415927f/128)+160);
if (c>255.0) c = 255.0;
Texture[(y+128)*256+x+128] = (unsigned char)c;
}
else Texture[(y+128)*256+x+128]=0;
}
La deuxième partie de cette fonction initialise les metaballs avec des variables aléatoires, qui seront en partie déterminé par l’usager, via une boîte de dialogue (voir Windows chap.1) :
for (x=0;x<NB_META;x++)
{
Metaball[x].X = (rand()%ECRAN_X);
Metaball[x].Y = (rand()%ECRAN_Y);
Metaball[x].Vx = (rand()%10) - 5;
Metaball[x].Vy = (rand()%10) - 5;
Metaball[x].Rayon = (rand()%RAYON_META) + (RAYON_META/2);
}
}
DESSINER LES METABALLS
Nous allons dessiner les metaballs en utilisant la texture map que nous venons de générer. A partir du rayon de la metaball (et de son origine, naturellement), nous allons interpoler dans la texture afin de dessiner une sphère du rayon correspondant. Il faudra ensuite, pour obtenir l’effet de « mercure », additionner les valeurs R,G,B (en mode RGB) ou les indices de palettes (en mode 8-bit). Il faudra s’assurer qu’on ne dépasse pas le maximum d’intensité de couleur (255), et affiche le pixel. Regardons plus attentivement la fonction DessineMetaballs. La première étape consiste à déplacer les metaballs selon leurs vélocités X et Y, et de s’assurer qu’elles ne dépassent pas les limites de l’écran :
for (int i=0;i<NB_META;i++)
{
if ((Metaball[i].X+=Metaball[i].Vx)<0)
{
Metaball[i].X = 0;
Metaball[i].Vx =-Metaball[i].Vx;
}
else if (Metaball[i].X>ECRAN_X-1)
{
Metaball[i].X = ECRAN_X-1;
Metaball[i].Vx =-Metaball[i].Vx;
}
if ((Metaball[i].Y+= Metaball[i].Vy)<20)
{
Metaball[i].Y=20;
Metaball[i].Vy=-Metaball[i].Vy;
}
else if (Metaball[i].Y>ECRAN_Y-1)
{
Metaball[i].Y=ECRAN_Y-1;
Metaball[i].Vy=-Metaball[i].Vy;
}
Une fois ces tests réalisés, on passe à la deuxième étape, qui consiste à dessiner les metaballs sur l’écran. Comme mentionner ci-haut, on interpole dans la texture map selon le rayon des metaballs, et on additionne le textel (pixel dans la texture) avec le pixel déjà présent sur l’écran virtuel. Cette nouvelle valeur donnera l’impression que les pixels des metaballs se « fondent » les unes dans les autres :
// Variables de travail pour simplifié le tout
ra = Metaball[i].Rayon;
cx = Metaball[i].X;
cy = Metaball[i].Y;
// Delta U et delta V en 16.16 virgule fixe
dv = du = (float)(255 << 16) / (ra+ra);
u=v=0;
// Parcourir de centrey-rayon .. centrey+rayon
for (int y=cy-ra;y<cy+ra;y++)
{
// Clipping y
if ((y>=0) && (y<ECRAN_Y))
{
u = 0;
tv = (v >> 16);
offset=(y*ECRAN_X);
// Parcourir de centrex-rayon .. centrex+rayon
for (int x=cx-ra;x<cx+ra;x++)
{
// Clipping x
if ((x>=0) && (x<ECRAN_X))
{
// Addition du pixel sur l'écran virtuel et dans la texture
dest = virtuel[offset+x] + Texture[(tv<<8)+(u>>16)];
// Ne pas dépasser 255!
if (dest > 255) dest = 255;
// L'afficher dans l'écran virtuel
virtuel[offset+x] = dest;
}
// Suivre le delta X
u += (int)du;
}
}
// Suivre le delta Y
v += (int)dv;
}
}
Remaquer que j’utilise des nombres à virgules fixes (16.16) pour l’interpolation. Dans ce cas particulier, il m’a sembler très pertinent (surtout très facile) d’utiliser des nombres à virgules fixes, sans trop mélanger le lecteur. J’effectue aussi le clipping au fur et à mesure que je dessine les metaballs. N’oubliez pas qu’on dessine une sphère en parcourant (origine-rayon .. origine+rayon).
fxmeta2d.cpp
// Metaballs 2D
// DATE: 30/06/99
// AUTEUR: Shaun DorÈ
// NOTE: En 640x480, il est prÈfÈrable d'augmenter le rayon des metaballs
// MACROS ///////////////////////////////////////////////////////////////
// RÈduit la taille des headers Windows
#define WIN32_LEAN_AND_MEAN
// Macro qui retourne vrai si une touche est enfoncÈe
#define Touche(VkCode) (GetAsyncKeyState(VkCode) & 0x8000 ? 1 : 0)
// INCLUDES /////////////////////////////////////////////////////////////
#include <windows.h> // Include standard de tout programme Win32
#include <windowsx.h> // FonctionnalitÈs supplÈmentaires de Win32
#include <ddraw.h> // Header de DirectDraw
#include <math.h>
#include "resource.h"
// Structure pour contenir les informations sur une metaball
typedef struct
{
int X, // Centre x
Y, // Centre y
Rayon, // Rayon de cette metaball
Vx, // VelocitÈ x
Vy; // VelocitÈ y
} META;
// GLOBALES /////////////////////////////////////////////////////////////
LPDIRECTDRAW DirectDraw = NULL; // Objet DirectDraw
LPDIRECTDRAWSURFACE SurfacePrimaire = NULL; // Surface primaire
LPDIRECTDRAWSURFACE SurfaceSecondaire = NULL; // L'ecran virtuel de la surface primaire
LPDIRECTDRAWPALETTE DirectDrawPal = NULL; // Palette DirectDraw
PALETTEENTRY Palette[256]; // Tableau des couleurs (CLUT)
DDSURFACEDESC SurfaceDesc; // Description de la surface
DDSCAPS SurfaceCap; // CapacitÈs de la surface
HINSTANCE InstancePrincipale = NULL; // Instance de l'application
HWND HandlePrincipale = NULL; // Handle sur la fenÍtre principale
UCHAR *virtuel = NULL; // Ptr sur Ècran virtuel
BOOL Quitter = FALSE; // Test pour savoir si on quitte l'app
META *Metaball = NULL; // Tableau dynamique pour les metaballs
UCHAR Texture[65536]; // Texture gÈnÈrÈe pour dessiner les metaballs
// Variables usager
int ECRAN_X = 0; // RÈsolution horizontale
int ECRAN_Y = 0; // RÈsolution verticale
int NB_META = 0; // Nombre de metaballs
int RAYON_META = 0; // Rayon moyen des metaballs
// D…CLARATIONS /////////////////////////////////////////////////////////
int InitDirectDraw(); // Initialisation de DirectDraw
void CloseDirectDraw(); // LibËre la mÈmoire des objets DirectDraw
void DessinePixel(); // Dessine des pixels sur l'Ècran secondaire
int InitFenetre(); // Initialise la fenÍtre
// FONCTIONS ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Gestionnaire d'ÈvÈnements de la fenÍtre
LRESULT CALLBACK WindowProc(HWND hWnd, // Handle sur la fenÍtre
UINT Msg, // Identificateur du message
WPARAM wParam, // ParamËtre supplÈmentaire
LPARAM lParam) // ParamËtre supplÈmentaire
{
// Analyse le message
switch (Msg)
{
// La fenÍtre va Ítre dÈtruite
case WM_DESTROY:
{
// Envoie un message ‡ la fenÍtre pour quitter
PostQuitMessage(0);
return 0;
} break;
default:
break;
}
// Le reste des messages au gestionnaire par dÈfaut
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
////////////////////////////////////////////////////////////////////////////
// Initialise et instancie une fenÍtre
int InitFenetre()
{
WNDCLASS ClasseFenetre;
HWND hWnd = NULL;
ClasseFenetre.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
ClasseFenetre.lpfnWndProc = WindowProc;
ClasseFenetre.cbClsExtra = 0;
ClasseFenetre.cbWndExtra = 0;
ClasseFenetre.hInstance = InstancePrincipale;
ClasseFenetre.hIcon = LoadIcon(NULL, IDI_APPLICATION);
ClasseFenetre.hCursor = LoadCursor(NULL, IDC_ARROW);
ClasseFenetre.hbrBackground = (struct HBRUSH__ *)GetStockObject(BLACK_BRUSH);
ClasseFenetre.lpszMenuName = NULL;
ClasseFenetre.lpszClassName = "Fenetre";
// Enregistre la classe
if (!RegisterClass(&ClasseFenetre))
{
MessageBox(NULL,
"Il y a eu une erreur dans l'enregistrement de la classe",
"Erreur",
MB_OK | MB_ICONERROR);
return 0;
};
// CrÈation de la fenÍtre
hWnd = CreateWindow("Fenetre",
"Programmation Windows - Chapitre 2",
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
InstancePrincipale,
NULL);
// VÈrifie l'initialisation de la fenÍtre
if (!hWnd)
{
MessageBox(NULL,
"Il y a eu une erreur lors de la crÈation de la fenÍtre",
"Erreur",
MB_OK | MB_ICONERROR);
return 0;
}
// Sauvegarde l'handle de la fenÍtre dans une globale
HandlePrincipale = hWnd;
return 1;
}
////////////////////////////////////////////////////////////////////////////
// Gestionnaire d'ÈvËnements de la boite de dialogues
LRESULT CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
RECT rc;
// Chaine de car pour le combo box
char* nbmeta[] = {"10","20","30", "40", "50"};
char* raymeta[] = {"30","40","50","60","70"};
// Int des chaines de ar
int nbmet[] = {10,20,30,40,50};
int raymet[] = {30,40,50,60,70};
int i;
switch(msg)
{
// CrÈation de la boÓte de dialogue
case WM_INITDIALOG:
// Centre de l'Ècran
GetWindowRect( hwnd, &rc );
SetWindowPos( hwnd, HWND_TOP,
(GetSystemMetrics(SM_CXSCREEN) - rc.right) / 2,
(GetSystemMetrics(SM_CYSCREEN) - rc.bottom) / 2,
0, 0, SWP_NOSIZE);
// Bouton 1 checked
SendDlgItemMessage( hwnd, IDC_320240, BM_SETCHECK, 1, 0 );
for (i=0 ; i<5 ; i++ )
{
SendDlgItemMessage( hwnd, IDC_NBMETA, CB_ADDSTRING, 0, (int)nbmeta[i] );
}
for (i=0 ; i<5 ; i++ )
{
SendDlgItemMessage( hwnd, IDC_METAR, CB_ADDSTRING, 0, (int)raymeta[i] );
}
SendDlgItemMessage( hwnd, IDC_NBMETA, CB_SETCURSEL, 1, 0 );
SendDlgItemMessage( hwnd, IDC_METAR, CB_SETCURSEL, 1, 0 );
break;
// Un bouton de commande (le # du bouton est contenu dans le low 8-bit de wParam)
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case ID_OK:
if ( SendDlgItemMessage( hwnd, IDC_320240, BM_GETCHECK, 0, 0))
{
ECRAN_X = 320;
ECRAN_Y = 240;
}
else if ( SendDlgItemMessage( hwnd, IDC_512384, BM_GETCHECK, 0, 0))
{
ECRAN_X = 512;
ECRAN_Y = 384;
}
else if ( SendDlgItemMessage( hwnd, IDC_640480, BM_GETCHECK, 0, 0))
{
ECRAN_X = 640;
ECRAN_Y = 480;
}
NB_META = nbmet[ SendDlgItemMessage(hwnd,IDC_NBMETA,CB_GETCURSEL,0,0)];
RAYON_META = raymet[ SendDlgItemMessage(hwnd,IDC_METAR,CB_GETCURSEL,0,0)];
Metaball = new META[NB_META];
EndDialog(hwnd, FALSE);
break;
case ID_ABOUT:
{
MessageBox(HandlePrincipale,"METABALLS 2D \n\nCode: Krashlog/Creative Impact\nEmail: dores@videotron.ca\nhttp://pages.infinit.net/shaun/\nhttp://pages.infinit.net/pcdesign/creative.impact/","A propos...",MB_OK | MB_ICONINFORMATION);
break;
}
case ID_QUIT:
{
EndDialog(hwnd, FALSE);
Quitter = TRUE;
break;
}
}
break;
}
default:
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
// GÈnËre la texture utilisÈs pour dessiner les metaballs et initialise
// les metaballs avec une position, une velocitÈ et un rayon initial
void InitMetaballs()
{
// GÈnËre la texture map
for (int x =-128; x<128; x++)
for (int y =-128; y <128; y++)
{
float d = (float) sqrt(x*x + y*y);
if (d <= 128)
{
float c = (float) (160*cos(d*3.1415927f/128)+160);
if (c>255.0) c = 255.0;
Texture[(y+128)*256+x+128] = (unsigned char)c;
}
else Texture[(y+128)*256+x+128]=0;
}
// Initialise les metaballs
for (x=0;x<NB_META;x++)
{
Metaball[x].X = (rand()%ECRAN_X);
Metaball[x].Y = (rand()%ECRAN_Y);
Metaball[x].Vx = (rand()%10) - 5;
Metaball[x].Vy = (rand()%10) - 5;
Metaball[x].Rayon = (rand()%RAYON_META) + (RAYON_META/2);
}
}
////////////////////////////////////////////////////////////////////////////
// Dessine les metaballs
void DrawMetaballs()
{
float du,dv;
int dest,ra,cx,cy,u,v,tv;
unsigned int offset;
// Lock la surface virtuelle
SurfaceSecondaire->Lock(NULL,&SurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
// Ramene un ptr sur la surface secondaire
virtuel = (UCHAR *)SurfaceDesc.lpSurface;
// Vide l'Ècran virtuel
memset(virtuel,0,ECRAN_X*ECRAN_Y);
// VÈrification des bordures et changements de direction
for (int i=0;i<NB_META;i++)
{
if ((Metaball[i].X+=Metaball[i].Vx)<0)
{
Metaball[i].X = 0;
Metaball[i].Vx =-Metaball[i].Vx;
}
else if (Metaball[i].X>ECRAN_X-1)
{
Metaball[i].X = ECRAN_X-1;
Metaball[i].Vx =-Metaball[i].Vx;
}
if ((Metaball[i].Y+= Metaball[i].Vy)<20)
{
Metaball[i].Y=20;
Metaball[i].Vy=-Metaball[i].Vy;
}
else if (Metaball[i].Y>ECRAN_Y-1)
{
Metaball[i].Y=ECRAN_Y-1;
Metaball[i].Vy=-Metaball[i].Vy;
}
// Variables de travail pour simplifiÈ le tout
ra = Metaball[i].Rayon;
cx = Metaball[i].X;
cy = Metaball[i].Y;
// Delta U et delta V en 16.16 virgule fixe
dv = du = (float)(255 << 16) / (ra+ra);
u=v=0;
// Parcourir de centrey-rayon .. centrey+rayon
for (int y=cy-ra;y<cy+ra;y++)
{
// Clipping y
if ((y>=0) && (y<ECRAN_Y))
{
u = 0;
tv = (v >> 16);
offset=(y*ECRAN_X);
// Parcourir de centrex-rayon .. centrex+rayon
for (int x=cx-ra;x<cx+ra;x++)
{
// Clipping x
if ((x>=0) && (x<ECRAN_X))
{
// Addition du pixel sur l'Ècran virtuel et dans la texture
dest = virtuel[offset+x] + Texture[(tv<<8)+(u>>16)];
// Ne pas dÈpasser 255!
if (dest > 255) dest = 255;
// L'afficher dans l'Ècran virtuel
virtuel[offset+x] = dest;
}
// Suivre le delta X
u += (int)du;
}
}
// Suivre le delta Y
v += (int)dv;
}
}
// LibËre la surface secondaire
SurfaceSecondaire->Unlock(virtuel);
// Flip!
SurfacePrimaire->Flip(NULL,DDFLIP_WAIT);
}
////////////////////////////////////////////////////////////////////////////
// Fonction principale
int WINAPI WinMain(HINSTANCE hInstance, // Handle sur l'instance prÈsente
HINSTANCE hPrevInstance, // Handle sur l'instance prÈcÈdente
LPSTR lpCmbLine, // Ptr sur les arguments
int nCmdShow) // …tat de la fenÍtre
{
MSG Msg;
InstancePrincipale = hInstance; // Sauvegarde de l'instance principale
DialogBox(InstancePrincipale, MAKEINTRESOURCE(IDD_MENU), NULL, ( DLGPROC ) DlgProc);
EndDialog(HandlePrincipale, FALSE);
// Initialise et affiche la fenÍtre principale
if (!Quitter)
{
if(!InitFenetre()) Quitter = TRUE;
if(!InitDirectDraw()) Quitter = TRUE;
}
// Tant qu'on n'a pas quitter
while (Quitter == FALSE)
{
// Regarde s'il y a un message dans la msg queue
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
// VÈrifie si le message est un WM_QUIT
if (Msg.message == WM_QUIT)
Quitter = true;
else
{
// Traduit le message
TranslateMessage(&Msg);
// Envoie le message au gestionnaire d'ÈvÈnements
DispatchMessage(&Msg);
}
}
DrawMetaballs();
// Si escape est enfoncÈ, envoyer le message WM_DESTROY dans la queue de messages
if (Touche(VK_ESCAPE)) PostMessage(HandlePrincipale, WM_DESTROY, 0, 0);
}
// Nettoyer la mÈmoire
CloseDirectDraw();
// Retour ‡ Windows
return Msg.wParam;
}
////////////////////////////////////////////////////////////////////////////
// Initialise DirectDraw (surface primaire & secondaire)
int InitDirectDraw()
{
// CrÈation d'un objet DirectDraw
if (DirectDrawCreate(NULL, &DirectDraw, NULL) != DD_OK)
return 0;
// Niveau de coopÈration (FullScreen et Exclusive)
if (DirectDraw->SetCooperativeLevel(HandlePrincipale,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) != DD_OK)
return 0;
// SÈlection du mode vidÈo
if (DirectDraw->SetDisplayMode(ECRAN_X, ECRAN_Y, 8) != DD_OK)
{
MessageBox(HandlePrincipale,
"Le mode vidÈo dÈsirÈ n'est pas supportÈ par votre pilote. Assurez-vous d'avoir la derniËre version du pilote DirectX de votre carte vidÈo.",
"Erreur mode vidÈo",
MB_OK | MB_ICONERROR);
return 0;
}
// Initialise la structure de description de la surface
ZeroMemory(&SurfaceDesc,sizeof(SurfaceDesc));
SurfaceDesc.dwSize = sizeof(SurfaceDesc);
SurfaceDesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
SurfaceDesc.dwBackBufferCount = 1;
// CrÈation de la surface primaire
if (DirectDraw->CreateSurface(&SurfaceDesc, &SurfacePrimaire, NULL) != DD_OK)
return 0;
// CrÈation de la surface secondaire (virtuelle)
SurfaceCap.dwCaps = DDSCAPS_BACKBUFFER;
SurfacePrimaire->GetAttachedSurface(&SurfaceCap, &SurfaceSecondaire);
// GÈnËre une palette pour les metaballs
for (int i=0;i<256;i++)
{
Palette[i].peRed = i;
Palette[i].peGreen = 0;
Palette[i].peBlue = i;
}
for (i=0;i<63;i++)
{
Palette[192+i].peGreen = i * 4;
}
// crÈe l'objet palette
DirectDraw->CreatePalette(DDPCAPS_8BIT,Palette,&DirectDrawPal,NULL);
// Attache la palette 8-bit ‡ la surface primaire
SurfacePrimaire->SetPalette(DirectDrawPal);
InitMetaballs();
// Cacher le curseur de souris
ShowCursor(FALSE);
return 1;
}
////////////////////////////////////////////////////////////////////////////
// LibËre les objets DirectDraw
void CloseDirectDraw()
{
delete [] Metaball;
// LibËre surface secondaire
if (SurfaceSecondaire != NULL)
SurfaceSecondaire->Release();
// LibËre surface primaire
if (SurfacePrimaire != NULL)
SurfacePrimaire->Release();
// LibËre objet COM DirectDraw
if (DirectDraw != NULL)
DirectDraw->Release();
// Affiche le curseur de souris
ShowCursor(TRUE);
}
////////////////////////////////////////////////////////////////////////////
fxmeta2d.dsp
# Microsoft Developer Studio Project File - Name="fxmeta2d" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=fxmeta2d - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "fxmeta2d.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "fxmeta2d.mak" CFG="fxmeta2d - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "fxmeta2d - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "fxmeta2d - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "fxmeta2d - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /G5 /W3 /GX /Ox /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0xc0c /d "NDEBUG"
# ADD RSC /l 0xc0c /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "fxmeta2d - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0xc0c /d "_DEBUG"
# ADD RSC /l 0xc0c /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "fxmeta2d - Win32 Release"
# Name "fxmeta2d - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\fxmeta2d.cpp
# End Source File
# Begin Source File
SOURCE=.\fxmeta2d.rc
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
fxmeta2d.rc
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// French (Canada) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRC)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_CANADIAN
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MENU DIALOG DISCARDABLE 0, 0, 273, 138
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "METABALLS 2D"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",ID_OK,33,109,50,14
PUSHBUTTON "Quitter",ID_QUIT,111,108,50,14
GROUPBOX "MODE VID…O",IDC_RES,14,17,107,77
CONTROL "320 x 240 x 8-bit",IDC_320240,"Button",
BS_AUTORADIOBUTTON,24,36,93,10
CONTROL "640 x 480 x 8-bit",IDC_640480,"Button",
BS_AUTORADIOBUTTON,24,80,93,10
CONTROL "512 x 384 x 8-bit",IDC_512384,"Button",
BS_AUTORADIOBUTTON,24,58,93,10
GROUPBOX "AUTRES OPTIONS",IDC_OPT,129,17,137,77
LTEXT "Nombre de metaballs:",IDC_NBM,135,42,72,11
COMBOBOX IDC_NBMETA,215,39,44,68,CBS_DROPDOWN | WS_VSCROLL |
WS_TABSTOP
LTEXT "Rayon des metaballs:",IDC_RAYON,135,62,70,11
COMBOBOX IDC_METAR,215,58,44,55,CBS_DROPDOWN | WS_VSCROLL |
WS_TABSTOP
PUSHBUTTON "A propos",ID_ABOUT,189,108,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_MENU, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 266
TOPMARGIN, 7
BOTTOMMARGIN, 131
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog Info
//
IDD_MENU DLGINIT
BEGIN
IDC_NBMETA, 0x403, 1, 0
"\000"
0
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // French (Canada) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by fxmeta2d.rc
//
#define IDABOUT 3
#define ID_ABOUT 3
#define IDD_MENU 101
#define IDC_320240 1000
#define IDC_640480 1001
#define IDC_512384 1002
#define IDC_OPT 1004
#define IDC_NBM 1005
#define IDC_NBMETA 1006
#define IDC_RAYON 1007
#define IDC_METAR 1008
#define ID_OK 1010
#define ID_QUIT 1011
#define IDC_RES -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1012
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
fxmeta2d.dsw
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "fxmeta2d"=.\fxmeta2d.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################