Type C header Revision 2017.3060 Keywords Enterprise, C, CoronaGraphics, plugins See also TextureResourceExternal
CoronaGraphics.h
contains interfaces to interact with the Corona graphics pipeline.
These APIs allow bitmaps loaded from a C plugin to be made displayable in Corona by pushing them to Lua as TextureResourceExternal objects. A bitmap that is wrapped in a Lua TextureResourceExternal object can then be displayed in Corona via APIs that accept image filename
and baseDir
parameters such as the Lua display.newImage(), display.newImageRect(), and graphics.newImageSheet() functions. Textures can also be applied to display objects that have a fill property such as ShapeObjects.
Please see the texture management guide for examples on how to use and manage textures in Corona.
int CoronaExternalPushTexture( lua_State *L, const CoronaExternalTextureCallbacks *callbacks, void* userData )
Creates a new Lua TextureResourceExternal object with the given callbacks and user data, then pushes the newly created texture to the top of the Lua stack. This works similarly to the Lua graphics.newTexture() function except the return texture object wraps a bitmap loaded by the caller and the given callbacks
argument provides an interface for Corona to access this bitmap's information and pixel data.
Will return 1
if the texture object was successfully created and pushed to the top of the Lua stack.
Will return 0
if the function failed to create the texture object and the Lua stack was unchanged. This will happen if given invalid arguments or if the given Lua state does not belong to an actively running Corona runtime.
Note that pushed textures are subject to manual texture management and must be released when no longer needed.
Pointer to the Lua state to push the new TextureResourceExternal object to.
Pointer to a CoronaExternalTextureCallbacks structure providing callbacks for Corona to invoke when requesting the plugin to provide texture information, perform an operation, and other feedback information. All callbacks will receive the userData
value provided to this function. See CoronaExternalTextureCallbacks for more details.
Pointer to user data defined by the caller. This pointer will be passed as an argument to all function callbacks defined in the CoronaExternalTextureCallbacks struct.
void* CoronaExternalGetUserData( lua_State *L, int index )
Retrieves the userData
that was assigned to a Lua TextureResourceExternal object that was created by a call to the CoronaExternalPushTexture() C function. This function is useful when implementing the callback.onGetField()
callback.
Returns the userData
pointer specified when creating the texture with CoronaExternalPushTexture()
or returns NULL
if the given stack index doesn't reference a texture object.
Pointer to the Lua state to access the Lua TextureResourceExternal object from.
int CoronaExternalFormatBPP( CoronaExternalBitmapFormat format )
Helper function which returns the number of bytes-per-pixel that the given bitmap format has. For example, this function will return 4 for a kExternalBitmapFormat_RGBA
format, 3 for a kExternalBitmapFormat_RGB
format, and 1 for a kExternalBitmapFormat_Mask
format.
The pixel format to be queried for how many bytes it has per pixel.
CoronaExternalBitmapFormat
is an enumerated type describing the pixel format of the bitmap. Bitmap channels are
RGBA format uses premultiplied alpha. This means that if the "raw" values of the channels are r
, g
, b
, and a
, the red channel will be r*(a/255)
.
This enum provides the following constants:
kExternalBitmapFormat_Undefined
— Defaults to kExternalBitmapFormat_RGBA
.kExternalBitmapFormat_Mask
— Alpha; 1 byte per pixel. Textures with bitmaps of this format can be used only as masks.kExternalBitmapFormat_RGB
— RGB; 3 bytes per pixel.kExternalBitmapFormat_RGBA
— RGBA; 4 bytes per pixel. RGB channels must be premultiplied with alpha.The width of kExternalBitmapFormat_Mask
and kExternalBitmapFormat_RGB
bitmaps must be a multiple of 4. If the width is not a multiple of 4, the mask will create visual artifacts, and RGB will be treated as RGBA on Windows.
When using kExternalBitmapFormat_RGBA
, the red, green, and blue channels must have premultiplied alpha.
typedef struct CoronaExternalTextureCallbacks { unsigned long size; unsigned int (*getWidth)(void* userData); unsigned int (*getHeight)(void* userData); const void* (*onRequestBitmap)(void* userData); void (*onReleaseBitmap)(void* userData); CoronaExternalBitmapFormat (*getFormat)(void* userData); void (*onFinalize)(void *userData); int (*onGetField)(lua_State *L, const char *field, void* userData); } CoronaExternalTextureCallbacks;
The CoronaExternalTextureCallbacks
structure contains fields which provide information about the texture and callbacks to be invoked by Corona when events occur or when Corona is requesting information about the texture. Textures are managed by Corona and plugins have no control on when the texture is to be released. So, information about a texture's bitmap must be available upon request.
Always initialize an instance of this structure with zeros. Some of the fields are optional and the texture can be created even if they are NULL
. Other fields are required, however, and the texture will not be pushed if they aren't present.
CoronaExternalTextureCallbacks callbacks; memset(&callbacks, 0, sizeof(CoronaExternalTextureCallbacks)) callbacks.size = sizeof(CoronaExternalTextureCallbacks);
When creating an instance of this type, set this member to the number of bytes the CoronaExternalTextureCallbacks
type is. This field is used for identifying the API version.
size = sizeof(CoronaExternalTextureCallbacks);
Callback that will be invoked when Corona is requesting the plugin to provide the bitmap's pixel width. This callback receives the userData
pointer passed when the texture resource was created. Please note that some bitmap formats, such as 8-bit masks, require the width to be a multiple of 4 bytes.
Callback that will be invoked when Corona is requesting the plugin to provide the bitmap's pixel height. This callback receives the userData
pointer passed when the texture resource was created.
Callback that will be invoked by Corona when the bitmap's pixel array has been requested by Corona's rendering system. This function call will always be followed by a call to the onReleaseBitmap
callback. This callback receives the userData
pointer passed when the texture resource was created.
This function must return a valid pointer to the data containing bitmap information. Corona expects bitmap data to be a bpp = CoronaExternalFormatBPP(getFormat())
bytes. Each color channel uses 1 byte and is ordered the same as the format name, left to right. So, with RGBA format, the R index is 0
.
The overall size of memory must be at least...
unsigned int bitmapSizeInBytes = getWidth() * getHeight() * bytesPerPixel;
Accessing the
void* byteArray = onRequestBitmap(); int bytesPerPixel = CoronaExternalFormatBPP(getFormat()); int red = (int)byteArray[((Y * getWidth()) + X) * bytesPerPixel];
Remember that the default format, RGBA, uses premultiplied alpha.
Callback that will be invoked by Corona to notify the plugin that the texture bitmap's data is no longer required. Meaning that the plugin can delete the bitmap data from memory. After this callback is invoked, the pointer previously returned by the onRequestBitmap()
callback is no longer expected to be valid. This callback receives the userData
pointer passed when the texture resource was created.
Callback that will be invoked by Corona when requesting the pixel format of the bitmap. This callback receives the userData
pointer passed when the texture resource was created. This must return a CoronaExternalBitmapFormat
enum constant, such as kExternalBitmapFormat_RGBA
.
Callback that will be invoked by Corona to notify the plugin that the Lua TextureResourceExternal object is about to be destroyed. After this callback is invoked, no callbacks or returned bitmap pointers can be accessed. Essentially, this releases all objects and resources associated with this texture resource. This callback receives the userData
pointer passed when the texture resource was created.
Callback to be invoked when an unknown Lua property has been accessed from the Lua TextureResourceExternal object. This is the plugin's opportunity to provide custom read-only fields from the Lua object. Argument field
provides the name of the property being accessed from the TextureResourceExternal object. Argument userData
is the pointer passed when the texture resource was created. This function must returns the number of values pushed onto the Lua stack.
This example is a hypothetical plugin.texturer
with a single function, newTexture()
, that pushes an image from TPA_
)
luaopen_
function. This is common for all plugins.CORONA_EXPORT int luaopen_plugin_texturer( lua_State *L ) { // Functions in library const luaL_Reg kVTable[] = { { "newTexture", newTexture }, { NULL, NULL } }; luaL_openlib( L, kName, kVTable, 0 ); return 1; }
newTexture()
function which will push images:/** TextureResourceExternal texturer.newTexture(image) */ int newTexture(lua_State* luaStatePointer) { int image = 0; if (lua_type(luaStatePointer, 1) == LUA_TNUMBER) { image = (int)lua_tointeger(luaStatePointer, 1); } else { luaL_argerror( L, 1, "image must be a number") } // creating callbacks structure and initializing it with zeros CoronaExternalTextureCallbacks callbacks = {0}; // setting size callbacks.size = sizeof(CoronaExternalTextureCallbacks); // setting callbacks callbacks.getWidth = getWidth; callbacks.getHeight = getHeight; callbacks.onRequestBitmap = onRequestBitmap; callbacks.onReleaseBitmap = onReleaseBitmap; callbacks.onFinalize = onFinalize; // Creating helper structure HelperStruct* helper = new HelperStruct(); helper->image = image; helper->w = TPA_GetImageWidth(image); //caching width and height helper->h = TPA_GetImageHeight(image); int ret = CoronaExternalPushTexture(L, &callbacks, (image)); // Note that we're not deleting `helper` when everything is OK. It would be released in finalizing callback. if (ret == 0) { // something went wrong. Texture was not pushed, so should clean up to prevent memory leak delete helper; } return ret; }
struct HelperStruct { unsigned w; unsigned h; int image; void *buff; } unsigned getWidth(void* userData) { HelperStruct* self = (HelperStruct*)userData; return self->w; } unsigned getHeight(void* userData) { HelperStruct* self = (HelperStruct*)userData; return self->h; } const void* onRequestBitmap(void* userData) { HelperStruct* self = (HelperStruct*)userData; int sz = self->w*self->h*4; // we know that our API always return 4 byte RGBA self->buff = new unsigned char[sz]; TPA_GetImageRGBA(self->image, self->buff, sz); return self->buff; } void onReleaseBitmap(void* userData) { HelperStruct* self = (HelperStruct*)userData; delete [] self->buff; } void onFinalize(void *userData) { HelperStruct* self = (HelperStruct*)userData; // release helper when texture is no longer required delete self; }
local texturer = require( "plugin.texturer" ) local tex = texturer.newTexture( 42 ) display.newImageRect( tex.filename, tex.baseDir, tex.width, tex.height ) tex:releaseSelf()
When the texture is created, callbacks will not be instantly called. Corona creates textures between frames and only when they're required. Also, after texture:releaseSelf()
is called, texture
is not necessarily released — only this Lua reference is. If any display objects are using the texture, it will not be released, such that they can still be rendered correctly.