from ketmar: more small fixes: slightly better image API, some documentation clarifications

This commit is contained in:
Adam D. Ruppe 2018-02-27 11:25:45 -05:00
parent 548cfe06d1
commit 8b6835218d
1 changed files with 36 additions and 19 deletions

View File

@ -210,7 +210,10 @@ The following code illustrates the OpenGL state touched by the rendering code:
NanoVega allows you to load image files in various formats (if arsd loaders are in place) to be used for rendering.
In addition you can upload your own image.
The parameter imageFlags is combination of flags defined in NVGImageFlags.
The parameter imageFlags is combination of flags defined in [NVGImageFlag].
If you will use your image as fill pattern, it will be scaled by default. To make it repeat, pass
[NVGImageFlag.RepeatX] and [NVGImageFlag.RepeatY] flags to image creation function respectively.
paints =
## Paints
@ -265,6 +268,10 @@ The following code illustrates the OpenGL state touched by the rendering code:
## Text
NanoVega allows you to load .ttf files and use the font to render text.
You have to load some font, and set proper font size before doing anything
with text, as there is no "default" font provided by NanoVega. Also, don't
forget to check return value of `createFont()`, 'cause NanoVega won't fail
if it cannot load font, it will silently try to render nothing.
The appearance of the text can be defined by setting the current text style
and by specifying the fill color. Common text and font settings such as
@ -290,7 +297,7 @@ The following code illustrates the OpenGL state touched by the rendering code:
string txt = "Text me up.";
vg.textBounds(x, y, txt, bounds);
vg.beginPath();
vg.roundedRect(bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]);
vg.roundedRect(bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1], 6);
vg.fill();
----------------------
@ -997,7 +1004,7 @@ public struct NVGTextRow(CT) if (isAnyCharType!CT) {
/// Image creation flags.
/// Group: images
public enum NVGImageFlags : uint {
public enum NVGImageFlag : uint {
None = 0, /// Nothing special.
GenerateMipmaps = 1<<0, /// Generate mipmaps during creation of the image.
RepeatX = 1<<1, /// Repeat image in X direction.
@ -1008,6 +1015,8 @@ public enum NVGImageFlags : uint {
Nearest = NoFiltering, /// compatibility with original NanoVG
}
alias NVGImageFlags = NVGImageFlag; /// Backwards compatibility for [NVGImageFlag].
// ////////////////////////////////////////////////////////////////////////// //
package/*(arsd)*/:
@ -1464,7 +1473,7 @@ package/*(arsd)*/ NVGContext createInternal (NVGparams* params) nothrow @trusted
if (ctx.fs is null) goto error;
// create font texture
ctx.fontImages[0] = ctx.params.renderCreateTexture(ctx.params.userPtr, NVGtexture.Alpha, fontParams.width, fontParams.height, (ctx.params.fontAA ? 0 : NVGImageFlags.NoFiltering), null);
ctx.fontImages[0] = ctx.params.renderCreateTexture(ctx.params.userPtr, NVGtexture.Alpha, fontParams.width, fontParams.height, (ctx.params.fontAA ? 0 : NVGImageFlag.NoFiltering), null);
if (ctx.fontImages[0] == 0) goto error;
ctx.fontImageIdx = 0;
@ -2684,7 +2693,9 @@ public void scale (NVGContext ctx, in float x, in float y) nothrow @trusted @nog
/// Creates image by loading it from the disk from specified file name.
/// Returns handle to the image or 0 on error.
/// Group: images
public int createImage() (NVGContext ctx, const(char)[] filename, int imageFlags=NVGImageFlags.None) {
public int createImage() (NVGContext ctx, const(char)[] filename, const(/*NVGImageFlag*/uint)[] imageFlagsList...) {
uint imageFlags = 0;
foreach (immutable uint flag; imageFlagsList) imageFlags |= flag;
static if (NanoVegaHasArsdImage) {
import arsd.image;
// do we have new arsd API to load images?
@ -2725,8 +2736,10 @@ static if (NanoVegaHasArsdImage) {
/// Creates image by loading it from the specified memory image.
/// Returns handle to the image or 0 on error.
/// Group: images
public int createImageFromMemoryImage() (NVGContext ctx, MemoryImage img, int imageFlags=NVGImageFlags.None) {
public int createImageFromMemoryImage() (NVGContext ctx, MemoryImage img, const(/*NVGImageFlag*/uint)[] imageFlagsList...) {
if (img is null) return 0;
uint imageFlags = 0;
foreach (immutable uint flag; imageFlagsList) imageFlags |= flag;
if (auto tc = cast(TrueColorImage)img) {
return ctx.createImageRGBA(tc.width, tc.height, tc.imageData.bytes[], imageFlags);
} else {
@ -2739,13 +2752,15 @@ static if (NanoVegaHasArsdImage) {
/// Creates image by loading it from the specified chunk of memory.
/// Returns handle to the image or 0 on error.
/// Group: images
public int createImageMem() (NVGContext ctx, const(ubyte)* data, int ndata, int imageFlags=NVGImageFlags.None) {
public int createImageMem() (NVGContext ctx, const(ubyte)* data, int ndata, const(/*NVGImageFlag*/uint)[] imageFlagsList...) {
int w, h, n, image;
ubyte* img = stbi_load_from_memory(data, ndata, &w, &h, &n, 4);
if (img is null) {
//printf("Failed to load %s - %s\n", filename, stbi_failure_reason());
return 0;
}
uint imageFlags = 0;
foreach (immutable uint flag; imageFlagsList) imageFlags |= flag;
image = ctx.createImageRGBA(w, h, img[0..w*h*4], imageFlags);
stbi_image_free(img);
return image;
@ -2755,8 +2770,10 @@ static if (NanoVegaHasArsdImage) {
/// Creates image from specified image data.
/// Returns handle to the image or 0 on error.
/// Group: images
public int createImageRGBA (NVGContext ctx, int w, int h, const(void)[] data, int imageFlags=NVGImageFlags.None) nothrow @trusted @nogc {
public int createImageRGBA (NVGContext ctx, int w, int h, const(void)[] data, const(/*NVGImageFlag*/uint)[] imageFlagsList...) nothrow @trusted @nogc {
if (w < 1 || h < 1 || data.length < w*h*4) return 0;
uint imageFlags = 0;
foreach (immutable uint flag; imageFlagsList) imageFlags |= flag;
return ctx.params.renderCreateTexture(ctx.params.userPtr, NVGtexture.RGBA, w, h, imageFlags, cast(const(ubyte)*)data.ptr);
}
@ -3050,7 +3067,7 @@ public NVGLGS createLinearGradientWithStops (NVGContext ctx, float sx, float sy,
foreach (immutable i; 0..stops.length-1) gradientSpan(data.ptr, stops.ptr+i, stops.ptr+i+1);
}
gradientSpan(data.ptr, (stops.length ? stops.ptr+stops.length-1 : &s0), &s1);
img = ctx.createImageRGBA(NVG_GRADIENT_SAMPLES, 1, data[], NVGImageFlags.RepeatX|NVGImageFlags.RepeatY);
img = ctx.createImageRGBA(NVG_GRADIENT_SAMPLES, 1, data[], NVGImageFlag.RepeatX, NVGImageFlag.RepeatY);
if (img <= 0) return null;
// allocate data
NVGLGS res = cast(NVGLGS)malloc((*NVGLGS).sizeof);
@ -6845,7 +6862,7 @@ bool nvg__allocTextAtlas (NVGContext ctx) nothrow @trusted @nogc {
ctx.imageSize(ctx.fontImages[ctx.fontImageIdx], iw, ih);
if (iw > ih) ih *= 2; else iw *= 2;
if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE) iw = ih = NVG_MAX_FONTIMAGE_SIZE;
ctx.fontImages[ctx.fontImageIdx+1] = ctx.params.renderCreateTexture(ctx.params.userPtr, NVGtexture.Alpha, iw, ih, (ctx.params.fontAA ? 0 : NVGImageFlags.NoFiltering), null);
ctx.fontImages[ctx.fontImageIdx+1] = ctx.params.renderCreateTexture(ctx.params.userPtr, NVGtexture.Alpha, iw, ih, (ctx.params.fontAA ? 0 : NVGImageFlag.NoFiltering), null);
}
++ctx.fontImageIdx;
fonsResetAtlas(ctx.fs, iw, ih);
@ -10607,7 +10624,7 @@ public enum NVGContextFlag : int {
public enum NANOVG_GL_USE_STATE_FILTER = true;
/// These are additional flags on top of NVGImageFlags.
/// These are additional flags on top of [NVGImageFlag].
/// Group: images
public enum NVGImageFlagsGL : int {
NoDelete = 1<<16, // Do not delete GL texture handle.
@ -11097,7 +11114,7 @@ int glnvg__renderCreateTexture (void* uptr, NVGtexture type, int w, int h, int i
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
// GL 1.4 and later has support for generating mipmaps using a tex parameter.
if ((imageFlags&(NVGImageFlags.GenerateMipmaps|NVGImageFlags.NoFiltering)) == NVGImageFlags.GenerateMipmaps) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
if ((imageFlags&(NVGImageFlag.GenerateMipmaps|NVGImageFlag.NoFiltering)) == NVGImageFlag.GenerateMipmaps) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
if (type == NVGtexture.RGBA) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
@ -11105,20 +11122,20 @@ int glnvg__renderCreateTexture (void* uptr, NVGtexture type, int w, int h, int i
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
}
if ((imageFlags&(NVGImageFlags.GenerateMipmaps|NVGImageFlags.NoFiltering)) == NVGImageFlags.GenerateMipmaps) {
if ((imageFlags&(NVGImageFlag.GenerateMipmaps|NVGImageFlag.NoFiltering)) == NVGImageFlag.GenerateMipmaps) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (imageFlags&NVGImageFlags.NoFiltering ? GL_NEAREST : GL_LINEAR));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (imageFlags&NVGImageFlag.NoFiltering ? GL_NEAREST : GL_LINEAR));
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (imageFlags&NVGImageFlags.NoFiltering ? GL_NEAREST : GL_LINEAR));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (imageFlags&NVGImageFlag.NoFiltering ? GL_NEAREST : GL_LINEAR));
if (imageFlags&NVGImageFlags.RepeatX) {
if (imageFlags&NVGImageFlag.RepeatX) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
}
if (imageFlags&NVGImageFlags.RepeatY) {
if (imageFlags&NVGImageFlag.RepeatY) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@ -11258,7 +11275,7 @@ bool glnvg__convertPaint (GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGPaint* p
if (paint.image != 0) {
tex = glnvg__findTexture(gl, paint.image);
if (tex is null) return false;
if ((tex.flags&NVGImageFlags.FlipY) != 0) {
if ((tex.flags&NVGImageFlag.FlipY) != 0) {
/*
NVGMatrix flipped;
nvgTransformScale(flipped[], 1.0f, -1.0f);
@ -11289,7 +11306,7 @@ bool glnvg__convertPaint (GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGPaint* p
frag.type = NSVG_SHADER_FILLIMG;
if (tex.type == NVGtexture.RGBA) {
frag.texType = (tex.flags&NVGImageFlags.Premultiplied ? 0 : 1);
frag.texType = (tex.flags&NVGImageFlag.Premultiplied ? 0 : 1);
} else {
frag.texType = 2;
}