Hi Ivo,
Thank you for your reply !!
“If all you’re doing is rotating, you should be doing that by doing a vgRotate() on the VG_MATRIX_IMAGE_USER_TO_SURFACE matrix.”
I am rotating the bmp images by vgRotate() using VG_MATRIX_PATH_USER_TO_SURFACE, not VG_MATRIX_IMAGE_USER_TO_SURFACE. It’s just because the sample code I am referring for rotation uses VG_MATRIX_PATH_USER_TO_SURFACE.
“If you want to use the image as a texture paint, you should be able to use use the VG_MATRIX_FILL_PAINT_TO_USER and/or VG_MATRIX_STROKE_PAINT_TO_USER matrices to do the rotation.”
I have not used those matrices, but I feel I should try them for images.
I have attached the code I am working on. It basically creates a rectangular path (512x512 square), fills the path with image data, and rotates current matrix. Can you please have a look the code ?
Thanks.
john
#include “OVGTools.h”
#include “PVRShell.h”
#include “vg/openvg.h”
#include “GLES/egl.h”
#define PVRTRGBA(r, g, b, a) ((VGuint) ((® << 24) | ((g) << 16) | ((b) << 8) | (a)))
#define IMG_WIDTH 512
#define IMG_HEIGHT 512
class Image {
public:
Image(char* ps, int w, int h);
~Image();
char* pixels;
int width;
int height;
};
Image::Image(char* ps, int w, int h) : pixels(ps), width(w), height(h) {
}
Image::~Image() {
delete[] pixels;
}
class CPatternFill : public PVRShell
{
private:
VGPath m_vgPath;
VGPaint m_vgImagePaint;
VGImage m_vgImage;
CPVRTPrintVG m_PrintVG;
unsigned int m_ui32AbsTime;
unsigned int fnum;
Image *image;
public:
CPatternFill() {}
/* PVRShell functions */
virtual bool InitApplication();
virtual bool InitView();
virtual bool ReleaseView();
virtual bool QuitApplication();
virtual bool RenderScene();
/****************************************************************************
** Function Definitions
****************************************************************************/
void CreatePath();
void CreatePaints();
};
void CPatternFill::CreatePath()
{
/*
Create the shape to pattern fill
*/
static VGubyte aui8PathSegments[] = { //commands for path
VG_MOVE_TO_ABS,
VG_VLINE_TO_REL,
VG_HLINE_TO_REL,
VG_VLINE_TO_REL,
VG_CLOSE_PATH
};
static VGfloat afPathCoords[] = { //data for path
0.0f, 0.0f,
512.0f, //0.21f,
512.0f, //0.21f,
-512.0f,
};
// Create a path handle...
m_vgPath = vgCreatePath(
VG_PATH_FORMAT_STANDARD,
VG_PATH_DATATYPE_F,
1.0f, 0.0f,
5,
5,
VG_PATH_CAPABILITY_APPEND_TO);
// ... and populate it with data
vgAppendPathData(m_vgPath, 5, aui8PathSegments, afPathCoords);
}
void CPatternFill::CreatePaints()
{
int pel;
//Create the image we are going to use as the pattern
m_vgImage = vgCreateImage(VG_sRGBX_8888, IMG_WIDTH, IMG_HEIGHT, VG_IMAGE_QUALITY_NONANTIALIASED);
VGuint* pui32ImgData = new VGuint[IMG_WIDTH * IMG_HEIGHT];
/* load bmp image */
image = loadBMP("lilies512x512.bmp");
for (int i = 0; i < image->height; ++i)
{
pel = i*image->width;
for (int j = 0; j < image->width; ++j)
{
pui32ImgData[pel+j] = PVRTRGBA(image->pixels[3*(pel+j)],image->pixels[3*(pel+j)+1],image->pixels[3*(pel+j)+2],255);
}
}
delete image;
vgImageSubData(m_vgImage,pui32ImgData, sizeof(VGuint) * image->width,VG_sRGBX_8888, 0, 0, image->width, image->height);
// Delete the image data as it is now in OpenVG memory
delete[] pui32ImgData;
pui32ImgData = 0;
// Create a paint
m_vgImagePaint = vgCreatePaint();
// Set its type to pattern
vgSetParameteri(m_vgImagePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN);
//Set the image for the paint to use as a pattern
vgPaintPattern(m_vgImagePaint, m_vgImage);
//Set the tiling mode of the pattern. In this case it is set to repeat endlessly
vgSetParameteri(m_vgImagePaint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_REPEAT);
}
bool CPatternFill::InitApplication()
{
// This sets up PVRShell to use an OpenVG context
PVRShellSet(prefOpenVGContext, true);
return true;
}
bool CPatternFill::QuitApplication()
{
PVRShellOutputDebug("leaving...");
return true;
}
bool CPatternFill::InitView()
{
m_ui32AbsTime = 0;
fnum = 0;
//Create the path
CreatePath();
//Create the paints
CreatePaints();
//Set the clear colour
VGfloat afClearColour[] = { 0.6f, 0.8f, 1.0f, 1.0f };
vgSetfv(VG_CLEAR_COLOR, 4, afClearColour);
m_PrintVG.Initialize(PVRShellGet(prefWidth), PVRShellGet(prefHeight));
return true;
}
bool CPatternFill::ReleaseView()
{
//destroy the path
vgDestroyPath(m_vgPath);
//destroy the paint
vgDestroyPaint(m_vgImagePaint);
//destroy the image
vgDestroyImage(m_vgImage);
m_PrintVG.Terminate();
return true;
}
bool CPatternFill::RenderScene()
{
int pel2;
m_ui32AbsTime += 12;
/*** I added belows to load new bmp image every time ***/
/*** (actually it's same image in this test) ***/
if(fnum > 0) {
VGuint* pui32ImgData = new VGuint[IMG_WIDTH * IMG_HEIGHT];
/* load new bmp image */
image = loadBMP("lilies512x512.bmp");
for (int i = 0; i < image->height; ++i)
{
pel2 = i*image->width;
for (int j = 0; j < image->width; ++j)
{
pui32ImgData[pel2+j] = PVRTRGBA(image->pixels[3*(pel2+j)],image->pixels[3*(pel2+j)+1],image->pixels[3*(pel2+j)+2],255);
}
}
delete image;
vgImageSubData(m_vgImage,pui32ImgData, sizeof(VGuint) * image->width,VG_sRGBX_8888, 0, 0, image->width, image->height);
// Delete the image data as it is now in OpenVG memory
delete[] pui32ImgData;
pui32ImgData = 0;
}
/****************************************/
// Clear the screen with the clear colour.
vgClear(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
// Switch the matrix mode to VG_MATRIX_PATH_USER_TO_SURFACE
vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
vgLoadIdentity();
// Set the paint you would like to fill the shape with
vgSetPaint(m_vgImagePaint, VG_FILL_PATH);
/*** I added belows to rotate current bmp image ***/
float afUnitMatrix[3*3];
vgGetMatrix(afUnitMatrix);
float fRotationAngle = m_ui32AbsTime;
vgTranslate((VGfloat)(IMG_WIDTH/2), (VGfloat)(IMG_HEIGHT/2));
vgRotate(fRotationAngle); // rotate curr Matrix by angle.
vgTranslate(-(VGfloat)(IMG_WIDTH/2), -(VGfloat)(IMG_HEIGHT/2));
/**************************/
// Draw the path with stroke and fill
vgDrawPath(m_vgPath, VG_STROKE_PATH | VG_FILL_PATH);
m_PrintVG.DisplayDefaultTitle("PatternFill+Rotate", "", ePVRTPrint3DLogoIMG);
return true;
}