How to fill a rectangle region with Semi-transparent brush in MFC? - visual-c++

I need to fill a rectangular region with semi-transparent color/brush in mfc. How can I achieve that?

You can't just fill a rectangle with a semi-transparent brush, you'll need to use something like AlphaBlend or TransparentBlt to create the effect.
An example is available here:
http://www.codeproject.com/Articles/286/Using-the-AlphaBlend-function

I found the solution. To fill the rectangle region with semi-transparent brush, we need to use GdiPlus objects.
Here is the Sample Code:
void FillSemiTransparentRegion(CDC *pDC, CRect rc)
{
if (pDC == NULL || rc.IsRectEmpty() || rc.IsRectNull())
return;
Graphics gr(pDC->GetSafeHdc());
SolidBrush br(Color(100, 0, 0, 0)); // Alpha, Red, Blue, Green
gr.FillRectangle(&br, rc.left, rc.right, rc.Width(), rc.Height());
}

Related

c++builder style override options

I'm having a problem with vcl styles overwriting custom colours. Is there a way to turn off styles when using onDrawItem, or detect when a style is on, and what the target colour will be?
Specifically, in this particular case, if the style is on the dark mode, text is made white, and in my case I need the background to be white. So white text against white background is invisible.
It looks like the pen color is being ignored and replaced with the style color, while background colors are correct.
Ideally, I'd like to ignore style stuff while in this particular draw routine, and just use my own colors. (Using C++Builder 11)
TIA
The code in question:
//TCheckListBox *clbxCategory;
void __fastcall TFormATB::clbxCategoryDrawItem(TWinControl* Control,
int Index, TRect &Rect, TOwnerDrawState State)
{
if(State.Contains(odSelected)) {
clbxCategory->Canvas->Pen->Color = clBlack;
clbxCategory->Canvas->Brush->Color = clActiveCaption;
clbxCategory->Canvas->RoundRect(Rect.Left, Rect.Top , Rect.Right, Rect.Bottom, 0, 50);
}
else {
clbxCategory->Canvas->Pen->Color = Colours[Index];
clbxCategory->Canvas->Brush->Color = Colours[Index];
}
clbxCategory->Canvas->Rectangle(Rect.Left, Rect.Top - 1, Rect.Right, Rect.Bottom + 1);
clbxCategory->Canvas->TextOut(Rect.Left, Rect.Top,clbxCategory->Items->Strings[Index]);
}

How do I draw 2D fonts in processing P3D mode?

I'm running a sketch with an array of points in 3D space (P3D). I'd like to add an interface to it by drawing text as if it were "onscreen"/2D, only using "X, Y" parameters.
When I tried just adding "text("!##$%", width/2, height/2);" it rendered in 3D space.
Is it possible? I tried "textMode(SCREEN) but doesnt exist in processing 2 anymore.
Here is what I found, I guess on the Processing Forum
You can use:
a PMatrix3D for your 3D content
and code your 2D stuff the plain old way
I wish it helps
PMatrix3D baseMat;
float alpha =0;
void setup() {
size(400, 400, P3D);
// Remember the start model view matrix values
baseMat = getMatrix(baseMat);
}
void draw() {
background(40);
pushMatrix();
camera(0, 0, 400, 0, 0, 0, 0, 1, 0);
directionalLight(255, 255, 255, -100, 150, -100);
ambientLight(40, 40, 40);
// 3D drawing stuff here
rotateY(alpha);
box(100);
alpha += 0.05;
popMatrix();
// Restore the base matrix and lighting ready for 2D
this.setMatrix(baseMat);
ambientLight(255, 255, 255);
// draw 2D stuff here
rect(10, 10, 50, 10);
textSize(25);
text("voila", mouseX, mouseY);
}
A workaround that comes to mind is to create a 2D PGraphic that has the same width/height as your sketch, give it a transparent background, draw your text where you want on it, and then draw the PGraphic onto your real sketch like you would if you were copying over image source data.

Unity Shader RGBA Color mask

I am working on a shader for Unity in which I want to change the color based on an mask image. In this mask image the RGB channels stand for a color that can be choosen in the shader. The idea behind the shader is that it is easy to change the look of an object without having to change the texture by hand.
Shader "Custom/MultiColor" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_MaskTex ("Mask area (RGB)", 2D) = "black" {}
_ColorR ("Red Color", Color) = (1,1,1,1)
_ColorG ("Green Color", Color) = (1,1,1,1)
_ColorB ("Blue Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
sampler2D _MaskTex;
half4 _ColorR;
half4 _ColorG;
half4 _ColorB;
half4 _MaskMult;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 main = tex2D (_MainTex, IN.uv_MainTex);
half4 mask = tex2D (_MaskTex, IN.uv_MainTex);
half3 cr = main.rgb * _ColorR;
half3 cg = main.rgb * _ColorG;
half3 cb = main.rgb * _ColorB;
half r = mask.r;
half g = mask.g;
half b = mask.b;
half minv = min(r + g + b, 1);
half3 cf = lerp(lerp(cr, cg, g*(r+g)), cb, b*(r+g+b));
half3 c = lerp(main.rgb, cf, minv);
o.Albedo = c.rgb;
o.Alpha = main.a;
}
ENDCG
}
FallBack "Diffuse"
}
The problem with the shader is the blending between the masked color based on the green and blue channel. Between colors defined in the color supposted to be from the red region is visible. Below a sample is visable.
The red color is create by the red mask, green by the green mask and desert yellow by the blue region. I do not know why this happens or how to solve this problem.
Best guess: anti-aliasing or image compression. Aliasing (on the brush your using) will cause an overlap in the color channels, causing them to mix. Compression usually works by averaging each pixel's color info based on the colors around it (jpeg is especially notorious for this).
Troubleshoot by using a straight pixel based brush (no aliasing, no rounded edges) in Photoshop (or whatever image suite you're using) and/or try changing the colors through your shader and see how they mix- doing either should give you a better idea of what's going on under the hood. This combined with an lossless/uncompressed image-type, such as .tga should help, though they may use more memory.

How to create a hue (saturation) picker in cocos2d

I'm trying to create a simplified hue/saturation picker for cocos2d. I want to create a gradient and to pick from it. I need to recolor a black/white image gradient for every color like blue, red and others. So I need to create many gradients. I know that I should use some blend functions to achieve this.
But I'm still a little bit confused about what is the best way to proceed.
Should I use blend functions at all ?
My problem basically is that I use a gradient from black to transparent or to white but with
sprite.setColor(color);
I get a gradient from black to the desired color but I need a gradient from the desired darker color to white.
What you need to do is create a 2D gradient that goes from unsaturated to saturated left-to-right, and from dark to light bottom-to-top. I'd do it by creating a new bitmap (or if you're using OpenGL, a texture). I'd then color each pixel using the following pseudocode:
hue = <whatever the user set the hue to>
for (row = 0; row < height; row++)
{
for (col = 0; col < width; col++)
{
sat = col / width;
val = row / height;
rgb = HSVToRGB(hue, sat, value);
setPixel (col, row, rgb);
}
}

GDI: How to fill RoundRect with color?

While the question title seems dumb, that's not exactly what I need. To fill whole area with color, one needs to select appropriate brush - that's trivial. But I want to fill upper half of it with different color, and bottom half of it with the different one. If it was the normal (not round) rectangle, I could draw two rectangles (with different brushes). But with RoundRect I don't have any ideas how to do it.
Here is what I need it for: I draw each node in my graph visualization with RoundRect, and those nodes should have several compartments (cells) that should be filled with different colors.
I hope you get the idea what I mean :)
If you have to use legacy GDI instead of GDI+, here I wrote you a function to draw such a (cell) as you needed I hope it is what you have expected !
The basic idea is to create upper and lower regions (which they were both full overlapping rounded rectangles, then each has one of its halves cut off)
I have prepared the above illustration to show how the cell could be produced. It's for the upper side only, but you should have got the idea of creating the lower one.
Here is a wrapping function to create the cell you need:
void DrawCell(HDC& hdc, const RECT& rcTarget,const HBRUSH& hbrUpper, const HBRUSH& hbrLower)
{
HRGN hRgnUpper = CreateRoundRectRgn(rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom, 42, 38);
HRGN hRgnLower = CreateRoundRectRgn(rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom, 42, 38);
HRGN hRgnCutFromUpper = CreateRectRgn(rcTarget.left, rcTarget.top + ((rcTarget.bottom - rcTarget.top) / 2), rcTarget.right, rcTarget.bottom);
HRGN hRgnCutFromLower = CreateRectRgn(rcTarget.left, rcTarget.top , rcTarget.right, rcTarget.bottom - ((rcTarget.bottom - rcTarget.top) / 2));
CombineRgn(hRgnUpper, hRgnUpper,hRgnCutFromUpper, RGN_DIFF);
CombineRgn(hRgnLower, hRgnLower,hRgnCutFromLower, RGN_DIFF);
FillRgn( hdc, hRgnUpper, hbrUpper);
FillRgn( hdc, hRgnLower, hbrLower);
DeleteObject(hRgnCutFromLower);
DeleteObject(hRgnCutFromUpper);
DeleteObject(hRgnLower);
DeleteObject(hRgnUpper);
}
call this function from within your WM_PAINT handler:
RECT rcTarget;
rcTarget.left = 20;
rcTarget.top = 20;
rcTarget.right = 275;
rcTarget.bottom = 188;
HBRUSH hRed = CreateSolidBrush( RGB(255, 0, 0) );
HBRUSH hGreen = CreateSolidBrush( RGB(0, 255, 0) );
DrawCell(hdc, rcTarget, hRed, hGreen);

Resources