I use GDI+ Graphics.DrawImage() method to draw metafile images (emf/wmf) in my application. This method allows set color matrix by ImageAttributes. I use color matrix to perform image alpha blending (drawing semi transparent image) like this:
const auto alphaPercent = 0.5f
ColorMatrix colorMatrix = {
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, alphaPercent, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};
ImageAttributes imageAttributes;
imageAttributes.SetColorMatrix(&colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeDefault);
pGraphics->DrawImage(pImageToDraw,imagePosition, 0.f, 0.f, sourceWidth, sourceHeight, UnitPixel, &imageAttributes);
This method excellent works for bitmaps but not for emf metafiles.
Changing ColorAdjustTypeDefault to ColorAdjustTypePen or ColorAdjustTypeBrush doesn't help.
Example: GDI+ result:
But should be (alpha = 50%):
How to draw metafile image in GDI+ with alpha blending ?
Related
I startet with Directx 11 and I have some problems with setting up the camera.
I want to set the origin to the top-left of the sceen, currently it is on bot-left this is how I set it up:
D3DXMatrixIdentity(&mProjection);
D3DXMatrixIdentity(&mView);
mPosition = D3DXVECTOR3{ 0.0f, 0.0f, -0.5f };
mTarget = D3DXVECTOR3{ 0.0f, 0.0f, 0.0f };
mUp = D3DXVECTOR3{ 0.0f, 0.0f, 0.0f };
D3DXMatrixOrthoOffCenterLH(&mProjection,
0.0f, static_cast<Float32>(WindowWidth),
0.0f, static_cast<Float32>(WindowHeight), 0.0f, 1.0f);
and here is how I want it
this is currently my coord system:
swap y parameters for building the matrix:
D3DXMatrixOrthoOffCenterLH(&mProjection,
0.0f, static_cast<Float32>(WindowWidth),
static_cast<Float32>(WindowHeight), 0.0f, 0.0f, 1.0f);
I have a black and white image, a would like to replace the black pixels with red pixels. I've tried
Gdiplus::Graphics* g = Gdiplus::Graphics::FromImage(filename);
Gdiplus::ImageAttributes ia;
Gdiplus::ColorMatrix m = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f
};
ia.SetColorMatrix(&m);
g->DrawImage(org, r, 0, 0, org->GetWidth(), org->GetHeight(), Gdiplus::UnitPixel, &ia);
But it's making the entire bitmap red.
Do not use a matrix to perform this transformation. Your matrix will always output the following vector:
[1.0 0.0 0.0 currentAlpha 1.0]
That's why you have a red image.
Visit https://msdn.microsoft.com/en-us/library/ms533875%28v=vs.85%29.aspx
Use this instead
ImageAttributes ia;
ColorMap blackToRed;
blackToRed.oldColor = Color(255, 0, 0, 0); // black
blackToRed.newColor = Color(255, 255, 0, 0);// red
ia.SetRemapTable(1, &blackToRed);
I have a problem when combining the orthographic projection and the Perspective projection.
I'm drawing a texture over a 3d object:
I guess it has something to do with the clipping values:
camProjection = XMMatrixPerspectiveFovLH(0.4f * 3.14f, (float)SCREEN_WIDTH/SCREEN_HEIGHT, 1.0f, 1000.0f);
camProjection2D = XMMatrixOrthographicOffCenterLH(.0f, SCREEN_WIDTH, SCREEN_HEIGHT, .0f, 0.0f, 1000.0f);
Texture coords: (x, y, z, u, v)
Vertex( 0.0f, 0.0f, -1.0f, 0.0f, 1.0f),
Vertex( 0.0f, 20.0f, -1.0f, 0.0f, 0.0f),
Vertex(20.0f, 20.0f, -1.0f, 1.0f, 0.0f),
Vertex(20.0f, 0.0f, -1.0f, 1.0f, 1.0f),
I hope someone can help me with this problem.
Its not a big problem but its bugging me.
You're probably trying to display UI over your rendered scene. The standard way to do this is to render you scene first, then clear your z-buffer before drawing UI elements. This way there will be no z-fighting and interference from objects close to camera.
I knew what the purpose of using gluLookAt(...) , glPushMatrix and other basic transformational stuff in opengl. I am stuck in these piece of code. When i implement the glulookat(.....) inside the glPushMatrix() after setting the appropriate requirement for the opengl. The code works fine and on the keypress the cube gets rendered with appropriate rotation but when i implement the gluLookAt(....) outside the glPushMatrix() and glPopMatrix(), things got crazy. The cube shows the abnormal behaviour and finally it gets
disappeared from the screen.
gluLookAt(0.0f, 0.0f, 400.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glPushMatrix();
//gluLookAt(0.0f, 0.0f, 400.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
// Front Face
// White
glColor3ub((GLubyte) 255, (GLubyte)255, (GLubyte)255);
glVertex3f(50.0f,50.0f,50.0f);
// Yellow
glColor3ub((GLubyte) 255, (GLubyte)255, (GLubyte)0);
glVertex3f(50.0f,-50.0f,50.0f);
// Red
glColor3ub((GLubyte) 255, (GLubyte)0, (GLubyte)0);
glVertex3f(-50.0f,-50.0f,50.0f);
// Magenta
glColor3ub((GLubyte) 255, (GLubyte)0, (GLubyte)255);
glVertex3f(-50.0f,50.0f,50.0f);
// Back Face
// Cyan
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(50.0f,50.0f,-50.0f);
// Green
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(50.0f,-50.0f,-50.0f);
// Black
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(-50.0f,-50.0f,-50.0f);
// Blue
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-50.0f,50.0f,-50.0f);
// Top Face
// Cyan
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(50.0f,50.0f,-50.0f);
// White
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(50.0f,50.0f,50.0f);
// Magenta
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(-50.0f,50.0f,50.0f);
// Blue
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-50.0f,50.0f,-50.0f);
// Bottom Face
// Green
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(50.0f,-50.0f,-50.0f);
// Yellow
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(50.0f,-50.0f,50.0f);
// Red
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-50.0f,-50.0f,50.0f);
// Black
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(-50.0f,-50.0f,-50.0f);
// Left face
// White
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(50.0f,50.0f,50.0f);
// Cyan
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(50.0f,50.0f,-50.0f);
// Green
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(50.0f,-50.0f,-50.0f);
// Yellow
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(50.0f,-50.0f,50.0f);
// Right face
// Magenta
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(-50.0f,50.0f,50.0f);
// Blue
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-50.0f,50.0f,-50.0f);
// Black
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(-50.0f,-50.0f,-50.0f);
// Red
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-50.0f,-50.0f,50.0f);
glEnd();
glPopMatrix();
gluLookAt mulitplies the currently topmost element of the active matrix stack with a look-at matrix and replaces the topmost element with this.
Push and Pop are standard stack operations. Push creates a copy of the topmost element and pushes it on the top of the stack, pop removes it.
So any changes you do within a push-pop block get reverted with the pop operation. But outside of a stack frame (push-pop) the changes will accumulate. If you put a glLoadIdentity before the gluLookAt outside of the push-pop, it will work as well, but that is, because you reset the matrix to a sane value instead of working on top of what's been there from the previous rendering.
How do I get the OpenGL color matrix transforms working?
I've modified a sample program that just draws a triangle, and added some color matrix code to see if I can change the colors of the triangle but it doesn't seem to work.
static float theta = 0.0f;
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClearDepth(1.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef( theta, 0.0f, 0.0f, 1.0f );
glMatrixMode(GL_COLOR);
GLfloat rgbconversion[16] =
{
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f
};
glLoadMatrixf(rgbconversion);
glMatrixMode(GL_MODELVIEW);
glBegin( GL_TRIANGLES );
glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 1.0f , 0.5f);
glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( 0.87f, -0.5f, 0.5f );
glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( -0.87f, -0.5f, 0.5f );
glEnd();
glPopMatrix();
As far as I can tell, the color matrix I'm loading should change the triangle to black, but it doesn't seem to work. Is there something I'm missing?
The color matrix only applies to pixel transfer operations such as glDrawPixels which aren't hardware accelerated on current hardware. However, implementing a color matrix using a fragment shader is really easy. You can just pass your matrix as a uniform mat4 then mulitply it with gl_FragColor
It looks like you're doing it correctly, but your current color matrix sets the triangle's alpha value to 0 as well, so while it is being drawn, it does not appear on the screen.
"Additionally, if the ARB_imaging extension is supported, GL_COLOR is also accepted."
From the glMatrixMode documentation. Is the extension supported on your machine?
I have found the possible problem.
The color matrix is supported by the "Image Processing Subset". In most HW, it was supported by driver.(software implementation)
Solution:
Add this line after glEnd():
glCopyPixels(0,0, getWidth(), getHeight(),GL_COLOR);
It's very slow....