SHResourceType shGetResourceType(VGContext *c, VGHandle h) { if (shIsValidPath(c, h)) return SH_RESOURCE_PATH; else if (shIsValidPaint(c, h)) return SH_RESOURCE_PAINT; else if (shIsValidImage(c, h)) return SH_RESOURCE_IMAGE; else return SH_RESOURCE_INVALID; }
VG_API_CALL void vgPaintPattern(VGPaint paint, VGImage pattern) { VG_GETCONTEXT(VG_NO_RETVAL); /* Check if handle valid */ VG_RETURN_ERR_IF(!shIsValidPaint(context, paint), VG_BAD_HANDLE_ERROR, VG_NO_RETVAL); /* Check if pattern image valid */ VG_RETURN_ERR_IF(!shIsValidImage(context, pattern), VG_BAD_HANDLE_ERROR, VG_NO_RETVAL); /* TODO: Check if pattern image is current rendering target */ /* Set pattern image */ ((SHPaint*)paint)->pattern = pattern; VG_RETURN(VG_NO_RETVAL); }
VG_API_CALL void vgDrawImage(VGImage image) { SHImage *i; SHfloat mgl[16]; SHfloat texGenS[4] = {0,0,0,0}; SHfloat texGenT[4] = {0,0,0,0}; SHPaint *fill; SHVector2 min, max; SHRectangle *rect; VG_GETCONTEXT(VG_NO_RETVAL); VG_RETURN_ERR_IF(!shIsValidImage(context, image), VG_BAD_HANDLE_ERROR, VG_NO_RETVAL); /* TODO: check if image is current render target */ /* Check whether scissoring is enabled and scissor rectangle is valid */ if (context->scissoring == VG_TRUE) { rect = &context->scissor.items[0]; if (context->scissor.size == 0) VG_RETURN( VG_NO_RETVAL ); if (rect->w <= 0.0f || rect->h <= 0.0f) VG_RETURN( VG_NO_RETVAL ); glScissor( (GLint)rect->x, (GLint)rect->y, (GLint)rect->w, (GLint)rect->h ); glEnable( GL_SCISSOR_TEST ); } /* Apply image-user-to-surface transformation */ i = (SHImage*)image; shMatrixToGL(&context->imageTransform, mgl); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(mgl); /* Clamp to edge for proper filtering, modulate for multiply mode */ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, i->texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* Adjust antialiasing to settings */ if (context->imageQuality == VG_IMAGE_QUALITY_NONANTIALIASED) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glDisable(GL_MULTISAMPLE); }else{ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glEnable(GL_MULTISAMPLE); } /* Generate image texture coords automatically */ texGenS[0] = 1.0f / i->texwidth; texGenT[1] = 1.0f / i->texheight; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, texGenS); glTexGenfv(GL_T, GL_OBJECT_PLANE, texGenT); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); /* Pick fill paint */ fill = (context->fillPaint ? context->fillPaint : &context->defaultPaint); /* Use paint color when multiplying with a color-paint */ if (context->imageMode == VG_DRAW_IMAGE_MULTIPLY && fill->type == VG_PAINT_TYPE_COLOR) glColor4fv((GLfloat*)&fill->color); else glColor4f(1,1,1,1); /* Check image drawing mode */ if (context->imageMode == VG_DRAW_IMAGE_MULTIPLY && fill->type != VG_PAINT_TYPE_COLOR) { /* Draw image quad into stencil */ glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); glBegin(GL_QUADS); glVertex2i(0, 0); glVertex2i(i->width, 0); glVertex2i(i->width, i->height); glVertex2i(0, i->height); glEnd(); /* Setup blending */ updateBlendingStateGL(context, 0); /* Draw gradient mesh where stencil 1*/ glEnable(GL_TEXTURE_2D); glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); SET2(min,0,0); SET2(max, (SHfloat)i->width, (SHfloat)i->height); if (fill->type == VG_PAINT_TYPE_RADIAL_GRADIENT) { shDrawRadialGradientMesh(fill, &min, &max, VG_FILL_PATH, GL_TEXTURE1); }else if (fill->type == VG_PAINT_TYPE_LINEAR_GRADIENT) { shDrawLinearGradientMesh(fill, &min, &max, VG_FILL_PATH, GL_TEXTURE1); }else if (fill->type == VG_PAINT_TYPE_PATTERN) { shDrawPatternMesh(fill, &min, &max, VG_FILL_PATH, GL_TEXTURE1); } glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); glDisable(GL_STENCIL_TEST); }else if (context->imageMode == VG_DRAW_IMAGE_STENCIL) { }else{/* Either normal mode or multiplying with a color-paint */ /* Setup blending */ updateBlendingStateGL(context, 0); /* Draw textured quad */ glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glVertex2i(0, 0); glVertex2i(i->width, 0); glVertex2i(i->width, i->height); glVertex2i(0, i->height); glEnd(); glDisable(GL_TEXTURE_2D); } glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glPopMatrix(); if (context->scissoring == VG_TRUE) glDisable( GL_SCISSOR_TEST ); VG_RETURN(VG_NO_RETVAL); }