Added GLFWimage struct.

This commit is contained in:
Camilla Berglund 2014-02-23 16:43:17 +01:00
parent 608de57358
commit 8fa9cc0de3
8 changed files with 74 additions and 55 deletions

View File

@ -863,6 +863,23 @@ typedef struct GLFWgammaramp
unsigned int size; unsigned int size;
} GLFWgammaramp; } GLFWgammaramp;
/*! @brief Image data.
*
* @ingroup window
*/
typedef struct GLFWimage
{
/*! The width, in pixels, of this image.
*/
int width;
/*! The height, in pixels, of this image.
*/
int height;
/*! The pixel data of this image, arranged left-to-right, top-to-bottom.
*/
unsigned char* pixels;
} GLFWimage;
/************************************************************************* /*************************************************************************
* GLFW API functions * GLFW API functions
@ -1936,13 +1953,9 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
/*! @brief Creates a cursor. /*! @brief Creates a cursor.
* *
* @param[in] width The desired cursor width. * @param[in] image The desired cursor image.
* @param[in] height The desired cursor height.
* @param[in] xhot The desired x-coordinate of the cursor hotspot. * @param[in] xhot The desired x-coordinate of the cursor hotspot.
* @param[in] yhot The desired y-coordinate of the cursor hotspot. * @param[in] yhot The desired y-coordinate of the cursor hotspot.
* @param[in] format Not used.
* @param[in] data The cursor image data in RGBA8 format, packed in rows from
* top to bottom.
* *
* @return A new cursor ready to use or `NULL` if an error occurred. If you * @return A new cursor ready to use or `NULL` if an error occurred. If you
* don't destroy the cursor by calling `glfwDestroyCursor` it will be destroyed * don't destroy the cursor by calling `glfwDestroyCursor` it will be destroyed
@ -1952,7 +1965,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
* *
* @ingroup input * @ingroup input
*/ */
GLFWAPI GLFWcursor* glfwCreateCursor(int width, int height, int xhot, int yhot, int format, const void* data); GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
/*! @brief Destroys a cursor. /*! @brief Destroys a cursor.
* *

View File

@ -1201,37 +1201,38 @@ void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
CGAssociateMouseAndMouseCursorPosition(true); CGAssociateMouseAndMouseCursorPosition(true);
} }
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int width, int height, int xhot, int yhot, int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int format, const void* data) const GLFWimage* image,
int xhot, int yhot)
{ {
NSImage* image; NSImage* native;
NSBitmapImageRep* rep; NSBitmapImageRep* rep;
rep = [[NSBitmapImageRep alloc] rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL initWithBitmapDataPlanes:NULL
pixelsWide:width pixelsWide:image->width
pixelsHigh:height pixelsHigh:image->height
bitsPerSample:8 bitsPerSample:8
samplesPerPixel:4 samplesPerPixel:4
hasAlpha:YES hasAlpha:YES
isPlanar:NO isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
bytesPerRow:width * 4 bytesPerRow:image->width * 4
bitsPerPixel:32]; bitsPerPixel:32];
if (rep == nil) if (rep == nil)
return GL_FALSE; return GL_FALSE;
memcpy([rep bitmapData], data, width * height * 4); memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);
image = [[NSImage alloc] initWithSize:NSMakeSize(width, height)]; native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)];
[image addRepresentation: rep]; [native addRepresentation: rep];
cursor->ns.object = [[NSCursor alloc] initWithImage:image cursor->ns.object = [[NSCursor alloc] initWithImage:native
hotSpot:NSMakePoint(xhot, yhot)]; hotSpot:NSMakePoint(xhot, yhot)];
[image release]; [native release];
[rep release]; [rep release];
if (cursor->ns.object == nil) if (cursor->ns.object == nil)

View File

@ -353,8 +353,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
_glfwPlatformSetCursorPos(window, xpos, ypos); _glfwPlatformSetCursorPos(window, xpos, ypos);
} }
GLFWAPI GLFWcursor* glfwCreateCursor(int width, int height, int xhot, int yhot, GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
int format, const void* data)
{ {
_GLFWcursor* cursor; _GLFWcursor* cursor;
@ -364,7 +363,7 @@ GLFWAPI GLFWcursor* glfwCreateCursor(int width, int height, int xhot, int yhot,
cursor->next = _glfw.cursorListHead; cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor; _glfw.cursorListHead = cursor;
if (!_glfwPlatformCreateCursor(cursor, width, height, xhot, yhot, format, data)) if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot))
{ {
glfwDestroyCursor((GLFWcursor*) cursor); glfwDestroyCursor((GLFWcursor*) cursor);
return NULL; return NULL;

View File

@ -588,8 +588,7 @@ int _glfwPlatformExtensionSupported(const char* extension);
*/ */
GLFWglproc _glfwPlatformGetProcAddress(const char* procname); GLFWglproc _glfwPlatformGetProcAddress(const char* procname);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int width, int height, int xhot, int yhot, int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
int format, const void* data);
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);

View File

@ -1223,21 +1223,22 @@ void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
} }
} }
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int width, int height, int xhot, int yhot, int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int format, const void* data) const GLFWimage* image,
int xhot, int yhot)
{ {
HDC dc; HDC dc;
HBITMAP bitmap, mask; HBITMAP bitmap, mask;
BITMAPV5HEADER bi; BITMAPV5HEADER bi;
ICONINFO ii; ICONINFO ii;
DWORD* target = 0; DWORD* target = 0;
BYTE* source = (BYTE*) data; BYTE* source = (BYTE*) image->pixels;
int i; int i;
ZeroMemory(&bi, sizeof(bi)); ZeroMemory(&bi, sizeof(bi));
bi.bV5Size = sizeof(BITMAPV5HEADER); bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = width; bi.bV5Width = image->width;
bi.bV5Height = -height; bi.bV5Height = -image->height;
bi.bV5Planes = 1; bi.bV5Planes = 1;
bi.bV5BitCount = 32; bi.bV5BitCount = 32;
bi.bV5Compression = BI_BITFIELDS; bi.bV5Compression = BI_BITFIELDS;
@ -1254,14 +1255,14 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int width, int height, int xh
if (!bitmap) if (!bitmap)
return GL_FALSE; return GL_FALSE;
mask = CreateBitmap(width, height, 1, 1, NULL); mask = CreateBitmap(image->width, image->height, 1, 1, NULL);
if (!mask) if (!mask)
{ {
DeleteObject(bitmap); DeleteObject(bitmap);
return GL_FALSE; return GL_FALSE;
} }
for (i = 0; i < width * height; i++, target++, source += 4) for (i = 0; i < image->width * image->height; i++, target++, source += 4)
*target = (source[3] << 24) | (source[0] << 16) | (source[1] << 8) | source[2]; *target = (source[3] << 24) | (source[0] << 16) | (source[1] << 8) | source[2];
ZeroMemory(&ii, sizeof(ii)); ZeroMemory(&ii, sizeof(ii));

View File

@ -1356,22 +1356,23 @@ void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
} }
} }
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int width, int height, int xhot, int yhot, int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int format, const void* data) const GLFWimage* image,
int xhot, int yhot)
{ {
int i; int i;
XcursorImage* native = XcursorImageCreate(width, height); XcursorImage* native = XcursorImageCreate(image->width, image->height);
if (native == NULL) if (native == NULL)
return GL_FALSE; return GL_FALSE;
native->xhot = xhot; native->xhot = xhot;
native->yhot = yhot; native->yhot = yhot;
unsigned char* source = (unsigned char*) data; unsigned char* source = (unsigned char*) image->pixels;
XcursorPixel* target = native->pixels; XcursorPixel* target = native->pixels;
for (i = 0; i < width * height; i++, target++, source += 4) for (i = 0; i < image->width * image->height; i++, target++, source += 4)
*target = (source[3] << 24) | (source[0] << 16) | (source[1] << 8) | source[2]; *target = (source[3] << 24) | (source[0] << 16) | (source[1] << 8) | source[2];
cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, native); cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, native);

View File

@ -88,29 +88,33 @@ static void command_callback(int key)
case GLFW_KEY_C: case GLFW_KEY_C:
{ {
if (cursor == NULL) int x, y;
GLFWimage image;
unsigned char* pixels;
if (cursor)
break;
image.width = cursorSize[currentSize].w;
image.height = cursorSize[currentSize].h;
pixels = malloc(4 * image.width * image.height);
image.pixels = pixels;
for (y = 0; y < image.height; y++)
{ {
int w = cursorSize[currentSize].w; for (x = 0; x < image.width; x++)
int h = cursorSize[currentSize].h;
int x, y, i = 0;
unsigned char *image = malloc(4 * w * h);
for (y = 0; y < h; y++)
{ {
for (x = 0; x < w; x++) *pixels++ = 0xff;
{ *pixels++ = 0;
image[i++] = 0xff; *pixels++ = 255 * y / image.height;
image[i++] = 0; *pixels++ = 255 * x / image.width;
image[i++] = 255 * y / h;
image[i++] = 255 * x / w;
}
} }
cursor = glfwCreateCursor(w, h, w / 2, h / 2, 0, image);
currentSize = (currentSize + 1) % SizeCount;
free(image);
} }
cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2);
currentSize = (currentSize + 1) % SizeCount;
free(image.pixels);
break; break;
} }

View File

@ -66,10 +66,11 @@ static float star(int x, int y, float t)
static GLFWcursor* load_frame(float t) static GLFWcursor* load_frame(float t)
{ {
int i = 0, x, y; int i = 0, x, y;
const GLFWimage image = { SIZE, SIZE, buffer };
for (y = 0; y < SIZE; y++) for (y = 0; y < image.width; y++)
{ {
for (x = 0; x < SIZE; x++) for (x = 0; x < image.height; x++)
{ {
buffer[i++] = 255; buffer[i++] = 255;
buffer[i++] = 255; buffer[i++] = 255;
@ -78,7 +79,7 @@ static GLFWcursor* load_frame(float t)
} }
} }
return glfwCreateCursor(SIZE, SIZE, SIZE / 2, SIZE / 2, 0, buffer); return glfwCreateCursor(&image, image.width / 2, image.height / 2);
} }
int main(void) int main(void)