Sign in to follow this  
Followers 0
DatMCEyeBall

2D water simulation using a C++ dll

11 posts in this topic

#1 ·  Posted (edited)

I wrote this a while ago and only recently implemented shading.

The current shading algorithm could use some improvements.

Most of the source is based from here

The .dll source is also in the archive (made with Visual Studio 2012 Express).

2D Water simulation using a C++ dll.7z

If you use a x64 bit OS then:

For anyone having trouble running this on a x64 OS, set #AutoIt3Wrapper_UseX64=n (OP code assumes you are running x86 AutoIt).

 

EDIT:

Added an example using a .gif file (split into frames).

Edited by DatMCEyeBall
3 people like this

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I can't get it run. msvcp110d.dll was missing but after downloaded it, nothing happens when starting the script.

Tested on Win 8.1 and 3.3.10.2.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Cool, works now. I will check whether it can be loaded from memory and use it for my watermark app.

Btw, I tried several times to learn C++ using MS VS but it is a overkill with plenty of features which I don't need when being a C++ noob besides to use the IDE environment.

A mentor would be nice...

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Cool, works now. I will check whether it can be loaded from memory and use it for my watermark app.

Look at the first line of WaterSim.au3 (the Global Enum line).

Check the UseBuffer1 flag in the params structure (forgot the Enum's name) if so use the HM (height map) #1 if not use #2

Add to the data (+=) at the specified location an amount (it's a height map used by the .dll so add a number like 512 or more - depends on what you prefer)

The height map is a 1D array, I think the main .au3 file still has a _PixelIndexFromXY (or similar) function, use it to convert XY co-ordinates into the index of the array. 

Call the NewFrame function to draw and flatten the water.

I can write you something special instead. If you want me to do so then please PM me.

A mentor would be nice...

Mentor?  :sorcerer:

C++ for dummies(link to .pdf) is what I used to learn it, VS is just there for convenience.

Edited by DatMCEyeBall

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I mean rather to load the DLL from the memory.


Thanks for the Dummy stuff but I've already a lot of C++ documentations (incl. this).  :whistle: 

Br,
UEZ

Edited by UEZ
1 person likes this

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

For anyone having trouble running this on a x64 OS, set #AutoIt3Wrapper_UseX64=n (OP code assumes you are running x86 AutoIt).

I'm adding this to the OP.

 

I mean rather to load the DLL from the memory.

Thanks for the Dummy stuff but I've already a lot of C++ documentations (incl. this).   :whistle:

What exactly is bothering you with MS VS C++?

If you have a problem then Google it - that's what I do.

Edited by DatMCEyeBall

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

Your demo reminds me something... 

Nice work and nice effects !  :thumbsup:


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

#10 ·  Posted

I'm adding this to the OP.

 
 

What exactly is bothering you with MS VS C++?

If you have a problem then Google it - that's what I do.

 

I find it hard to use the editor - it is so oversized compared to SciTE. Anyhow, if I find enough motivation I will try again.

 

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#11 ·  Posted

If you try searching on Youtube for "Microsoft Visual Studio 2012 C++ tutorial":

http://www.youtube.com/watch?v=xoExJLVroZc


"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • timmalos
      By timmalos
      Hey all.
      I'm trying to know when my user clicks on a Rect drawn via GDI+. Everything is almost working except I have a strange behaviour in the "order" clicks are fired.
      I created a simplified code to help :
      #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <Array.au3> Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled _GDIPlus_Startup() Global $hGUI, $hGraphics Global $iWidth = 1024, $iHeight = 762 createGUI() draw() While 1 Sleep(10) WEnd Func createGUI() $hGUI = GUICreate("Current CasparCG Output", $iWidth,$iHeight) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetBkColor(0x000000) GUISetState(@SW_SHOW) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;sets the graphics object rendering quality (antialiasing) EndFunc ;==>Example Func draw() ;_WinAPI_draw($hGUI,"","",BitOR($RDW_ERASE,$RDW_INVALIDATE,$RDW_UPDATENOW)) _GDIPlus_GraphicsClear($hGraphics) $hFamily = _GDIPlus_FontFamilyCreate("Arial") $hFont = _GDIPlus_FontCreate($hFamily, 15, 1) $hPen = _GDIPlus_PenCreate(0xFFFEDCFF, 2) ;color format AARRGGBB (hex) $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) $hBrushString = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF00FF) ;color format AARRGGBB (hex) For $i = 1 to 2 Local $x = 0.25 Local $y = 0.25 Local $w = 0.5 Local $h = 0.5 Local $title = "Layer "&$i If $x >= -1 And $x <= 1 Then $x *= $iWidth If $y >= -1 And $y <= 1 Then $y *= $iHeight If $w >= -1 And $w <= 1 Then $w *= $iWidth If $h >= -1 And $h <= 1 Then $h *= $iHeight $hItem = GUICtrlCreateLabel("", $x,$y,$w,$h) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetOnEvent($hItem,"_gui_layer_clicked") ConsoleWrite("Created label with handle="&$hItem&" $i= " & $i&@CRLF) _GDIPlus_GraphicsFillRect($hGraphics, $x, $y, $w, $h,$hBrush) _GDIPlus_GraphicsDrawRect($hGraphics, $x, $y, $w, $h,$hPen) $tLayout = _GDIPlus_RectFCreate($x, $y, $w, $h) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $title, $hFont, $tLayout, $hFormat) _GDIPlus_GraphicsDrawStringEx($hGraphics, $title, $hFont, $aInfo[0], $hFormat, $hBrushString) Next _GDIPlus_BrushDispose($hBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_FontDispose($hFont) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrushString) Return 1 EndFunc Func _gui_layer_clicked() ConsoleWrite("Clicked on " & @GUI_CtrlId&@CRLF) EndFunc Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Clean up resources _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() Exit EndSelect EndFunc ;==>SpecialEvents What happens there :
      We have two rectangles, with the one labelled "2" is front and, the one labelled "1" in background. However when we click, the fired label is the one created first (in the background) and not the second one (in the front).
      Is it normal ?
      If yes, is there any way to change this order ? If I create another label after a first one on the same coords, I would the second one to be fired instead of the first one (This is a simplified code I can't just invert the label order creation easily)
       
      Thanks for your help
       
    • Xandy
      By Xandy
      I wanted to start using SDL2 libraries in C++.
      This is a Hello World project that covers some of the essentials of programming with SDL2.
      I will use it when I forget how to create an SDL2 project.
      Loads a scrolling background image for world. Mouse position, left click, and double click example. Hotkeys and cooldown timers to prevent hotkey spam. Plays background music. (ALT + P) Plays sound effects changing sprite type. (numpad: /, *, -, +) Features a Player class for multiplayer. Player collision detection. Uses a Window class from Lazyfoo for maximize button, fullscreen ext.. Built using MSVS 2013 (free).  All dlls and libraries included and linked (for MSVS) using relative paths. You can probably run the SDL2_HelloWorld.sln without setting up any libraries. Note SDL_Net is setup but not used. Delta time used to create consistent frame rate across machines. Player animation sprite sheet:  
      Demo: Slimy's First Kiss
      Download Source and project: http://songersoft.com/programming/sdl2_helloworld/sdl2_helloworld_about.phtml
      This isn't meant to be amazing.  It's just to help get started with SDL2.
      I will consider any criticism.
      main.cpp
      // This example HelloWorld followed this video: // https://www.youtube.com/watch?v=M4Jgz0wEQxY // Turned into this // https://www.youtube.com/watch?v=yRpen8jOa08&list=PL77-op_SRaiEuC0YC43ZAUJJwL_G_C2z8&index=15 // Window class was copied from Lazyfoo // http://lazyfoo.net/tutorials/SDL/35_window_events/index.php #include <iostream> #include <string> #include "SDL.h" #include "SDL_image.h" #include "SDL_ttf.h" #include "SDL_mixer.h" #include "SDL_net.h" #include "Player.h" #include "Window.h" using namespace std; // Prototypes SDL_Texture *LoadTexture(string filepath, SDL_Renderer *renderTarget); void logSDLError(const string); SDL_Rect sdlrect(int, int, int, int); SDL_Surface *OptimizedSurface(string filepath, SDL_Surface *windowSurface); // if(okAlt) either Alt key is pressed OrKeyALT #define okAlt (k[SDL_SCANCODE_RALT] || k[SDL_SCANCODE_LALT]) int main(int argc, char *argv[]) { // Needed for the initialize block Window window; SDL_Renderer *renderTarget = nullptr; // Initialize SDL2 if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { logSDLError("SDL_Init "); } // Initialize SDL_image if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { cout << "Could not initialize SDL_image: " << IMG_GetError() << std::endl; SDL_Delay(5500); } // Initialize TTF if (TTF_Init() < 0) cout << "TTF_Init " << TTF_GetError() << endl; //Create window if (!window.init("SDL2 Hello World", 640, 480, "../../Graphics/iconbmp.bmp")) { printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); } else { //Create renderer for window renderTarget = window.createRenderer(); if (renderTarget == NULL) { printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); } } // Audio if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { cout << "Mix_OpenAudio: " << Mix_GetError() << endl; } // Load sounds: Run chunk if less than 10 sec, music if greater (generally) //Mix_Music *bgm = Mix_LoadMUS("../../Sounds/overworld.mid"); // Can't Pause MIDI Mix_Music *bgm = Mix_LoadMUS("../../Sounds/bensound-goinghigher.mp3"); cout << Mix_GetError() << endl; // Font and text SDL_Texture *text_texture = nullptr; SDL_Color textColor = { 144, 77, 255, 255 }; TTF_Font *font = TTF_OpenFont("../../Graphics/Fonts/VCR_OSD_MONO.ttf", 20); if (font) { SDL_Surface *textSurf = TTF_RenderText_Solid(font, "Hello world", textColor); text_texture = SDL_CreateTextureFromSurface(renderTarget, textSurf); SDL_FreeSurface(textSurf); } else cout << TTF_GetError() << endl; SDL_Rect textRect = { 0, 0, 0, 0 };// Position of text on window // Get the size of the text_texture SDL_QueryTexture(text_texture, NULL, NULL, &textRect.w, &textRect.h); const int playerMax = 8; int players = 2; float prevTime = 0, currentTime = 0, deltaTime = 0; bool fullscreen_toggle = 0; int i = 0, ii = 0; int redraw = 1; bool done = 0; // Load player sprite sheet and background texture SDL_Texture *spritesheet_texture = LoadTexture("../../Graphics/DW3_Char_SpriteSheet.png", renderTarget); SDL_Texture *bg_texture = LoadTexture("../../Graphics/dw3-over.png", renderTarget); int bg_texture_w = 0, bg_texture_h = 0; // Point k to Keyboard state (only needs done here, not in main loop) const Uint8 *k = SDL_GetKeyboardState(NULL); SDL_Event windowEvent; // Stop keys spamming (like music ON / OFF) float key_cooldown_timer_max = 500.0f, key_cooldown_timer = 0; SDL_Rect cameraRect = { 0, 0, window.getWidth(), window.getHeight()}; // Construct default players Player player[playerMax]; // Customize players (texture and position) for (i = 0; i < players; i++)//(sprite texture, position x, position y) player[i].Player_new(spritesheet_texture, window.getWidth() / 2 + i * 16, window.getHeight() / 2); // Get the size of bg_texture SDL_QueryTexture(bg_texture, NULL, NULL, &bg_texture_w, &bg_texture_h); // Main message loop while (!done) { prevTime = currentTime; currentTime = SDL_GetTicks(); deltaTime = (currentTime - prevTime) / 1000.0f; while (SDL_PollEvent(&windowEvent) != 0) { // Check for events if (windowEvent.type == SDL_QUIT) { // Window Exit done = 1; } else if(windowEvent.type == SDL_MOUSEBUTTONDOWN) { // Mouse buttons if (windowEvent.button.clicks == 2) { // Double left click redraw = 1; } else if (windowEvent.button.button == SDL_BUTTON_LEFT) { // Single left click redraw = 1; } // Output mouse position cout << "Mouse: " << windowEvent.button.x << " " << windowEvent.button.y << endl; } }// if(SDL_PollEvent(&windowEvent)) if (okAlt) { // Either ALT key if (k[SDL_SCANCODE_RETURN]) { // ALT + ENTER, toggle fullscreen // Consider matching current window resolution to closest preset array of valid full screen resolutions. fullscreen_toggle = 1; } if (k[SDL_SCANCODE_P]) { if (SDL_GetTicks() - key_cooldown_timer > key_cooldown_timer_max) { // Action cooldown timer is ready. Avoids ON / OFF flicker // Play Music if (!Mix_PlayingMusic()) { cout << "PLAY"; Mix_PlayMusic(bgm, -1); } else if (Mix_PausedMusic()) { cout << "RESUME"; Mix_ResumeMusic(); } else { cout << "PAUSE"; Mix_PauseMusic(); } key_cooldown_timer = SDL_GetTicks(); } }// SDL_SCANCODE_P if (k[SDL_SCANCODE_S]) { // Stop Music Mix_HaltMusic(); } }// okAlt //Handle window events fullscreen_toggle = window.handleEvent(windowEvent, renderTarget, fullscreen_toggle); // Player Update and IntersectsWith for (i = 0; i < players; i++) { player[i].Update(deltaTime, k); for (ii = 0; ii < players; ii++) { if(i != ii)// Not self player[i].IntersectsWith(player[ii]); } } // Camera cameraRect.x = player[0].GetOriginX() - window.getWidth() / 2; cameraRect.y = player[0].GetOriginY() - window.getHeight() / 2; // Normalize if (cameraRect.x < 0) cameraRect.x = 0; if (cameraRect.y < 0) cameraRect.y = 0; if (cameraRect.x + cameraRect.w >= bg_texture_w) cameraRect.x = bg_texture_w - window.getWidth(); if (cameraRect.y + cameraRect.h >= bg_texture_h) cameraRect.y = bg_texture_h - window.getHeight(); redraw = 1; // Don't judge me if (redraw) { // Redraw should definatly pretty much be at the end of loop // Clear window SDL_RenderClear(renderTarget); // Copy camera from bg_texture SDL_RenderCopy(renderTarget, bg_texture, &cameraRect, NULL); // Draw players for (i = 0; i < players; i++) player[i].Draw(renderTarget, cameraRect); // Print text SDL_RenderCopy(renderTarget, text_texture, NULL, &textRect); // Show the rendered content SDL_RenderPresent(renderTarget); redraw = 0; }// if(redraw) }// while(true) // Free windows window.free(); SDL_DestroyTexture(bg_texture); SDL_DestroyTexture(spritesheet_texture); SDL_DestroyTexture(text_texture); TTF_CloseFont(font); // Free Renderers SDL_DestroyRenderer(renderTarget); // Free music Mix_FreeMusic(bgm); // Close systems Mix_Quit(); TTF_Quit(); IMG_Quit(); SDL_Quit(); return EXIT_SUCCESS; }// main() SDL_Texture *LoadTexture(string filepath, SDL_Renderer *renderTarget) { // Create texture SDL_Texture *texture = nullptr; // Load surface SDL_Surface *surface = IMG_Load(filepath.c_str()); if (surface == NULL) { // surface didn't load logSDLError("LoadTexture surface "); } else { SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0, 0, 0)); texture = SDL_CreateTextureFromSurface(renderTarget, surface); //SDL_SetTextureColorMod(texture, 120, 150, 140); if (texture == NULL) logSDLError("LoadTexture texture "); } SDL_FreeSurface(surface); return texture; } void logSDLError(const string msg){ cout << msg << " Error: " << SDL_GetError() << endl; SDL_Delay(4000); } SDL_Rect sdlrect(int x, int y, int w, int h) { SDL_Rect rect = {x, y, w, h}; return rect; } SDL_Surface *OptimizedSurface(string filepath, SDL_Surface *windowSurface) { SDL_Surface *optimizedSurf = nullptr; SDL_Surface *surface = IMG_Load(filepath.c_str()); if (surface == NULL) { cout << "Error: " << endl; } else { optimizedSurf = SDL_ConvertSurface(surface, windowSurface->format, 0); if (optimizedSurf == NULL) cout << "Error: " << endl; } SDL_FreeSurface(surface); return optimizedSurf; } Player.h
      #pragma once #include <iostream> #include "SDL.h" #include <String> #include "SDL_mixer.h" using namespace std; enum player_control { ePlayer_control_up, ePlayer_control_down, ePlayer_control_left, ePlayer_control_right, ePlayer_control_type_minus, ePlayer_control_type_plus }; class Player { private: SDL_Rect cropRect; SDL_Texture *texture; int spritesheet_texture_w, spritesheet_texture_h;//size of spritesheet texture bool isActive;//animation timer SDL_Scancode keys[6]; int frame_w, frame_h;//16, 16 float frameTimerMax; float frameTimer;//0..frameTimerMax int frame;//0..1 int frameMax;//2 int way;//0..3 int classType;//0..53 float moveSpeed; float cast_cooldown_max; Mix_Chunk *soundEffect; int originX, originY; int radius; Uint32 key_cooldown_timer; string name; public: void Player_new(SDL_Texture *spritesheet_texture, int x, int y); Player(); ~Player(); void Update(float delta, const Uint8 *keyState); void Draw(SDL_Renderer *renderTarget, SDL_Rect cameraRect); bool IntersectsWith(Player &p); int GetOriginX(); int GetOriginY(); int GetRadius(); SDL_Rect positionRect; }; Player.cpp
      #pragma once #include "Player.h" #include "SDL_image.h" #include "SDL_mixer.h" #include <iostream> #include <String> #include <cmath> using namespace std; Player::Player() { cropRect = {0, 0, 16, 16}; texture = nullptr; spritesheet_texture_w = spritesheet_texture_h = 0;//size of spritesheet texture isActive = false;//animation timer keys[6]; frame_w = frame_h = 16;//16, 16 frameTimerMax = 0.5f; frameTimer = 0;//0..frameTimerMax frame = 0;//0..1 frameMax = 2;//2 way = 0;//0..3 classType = 0;//0..53 moveSpeed = 200.0f; radius = frame_w / 2; soundEffect = nullptr; key_cooldown_timer = 0; cast_cooldown_max = 190.0f; static int playerNumber = 0; playerNumber++; name = "Player:" + to_string(playerNumber); // Setup keys for player 1 // ** I see the enum didn't exist when this was written ** if (playerNumber == 1) { keys[0] = SDL_SCANCODE_W; keys[1] = SDL_SCANCODE_S; keys[2] = SDL_SCANCODE_A; keys[3] = SDL_SCANCODE_D; keys[4] = SDL_SCANCODE_KP_MINUS; keys[5] = SDL_SCANCODE_KP_PLUS; } else { // Setup keys all other players (not 1) keys[0] = SDL_SCANCODE_UP; keys[1] = SDL_SCANCODE_DOWN; keys[2] = SDL_SCANCODE_LEFT; keys[3] = SDL_SCANCODE_RIGHT; keys[4] = SDL_SCANCODE_KP_DIVIDE; keys[5] = SDL_SCANCODE_KP_MULTIPLY; } }//Player::Player() void Player::Player_new(SDL_Texture *spritesheet_texture, int x, int y) { // This is new player isActive = false; // Read size of spritesheet texture SDL_QueryTexture(spritesheet_texture, NULL, NULL, &spritesheet_texture_w, &spritesheet_texture_h); texture = spritesheet_texture; // spritesheet rect cropRect = { 0, 0, 16, 16 }; // player screen position positionRect = { x, y, 16, 16 }; // Defaults moveSpeed = 200.0f; radius = frame_w / 2; frameTimer = 0; frame = 0; frameMax = 2; way = 0; classType = 0; originX = frame_w / 2; originY = frame_h / 2; soundEffect = Mix_LoadWAV("../../Sounds/whipcrack1.wav"); cout << "Name: " << name << endl; }//Player::Player_new() void Player::Update(float delta, const Uint8 *keyState) { isActive = true; if (keyState[keys[ePlayer_control_up]]) { way = 0; positionRect.y -= moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_down]]) { way = 1; positionRect.y += moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_left]]) { way = 3; positionRect.x -= moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_right]]) { way = 2; positionRect.x += moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_type_minus]]) { if (SDL_GetTicks() - key_cooldown_timer > cast_cooldown_max) { key_cooldown_timer = SDL_GetTicks(); Mix_PlayChannel(-1, soundEffect, 0); classType--; if (classType < 0) classType = spritesheet_texture_h / cropRect.h - 1; cropRect.y = classType * cropRect.h; } } if (keyState[keys[ePlayer_control_type_plus]]) { if (SDL_GetTicks() - key_cooldown_timer > cast_cooldown_max) { key_cooldown_timer = SDL_GetTicks(); Mix_PlayChannel(-1, soundEffect, 0); classType++; if (classType >= spritesheet_texture_h / cropRect.h) classType = 0; cropRect.y = classType * cropRect.h; } } if (isActive) { frameTimer += delta; if (frameTimer >= frameTimerMax){ frameTimer = 0; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); if (frame >= frameMax - 1) frame = 0; else frame++; } } else { frameTimer = 0; } }//Player::Update() void Player::Draw(SDL_Renderer *renderTarget, SDL_Rect cameraRect) { SDL_Rect drawingRect = { positionRect.x - cameraRect.x, positionRect.y - cameraRect.y, positionRect.w, positionRect.h }; SDL_RenderCopy(renderTarget, texture, &cropRect, &drawingRect); } bool Player::IntersectsWith(Player &p){ if (sqrt(pow(GetOriginX() - p.GetOriginX(), 2) + pow(GetOriginY() - p.GetOriginY(), 2)) >= radius + p.GetRadius()) { SDL_SetTextureColorMod(texture, 255, 255, 255); return false; } SDL_SetTextureColorMod(texture, 255, 0, 0); return true; } Player::~Player() { SDL_DestroyTexture(texture); Mix_FreeChunk(soundEffect); } int Player::GetOriginX() { return positionRect.x + originX; } int Player::GetOriginY() { return positionRect.y + originY; } int Player::GetRadius() { return radius; }  
    • InunoTaishou
      By InunoTaishou
      Struggling a bit to get this GDI+ function converted to AutoIt.
      #include <GDIPlus.au3> _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile("F:\DCIM\Camera\20170515_111804.jpg") Global $tBufferSize = DllStructCreate("uint") Global $tProperties = DllStructCreate("uint") _GDIPlus_GetPropertySize($hImage, $tBufferSize, $tProperties) Global $tAllItems = DllStructCreate("struct;char[" & DllStructGetData($tBufferSize, 1) & "];endstruct") _GDIPlus_GetAllPropertyItems($hImage, $tBufferSize, $tProperties, $tPropertyItem) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Func _GDIPlus_GetAllPropertyItems(ByRef $hImage, Const $tTotalBufferSize, Const $tNumProperties, ByRef $tAllItems) If (Not IsDllStruct($tPropertyItem)) Then Return SetError(-1, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetAllPropertyItems", "hwnd", $hImage, "unit", DllStructGetData($tTotalBufferSize, 1), "uint", DllStructGetData($tNumProperties, 1), "ptr", DllStructGetPtr($tAllItems)) If (@error) Then Return SetError(@error, @extended, ConsoleWrite("@Error = " & @error & @LF)) If ($aResult[0]) Then Return SetError($aResult[0], @extended, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetAllPropertyItems Func _GDIPlus_GetPropertySize(Const ByRef $hImage, ByRef $tTotalBufferSize, ByRef $tNumProperties) If (Not IsDllStruct($tTotalBufferSize)) Then Return SetError(-1, 0, "") If (Not IsDllStruct($tNumProperties)) Then Return SetError(-2, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint_ptr", DllStructGetPtr($tTotalBufferSize), "uint_ptr", DllStructGetPtr($tNumProperties)) If (@error) Then Return SetError(@error, @extended, "") If ($aResult[0]) Then Return SetError($aResult[0], 0, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetPropertySize Got the GetPropertySize function to work, gives me the correct buffer size and the property count, but I cannot figure out how to get the struct for the all items.
      Function on MSDN:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms535372(v=vs.85).aspx
      Struct needed:
      PropertyItem class:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx
      Found other topics about this function in other languages where they used a blank string as the buffer, so I tried using a char array, which doesn't work. Just cannot figure out how to create the struct buffer to hold the data.
    • UEZ
      By UEZ
      Since I disovered FreeBasic I decided to create a DLL to implement much faster image processing functionality to AutoIt.
      Following functions are implemented yet:
      _GDIPlus_BitmapApplyFilter_BWJJNDithering _GDIPlus_BitmapApplyFilter_Cartoon1 _GDIPlus_BitmapApplyFilter_ColorAccent _GDIPlus_BitmapApplyFilter_Convolution_AnotherBlur _GDIPlus_BitmapApplyFilter_Convolution_BoxBlur _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection1 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection2 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection3 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection4 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection5 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection6 _GDIPlus_BitmapApplyFilter_Convolution_Emboss1 _GDIPlus_BitmapApplyFilter_Convolution_Emboss45Degree _GDIPlus_BitmapApplyFilter_Convolution_EmbossTopLeftBottomRight _GDIPlus_BitmapApplyFilter_Convolution_Gaussian3x3 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_1 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_2 _GDIPlus_BitmapApplyFilter_Convolution_GaussianBlur _GDIPlus_BitmapApplyFilter_Convolution_IntenseEmboss _GDIPlus_BitmapApplyFilter_Convolution_Kirsch _GDIPlus_BitmapApplyFilter_Convolution_Laplace1 _GDIPlus_BitmapApplyFilter_Convolution_Laplace2 _GDIPlus_BitmapApplyFilter_Convolution_Laplace3 _GDIPlus_BitmapApplyFilter_Convolution_LaplacianOfGaussian _GDIPlus_BitmapApplyFilter_Convolution_ManualMatrix _GDIPlus_BitmapApplyFilter_Convolution_MotionBlur _GDIPlus_BitmapApplyFilter_Convolution_Outline3x3 _GDIPlus_BitmapApplyFilter_Convolution_Prewitt _GDIPlus_BitmapApplyFilter_Convolution_Sharpen1 _GDIPlus_BitmapApplyFilter_Convolution_Sharpen2 _GDIPlus_BitmapApplyFilter_Convolution_Sobel _GDIPlus_BitmapApplyFilter_Convolution_SovelVsPrewitt _GDIPlus_BitmapApplyFilter_Convolution_TriangleBlur _GDIPlus_BitmapApplyFilter_Convolution_Unsharp _GDIPlus_BitmapApplyFilter_Convolution_Unsharp5x5 _GDIPlus_BitmapApplyFilter_Dilatation _GDIPlus_BitmapApplyFilter_DistortionBlur _GDIPlus_BitmapApplyFilter_Edges _GDIPlus_BitmapApplyFilter_Erosion _GDIPlus_BitmapApplyFilter_FishEye _GDIPlus_BitmapApplyFilter_Indexed _GDIPlus_BitmapApplyFilter_Jitter _GDIPlus_BitmapApplyFilter_Kuwahara _GDIPlus_BitmapApplyFilter_Linellism _GDIPlus_BitmapApplyFilter_Median _GDIPlus_BitmapApplyFilter_Median2 _GDIPlus_BitmapApplyFilter_OilPainting _GDIPlus_BitmapApplyFilter_PenSketch _GDIPlus_BitmapApplyFilter_PenSketch2 _GDIPlus_BitmapApplyFilter_Pixelate _GDIPlus_BitmapApplyFilter_Pointillism _GDIPlus_BitmapApplyFilter_RadialBlur _GDIPlus_BitmapApplyFilter_Raster _GDIPlus_BitmapApplyFilter_Swirl _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour _GDIPlus_BitmapApplyFilter_TiltShift _GDIPlus_BitmapApplyFilter_TimeWarp _GDIPlus_BitmapApplyFilter_Wave _GDIPlus_BitmapApplyFilter_XRay  
      Since I am absolutely a newbie in FreeBasic, the DLL may contain errors.  Please report any bug.
       
      FreeBasic source code can be found here: https://pastebin.com/Lugp6rCR
       
      To do:
      add function headers with descriptions speed-up FB code -> partly done add more filters -> ongoing  
      Credits to:
      Jakub Szymanowski rdc Dewald Esterhuizen Santhosh G_  Christian Graus www.gutgames.com  
      Have fun.
       
      Download link: 
       
      You can compare the speed with AutoIt version:
      #AutoIt3Wrapper_Version=b #include <Array.au3> #include <GDIPlus.au3> Global $sFile = FileOpenDialog("Select an image", "", "Images (*.jpg;*.png;*.gif;*.bmp)") If @error Then Exit _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172 Global Const $hImage = _GDIPlus_ImageLoadFromFile($sFile) Global Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Global Const $hGUI = GUICreate("GDI+ Image Filters", $iW * 2, $iH) Global $fProg = 0, $iEnd = $iW * $iH - 1 AdlibRegister("Progress", 490) Global $t = TimerInit() Global Const $hGDIBitmap = _GDIPlus_BitmapApplyFilter_Median($hImage, 4) ConsoleWrite(Round(TimerDiff($t) / 1000, 2) & " s / " & Round(TimerDiff($t) / 60000, 2) & " min" & @CRLF) Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1) Global Const $iPic_o = GUICtrlCreatePic("", $iW, 0, $iW - 1, $iH - 1) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap)) Global Const $hGDIBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_o, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap2)) GUISetState() AdlibUnRegister("Progress") ToolTip("") Do Until GUIGetMsg() = -3 _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hGDIBitmap) _WinAPI_DeleteObject($hGDIBitmap2) _GDIPlus_Shutdown() Exit Func Progress() ToolTip(Int($fProg / $iEnd * 100) & " % / " & Round(TimerDiff($t) / 60000, 2) & " min", MouseGetPos(0) + 30, MouseGetPos(1) + 30) EndFunc #Region Symmetric Nearest Neighbour Func _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour($hImage, $fRadius = 2, $bGDI = True) ;no alpha channel implemented yet Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iRowOffset, $iX, $iY, $c, $k, $sumR, $sumG, $sumB, $iCount, $xx, $yy, $iR, $iG, $iB, $iR1, $iG1, $iB1, $iR2, $iG2, $iB2, $x, $y For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW For $iX = 0 To $iW - 1 $sumR = 0 $sumG = 0 $sumB = 0 $iCount = 0 $c = DllStructGetData($tPixel, 1, $iRowOffset + $iX) $iR = BitShift(BitAND(0x00FF0000, $c), 16) $iG = BitShift(BitAND(0x0000FF00, $c), 8) $iB = BitAND(0x000000FF, $c) For $yy = -$fRadius To $fRadius For $xx = -$fRadius To $fRadius $k = $iX + $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = $iY + $yy $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR1 = BitShift(BitAND(0x00FF0000, $c), 16) $iG1 = BitShift(BitAND(0x0000FF00, $c), 8) $iB1 = BitAND(0x000000FF, $c) $k = $iX - $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = ($iY - $yy) $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR2 = BitShift(BitAND(0x00FF0000, $c), 16) $iG2 = BitShift(BitAND(0x0000FF00, $c), 8) $iB2 = BitAND(0x000000FF, $c) If __DeltaE($iR, $iG, $iB, $iR1, $iG1, $iB1) < __DeltaE($iR, $iG, $iB, $iR2, $iG2, $iB2) Then $sumR += $iR1 $sumG += $iG1 $sumB += $iB1 Else $sumR += $iR2 $sumG += $iG2 $sumB += $iB2 EndIf $iCount += 1 Next Next DllStructSetData($tPixel_Dest, 1, 0xFF000000 + Int($sumR / $iCount) * 0x10000 + Int($sumG / $iCount) * 0x100 + Int($sumB / $iCount), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_SNN" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __DeltaE($iR1, $iG1, $iB1, $iR2, $iG2, $iB2) Return Sqrt(($iR1 - $iR2) * ($iR1 - $iR2) + ($iG1 - $iG2) * ($iG1 - $iG2) + ($iB1 - $iB2) * ($iB1 - $iB2)) EndFunc #EndRegion #Region Jitter Func _GDIPlus_BitmapApplyFilter_Jitter($hImage, $iAmount = 20, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset, $fNX, $fNY For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 $fNX = $iX + Int((Random() - 0.5) * $iAmount) $fNX = $fNX < 1 ? 1 : $fNX > $iW - 1 ? $iW - 1 : $fNX $fNY = ($iY + Int((Random() - 0.5) * $iAmount)) $fNY = $fNY < 1 ? 1 : $fNY > $iH - 1 ? $iH - 1 : $fNY $fNY *= $iW DllStructSetData($tPixel_Dest, 1, DllStructGetData($tPixel, 1, $fNY + $fNX), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Jitter" & $iAmount & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc #EndRegion #Region Median Func _GDIPlus_BitmapApplyFilter_Median($hImage, $fRadius = 3, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 DllStructSetData($tPixel_Dest, 1, __Median_Value($iX, $iY, $fRadius, $tPixel, $iW, $iH), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Median" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __Median_Value($iPosX, $iPosY, $fRadius, $tPixel, $iW, $iH) Local $iX, $iY, $aColors[1000], $iColors = 0, $iSize = $iW * $iH - 1, $iOff, $e For $iX = $iPosX - $fRadius To $iPosX + $fRadius For $iY = $iPosY - $fRadius To $iPosY + $fRadius $iOff = 1 + $iY * $iW + $iX $aColors[$iColors] = DllStructGetData($tPixel, 1, $iOff < 1 ? 1 : $iOff > $iSize ? $iSize : $iOff) $iColors += 1 Next Next ReDim $aColors[$iColors] ;~ _ArraySort($aColors, 0) $e = $iColors - 1 __ArrayQuickSort1D($aColors, 0, $e) Local $iMid = Floor($iColors / 2), $iMedian If BitAND($iColors, 1) Then $iMedian = Int($aColors[$iMid + 1]) Else $iMedian = Int(($aColors[$iMid] + $aColors[$iMid + 1]) / 2) EndIf Return $iMedian EndFunc #EndRegion  
    • InunoTaishou
      By InunoTaishou
      Take a screenshot of your desktop (works even if the desktop is hidden), then redraws it row by row. Makes a neat little effect. An effect I remember seeing at the photo booth at Chuck E' Cheese.
      I mostly just wanted to mess with LockBits and PrintWindow and thought this was a decent way to figure it out, but I liked the outcome and thought I'd share lol
      #include <GDIPlus.au3> #include <WinApi.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() Global $tDesktopMetrics = GetDesktopMetrics() Global $hHBitmapDesktop = CaptureWindow("", -1, -1, -1, -1, "Program Manager") Global $hBitmapDesktop = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmapDesktop) _WinAPI_DeleteObject($hHBitmapDesktop) Global $iW = _GDIPlus_ImageGetWidth($hBitmapDesktop) Global $iH = _GDIPlus_ImageGetHeight($hBitmapDesktop) Global $tBitmapData = _GDIPlus_BitmapLockBits($hBitmapDesktop, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32PARGB) Global $tPixelMap = DllStructCreate("int[" & $iW * $iH & "];", DllStructGetData($tBitmapData, "Scan0")) Global $hGui = GUICreate("Redraw", $iW, $iH, $tDesktopMetrics.x, $tDesktopMetrics.y, $WS_POPUP) Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui) Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Global $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32PARGB) Global $tPixelMap2 = DllStructCreate("int[" & $iW * $iH & "];", DllStructGetData($tBitmapData2, "Scan0")) GUISetState(@SW_SHOW, $hGui) _GDIPlus_GraphicsClear($hGraphics) For $iY = 0 To $iH - 1 Local $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 ;get each pixel in each line and row DllStructSetData($tPixelMap2, 1, DllStructGetData($tPixelMap, 1, $iRowOffset + $iX), $iRowOffset + $iX) Next If (Not Mod($iY, 5)) Then ; Every 5 rows draw the bitmap _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData2) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32PARGB) $tPixelMap2 = DllStructCreate("int[" & $iW * $iH & "];", DllStructGetData($tBitmapData2, "Scan0")) EndIf Next If (Mod($iY, 5)) Then ; Didn't end on an even row, clean up _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData2) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) $tPixelMap2 = 0 $tBitmapData2 = 0 EndIf _GDIPlus_BitmapUnlockBits($hBitmapDesktop, $tBitmapData) _GDIPlus_BitmapDispose($hBitmapDesktop) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() GUIDelete($hGui) Exit 0 Func CaptureWindow($sFileName = "", $iLeft = -1, $iTop = -1, $iWidth = -1, $iHeight = -1, $hWnd = WinGetHandle("[Active]"), $bClientArea = True) If (Not IsHWnd($hWnd)) Then $hWnd = WinGetHandle($hWnd) If (@error) Then Return SetError(1, 0, False) If (BitAND(WinGetState($hWnd), 16) = 16) Then Return SetError(2, 0, False) Local $iSrcWidth = 0 Local $iSrcHeight = 0 ConsoleWrite($iLeft & ', ' & $iTop & ", " & $iWidth & ', ' & $iHeight & @LF) If ($hWnd = _WinAPI_GetDesktopWindow() Or $hWnd = WinGetHandle("Program Manager")) Then Local $tDesktop = GetDesktopMetrics() If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default Or $iWidth > DllStructGetData($tDesktop, 3)) Then $iWidth = DllStructGetData($tDesktop, 3) If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default Or $iWidth > DllStructGetData($tDesktop, 4)) Then $iHeight = DllStructGetData($tDesktop, 4) $iSrcWidth = DllStructGetData($tDesktop, 3) $iSrcHeight = DllStructGetData($tDesktop, 4) Else Local $tRectWindow = _WinAPI_GetWindowRect($hWnd) ; Get the absolute width, using Abs on all of the memembers because the [1] index of the struct may be negative, supports multiple monitors Local $iAbsWidth = Abs(Abs(DllStructGetData($tRectWindow, 3)) - Abs(DllStructGetData($tRectWindow, 1))) ; Get the absolute height, using Abs on all of the memembers because the [1] index of the struct may be negative, supports multiple monitors ; Subtracts the caption bar if $bClientArea only Local $iAbsHeight = Abs(Abs(DllStructGetData($tRectWindow, 4)) - Abs(DllStructGetData($tRectWindow, 2))) - ($bClientArea ? _WinAPI_GetSystemMetrics($SM_CYCAPTION) : 0) If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default Or $iWidth > $iAbsWidth) Then $iWidth = $iAbsWidth If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default Or $iHeight > $iAbsHeight) Then $iHeight = $iAbsHeight $iSrcWidth = $iAbsWidth $iSrcHeight = $iAbsHeight EndIf If ($iLeft = -1 Or $iLeft = Default) Then $iLeft = 0 If ($iTop = -1 Or $iTop = Default) Then $iTop = 0 Local $hDC = _WinAPI_GetWindowDC($hWnd) Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC) Local $hDestBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight) Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hDestBitmap) Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBmp = _WinAPI_CreateCompatibleBitmap($hDC, $iSrcWidth, $iSrcHeight) Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBmp) _WinAPI_PrintWindow($hWnd, $hSrcDC, True) _WinAPI_BitBlt($hDestDC, 0, 0, $iWidth, $iHeight, $hSrcDC, $iLeft, $iTop, $MERGECOPY) _WinAPI_SelectObject($hDestDC, $hDestSv) _WinAPI_SelectObject($hSrcDC, $hSrcSv) _WinAPI_ReleaseDC($hWnd, $hDC) _WinAPI_DeleteDC($hDestDC) _WinAPI_DeleteDC($hSrcDC) _WinAPI_DeleteObject($hBmp) $tPoint = 0 $tRectWindow = 0 $tDesktop = 0 If ($sFileName) Then _GDIPlus_Startup() Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hDestBitmap) _GDIPlus_ImageSaveToFile($hBitmap, $sFileName) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() EndIf Return $hDestBitmap EndFunc ;==>CaptureWindow Func GetDesktopMetrics() Return _GDIPlus_RectFCreate(_WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN), _ _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)) EndFunc ;==>GetDesktopMetrics