| 09-18-2009, 06:26 PM | #1 |
Well, purpose of this library: - add the IMAGE_TYPEs Blizzard forgot to add. - provide an object oriented wrapper for images + some additional features, like reading certain properties of the image Images are an interesting type. I recently published a documentation of that type, which is also the basis for large parts of this script. This library uses vJass (JassHelper 0.9.H.0 and up) and ARGB. ImageUtils:// ************************************************************* // * ImageUtils // * by Deaod // ************************************************************* // * // * CREDITS: // * - Vexorian (JassHelper, ARGB) // * - MindWorX and PitzerMike (JassNewGenPack) // * - Pipedream (Grimoire) // * - SFilip (TESH) // * // * HOW TO IMPORT: // * * C'n'P the code into your map // * * If you haven't done that already, import ARGB into your map // * // * HOW TO USE: // * * this library provides you with wrappers for CreateImage and DestroyImage (NewImage and ReleaseImage respectively). // * Those are necessary to work around creating invalid images. They also catch attempts to destroy images created by WC3 itself // * (although thats rather conditional, you need to use NewImage and ReleaseImage correctly for it to work). // * CreateImageEx also exists (for backwards compatibility), but is deprecated. // * // * This library also comes with an object oriented wrapper for images, heres how to use those: // * // * * declare a variable of type imagex // * // * * use imagex.create(string path, real sizeX, real sizeY, real posX, real posY, real posZ, boolean show) to create a new image // * - path is the path to the imagefile that you want to display // * - sizeX and sizeY are the dimensions of the image displayed in standard WC3 units of length // * - posX, posY and posZ specifiy the position where the image is created. // * Note that this point is the lower left corner of the image. // * // * * you can change the path of the image youre displaying by setting the path member of an instance of the imagex struct. // * Example: set yourimage.path="Path\\To\\The\\Image.blp" // * // * * you can change the size of the image by setting the sizeX and sizeY member of an instance of the imagex struct. // * Example: set yourimage.sizeX=64. // * set yourimage.sizeY=64. // * Theres also a method combining those two: yourimage.setSize(real sizex, real sizey) // * Example: call yourimage.setSize(64., 64.) // * Sizes work like describen in the create method. // * // * * you can change the position of the image by setting the X, Y and Z members of an instance of the imagex struct. // * Example: set yourimage.X=128. // * set yourimage.Y=128. // * set yourimage.Z=0. // * Theres also a method combining those three: yourimage.setPosition(real x, real y, real z) // * Example: call yourimage.setPosition(128.,128.,0.) // * The point specified is the lower left corner of the image. // * // * * you can access the individual values of the red, green, blue and alpha channels of the current color of the image // * with the red, green, blue and alpha members of an instance of the imagex struct. // * Example: set red = yourimage.red // * set green = yourimage.green // * set blue = yourimage.blue // * set alpha = yourimage.alpha // * I planned adding a way to change the value of the individual color channels, // * but unfortunately i cant due to a limitation in JassHelper. // * // * * you can change the color of the image by setting the color member of an instance of the imagex struct. // * Example: set yourimage.color=ARGB(0xFF808080) // * Refer to ARGBs manual for more information on what is a valid ARGB instance. // * // * * you can decide whether to display the image or not by setting the show member of an instance of the imagex struct. // * Example: set yourimage.show=true // * true displays the image, false hides it. // * // * * you can make the image wrap to the ground by setting the wrap member of an instance of the imagex struct. // * Example: set yourimage.wrap=true // * true makes the image wrap to the ground, but makes the image ignore its Z position. // * false allows you to change the Z position of the image freely. // * Defaults to false for new instances. // * // * * you can change the type of an image by setting the type member of an instance of the imagex struct. // * Example: set yourimage.type=IMAGE_TYPE_INDICATOR // * A list of all known image types can be found below. // * Note that not every image type known works, and that image types influence // * the order in which images are stacked on top of each other. // * // * NOTE: although i have only shown examples for changing the value of members, // * its also possible to read them, unless stated otherwise. // * // * * to destroy an image use yourimage.destroy() // * // ************************************************************* library ImageUtils requires ARGB globals private constant integer MAX_IMAGES = 8190 // Doesnt get rendered // using this type in CreateImage returns an invalid image (id of -1) constant integer IMAGE_TYPE_SHADOW = 0 // Gets drawn above fog of war constant integer IMAGE_TYPE_SELECTION = 1 // Gets drawn above fog of war constant integer IMAGE_TYPE_INDICATOR = 2 // Gets drawn above fog of war constant integer IMAGE_TYPE_OCCLUSION_MASK = 3 // Gets tinted based on time of day ingame. // Gets drawn below fog of war constant integer IMAGE_TYPE_UBERSPLAT = 4 // Doesnt get rendered constant integer IMAGE_TYPE_TOPMOST = 5 private constant integer DEFAULT_IMAGE_TYPE = IMAGE_TYPE_INDICATOR private ARGB DEFAULT_COLOR = 0xFFFFFFFF private constant integer INVALID_IMAGE_ID = -1 // go complain about that at Blizzard, // i have nothing to do with that endglobals globals private boolean array ImageValid[MAX_IMAGES] endglobals function NewImage takes string path, real sizex, real sizey, real sizez, real posx, real posy, real posz, real offx, real offy, real offz, integer imagetype returns image local image i=CreateImage(path, sizex, sizey, sizez, posx, posy, posz, offx, offy, offz, imagetype) local integer id=GetHandleId(i) if id<0 then debug call BJDebugMsg("NewImage: Invalid imagepath!") return null elseif id>=MAX_IMAGES then debug call BJDebugMsg("NewImage: Exceeded Maximum Images!") return i endif set ImageValid[id]=true return i endfunction function CreateImageEx takes string path, real sizex, real sizey, real sizez, real posx, real posy, real posz, real offx, real offy, real offz, integer imagetype returns image debug call BJDebugMsg("CreateImageEx: Use NewImage instead, CreateImageEx is deprecated!") return NewImage(path, sizex, sizey, sizez, posx, posy, posz, offx, offy, offz, imagetype) endfunction function ReleaseImage takes image i returns nothing local integer id=GetHandleId(i) if id>=MAX_IMAGES then call DestroyImage(i) elseif id>0 and ImageValid[id] then call DestroyImage(i) set ImageValid[id]=false debug elseif id>0 then debug call BJDebugMsg("ReleaseImage: Double free of image "+I2S(id)+".") debug else debug call BJDebugMsg("ReleaseImage: Trying to free invalid image.") endif endfunction struct imagex[MAX_IMAGES] private image img private string Path private real SizeX private real SizeY private real X private real Y private real Z private ARGB Color private boolean Show private boolean Wrap private integer Type // Get Methods method operator path takes nothing returns string return .Path endmethod method operator sizeX takes nothing returns real return .SizeX endmethod method operator sizeY takes nothing returns real return .SizeY endmethod method operator x takes nothing returns real return .X endmethod method operator y takes nothing returns real return .Y endmethod method operator z takes nothing returns real return .Z endmethod method operator red takes nothing returns integer return .Color.red endmethod method operator green takes nothing returns integer return .Color.green endmethod method operator blue takes nothing returns integer return .Color.blue endmethod method operator alpha takes nothing returns integer return .Color.alpha endmethod method operator color takes nothing returns ARGB return .Color endmethod method operator show takes nothing returns boolean return .Show endmethod method operator wrap takes nothing returns boolean return not .Wrap endmethod method operator type takes nothing returns integer return .Type endmethod // Private Proxies private method NewPosition takes nothing returns nothing call SetImagePosition(.img, .x, .y, 0) endmethod private method NewZPos takes real z returns nothing call SetImageConstantHeight(.img, .wrap, z) endmethod private method Recolor takes nothing returns nothing call SetImageColor(.img, .red, .green, .blue, .alpha) endmethod private method Recreate takes nothing returns nothing if .img!=null then call ReleaseImage(.img) // never destroy null images, if you dont want hell unleashed endif set .img=NewImage(.path, .sizeX, .sizeY, 0, .x, .y, 0, 0, 0, 0, .type) call .NewZPos(.z) call .Recolor() call SetImageRenderAlways(.img, .show) endmethod // Set Methods // Set the image's filepath method operator path= takes string path returns nothing set .Path=path call .Recreate() endmethod // Set the size of the image method operator sizeX= takes real sizex returns nothing set .SizeX=sizex call .Recreate() endmethod method operator sizeY= takes real sizey returns nothing set .SizeY=sizey call .Recreate() endmethod method setSize takes real sizex, real sizey returns nothing set .SizeX=sizex set .SizeY=sizey call .Recreate() endmethod // Set the position of the image method operator x= takes real x returns nothing set .X=x call .NewPosition() endmethod method operator y= takes real y returns nothing set .Y=y call .NewPosition() endmethod method operator z= takes real z returns nothing set .Z=z call .NewZPos(z) endmethod method setPosition takes real x, real y, real z returns nothing set .X=x set .Y=y set .Z=z call .NewPosition() call .NewZPos(z) endmethod // Set the color of the image // due to a limtation in JassHelper, only the operator color= works /*method operator red= takes integer red returns nothing set .Color.red=red call .Recolor() endmethod method operator green= takes integer green returns nothing set .Color.green=green call .Recolor() endmethod method operator blue= takes integer blue returns nothing set .Color.blue=blue call .Recolor() endmethod method operator alpha= takes integer alpha returns nothing set .Color.alpha=alpha call .Recolor() endmethod*/ method operator color= takes ARGB new returns nothing set .Color=new call .Recolor() endmethod // Do you want to display the image? method operator show= takes boolean show returns nothing set .Show=show call SetImageRenderAlways(.img, .show) endmethod method operator wrap= takes boolean wrap returns nothing set .Wrap=not wrap call .NewZPos(.z) endmethod // On which layer should the image be rendered? method operator type= takes integer imageType returns nothing set .Type=imageType call SetImageType(.img, imageType) endmethod // constructor and destructor static method create takes string path, real sizeX, real sizeY, real posX, real posY, real posZ, boolean show returns thistype local thistype s=.allocate() set s.Path=path set s.SizeX=sizeX set s.SizeY=sizeY set s.X=posX set s.Y=posY set s.Z=posZ set s.Show=show set s.Wrap=false set s.Type=DEFAULT_IMAGE_TYPE set s.Color=DEFAULT_COLOR call s.Recreate() return s endmethod method onDestroy takes nothing returns nothing if .img!=null then call ReleaseImage(.img) endif set .img=null endmethod private static method onInit takes nothing returns nothing if GetHandleId(CreateImage("ReplaceableTextures\\CommandButtons\\BTNSlowOn.blp", 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)) != null then debug call BJDebugMsg("ImageUtils: image(null) already allocated, there might be errors") endif endmethod endstruct endlibrary EDIT 1: Updated ImageUtils to incorporate the result of my research. Attached a map demonstrating use of ImageUtils in the context of a TextSplat library. EDIT 2: Added a documentation. If you still need something explained, feel free to ask. EDIT 3: Made the link to my research more visible. EDIT 4: Fixed two bugs. EDIT 5: Now supports wrapping to the ground. Fixed documentation errors. EDIT 6: Updated with workarounds to the newfound bug. As a result, CreateImageEx was added. Refer to the documentation for more information. EDIT 7: Deprecated CreateImageEx in favour of NewImage/ReleaseImage. Now also tries to work around the most common errors with images (and reports those to the user). EDIT 8: Fixed imagex instances causing errors. |
| 09-18-2009, 06:34 PM | #2 |
JASS:constant integer IMAGE_TYPE_SHADOW = 0 // unit shadows? // Doesnt get rendered constant integer IMAGE_TYPE_SELECTION = 1 // selection circles? // Gets drawn above fog of war constant integer IMAGE_TYPE_INDICATOR = 2 // AoE indicators? // Gets drawn above fog of war constant integer IMAGE_TYPE_OCCLUSION_MASK = 3 // fog of war? // Gets drawn above fog of war constant integer IMAGE_TYPE_UBERSPLAT = 4 // unit footsteps? // Gets tinted based on time of day ingame. // Gets drawn above fog of war constant integer IMAGE_TYPE_TOPMOST JASS:call BJDebugMsg("ImageUtils: Invalid imagepath!") Oh, and put the "ImageUtils" library on top of the example, and have both of them use [hiddenjass][/hiddenjass] tags around them. You will also need better documentation. By a lot. Also, I am calling forth the necessity of a demo map for this library. I refuse to let it get approved without one that shows all of the working image types, how they stack on each other, and gives some examples of how they work when you change their values and such. |
| 09-22-2009, 10:35 PM | #3 |
Updated. |
| 09-23-2009, 01:45 PM | #4 | |
Quote:
JASS:// Credits: // - Vexorian for ARGB and JassHelper // - Pipedream for grimoire // - MindWorX and Pitzermike for JassNewGenPack // - SFilip for TESH |
| 10-08-2009, 02:31 PM | #5 |
Please do something about your documentation so I can approve this. |
| 10-16-2009, 12:01 PM | #6 |
Is that enough documentation now? |
| 10-16-2009, 01:44 PM | #7 |
I think it's enough, but I suggest having the URL for your Image Tutorial in the documentation too for further reading if the user is interested. |
| 10-16-2009, 02:49 PM | #8 |
Link was already there, but anyway, updated. |
| 10-16-2009, 03:20 PM | #9 |
Oh? I guess I missed it when I read it, weird. Oh well, approved. |
| 11-08-2009, 04:25 AM | #10 |
updated. |
| 11-15-2009, 10:21 PM | #11 |
Aaaaand, updated. |
| 11-26-2009, 12:37 AM | #12 |
It's annoying that the position is always the lower left corner of the image. You can fix that 'flaw' with simple math. Could you please do that? |
| 11-26-2009, 02:37 PM | #13 |
I wont "fix" that, mostly because i already have two other libraries depending on it. Also, its rather trivial to fix this on your side (or even incorporate it). Edit: That aside, where would you want me to move the origin to? |
| 11-26-2009, 02:51 PM | #14 |
It could be in the middle of the image, so when modifying its size over time, you dont have to move your image alla time. See for example those images that appear in the ground when you use burrow/unborrow spell with those undead nerubian units. |
| 11-26-2009, 03:24 PM | #15 |
The origin being the center does make the most sense, for what it's worth. |
