I am using bitblt to to capture a window. If the aero theme is enabled, The background of the captured image is black. If I disable the DWM and capture the window then the captured image is very good.
Here is part of my code.
HDC hdcMemDC = GDI32.INSTANCE.CreateCompatibleDC(desktopDC);
HDC windowDC = User32.INSTANCE.GetDC(window);
HWND window= User32Extra.INSTANCE.FindWindow(null, "Start menu");
GDI32Extra.INSTANCE.BitBlt(hdcMemDC, 0, 0, width, height, desktopDC, 0, 0, WinGDIExtra.SRCCOPY );
GDI32Extra.INSTANCE.BitBlt(hdcMemDC,windowBounds.left, windowBounds.top, windowWidth, windowHeight, windowDC, windowBounds.left+windowBounds1.right-windowBounds.right+(windowExtraGap/2), windowBounds.top+windowBounds1.bottom-windowBounds.bottom+(windowExtraGap/2), WinGDIExtra.SRCCOPY);
How to capture the start Menu with proper background?
Are there any other methods to get the proper image of aero window?
use desktop DC and cut to window
RECT rc, rc2;
GetClientRect(hWnd, &rc);
GetWindowRect(hWnd, &rc2);
int width = rc2.right - rc2.left;
int height = rc2.bottom - rc2.top;
HDC hdcScreen = GetDC(NULL); //!!!! Get desktop DC
HDC hBmpFileDC = CreateCompatibleDC(hdcScreen);
HBITMAP hBmpFileBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBmpFileDC, hBmpFileBitmap);
BitBlt(hBmpFileDC, 0, 0, width, height, hdcScreen, rc2.left, rc2.top, SRCCOPY | CAPTUREBLT);
HGDIOBJ prev = SelectObject(hBmpFileDC, hOldBitmap);
SaveBitmap(szLogFilename, hBmpFileBitmap);
DeleteDC(hBmpFileDC);
DeleteObject(hBmpFileBitmap);
another variant
RECT rc;
GetClientRect(hWnd, &rc);
int width = rc.right - rc.left;
int height = rc.bottom - rc.top;
HDC hdcScreen = GetDC(hWnd);
////////////////////////////
PrintWindow(hWnd, hdcScreen, 0);
PrintWindow(hWnd, hdcScreen, PW_CLIENTONLY);
////////////////////////////
HDC hBmpFileDC = CreateCompatibleDC(hdcScreen);
HBITMAP hBmpFileBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hBmpFileDC, hBmpFileBitmap);
BitBlt(hBmpFileDC, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY | CAPTUREBLT);
HGDIOBJ prev = SelectObject(hBmpFileDC, hOldBitmap);
SaveBitmap(szLogFilename, hBmpFileBitmap);
DeleteDC(hBmpFileDC);
DeleteObject(hBmpFileBitmap);
before call any capture method I call PrintWindow. It acts window to redraw itself. And as a result screen capture will have correct picture. The most stable result I got with double call of PrintWindow.
Related
I am struggling to render smooth lines using GL_LINES.
I have borrowed the MultisampleConfigChooser from the following link: MultisampleConfigChooser.java
It seemed to find the multisample configuration without any errors.
Here is the code I use to render the lines on the screen:
GLES20.glUseProgram(this.lineDrawProgram);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(
mPositionHandle, 2,
GLES20.GL_FLOAT, false,
6*4, linesData);
linesData.position(2);
GLES20.glEnableVertexAttribArray(mColorHandle);
GLES20.glVertexAttribPointer(
mColorHandle, 4,
GLES20.GL_FLOAT, false,
6*4, linesData);
linesData.position(0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, matrix, 0);
GLES20.glDrawArrays(GLES20.GL_LINES, 0, this.numLines*2);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mColorHandle);
Blending is enabled with GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA.
One more mention is that I am drawing the lines to a texture which is bound to an FBO as a color attachment. I have not added any extra code to enable multisampling for the FBO.
Here is the code I use to setup the FBO and texture:
int[] fbo = new int[1];
int[] tex = new int[1];
enGLES20.glGenTextures(1, tex, 0);
GLES20.glGenFramebuffers(1, fbo, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0,GLES20.GL_RGBA, this.width, this.height, 0,GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
GES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, tex[0], 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
The resulting lines still look like crap:
Please help me get these lines to look smooth.
BTW there are many different small lines in the screenshot, no curved lines or anything exotic.
I am trying to implement shadow-mapping in my scene, but all I get is zeros in my fragment shader when I call texture() (I've tested it with == 0.0). My question: Am I sending the depth texture to the shader correctly?
Here is my fragment shader code:
bool getShadow() {
vec4 lightProjPositionScaled = lightProjPosition/lightProjPosition.w;
vec2 texCoords = lightProjPositionScaled.xy*0.5 + 0.5; // bias
return lightProjPositionScaled.z + 0.0005 > texture(shadowMap, texCoords).x;
}
Here is my relevant java codeInit (edited due to BDL's comment)
gl.glEnable(GL2.GL_TEXTURE_2D);
// generate stuff
IntBuffer ib = IntBuffer.allocate(1);
gl.glGenFramebuffers(1, ib);
frameBuffer = ib.get(0);
ib = IntBuffer.allocate(1);
gl.glGenTextures(1, ib);
shadowMap = ib.get(0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer);
gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 1024, 1024, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, null);
gl.glDrawBuffer(GL2.GL_NONE);
gl.glReadBuffer(GL2.GL_NONE);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
// prevents 'shadow acne'
gl.glPolygonOffset(2.5f, 0);
// prevents multiple shadows
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
// prevents (or expects!!!) pixel-y textures
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
// store one value in all four components of pixel
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY);
Display (1st pass, for shadows):
// render shadows
gl.glUseProgram(shadowProgram);
gl.glUniformMatrix4fv(lightMatrixLocShadow, 1, false, lightMatrix.getMatrix(), 0); // yep (haha change viewMatrix -> lightMatrix)
gl.glUniformMatrix4fv(projMatrixLocShadow, 1, false, projMatrix.getMatrix(), 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, sha.frameBuffer);
gl.glViewport(0, 0, 1024, 1024);
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
renderScene(gl, sunMatrix);
gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
Display (2nd pass, for rendering the scene):
// render display (regular)
gl.glUseProgram(displayProgram);
gl.glDrawBuffer(GL2.GL_FRONT);
gl.glReadBuffer(GL2.GL_FRONT);
gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(projMatrixLocDisplay, 1, false, projMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(lightMatrixLocDisplay, 1, false, lightMatrix.getMatrix(), 0);
gl.glUniform4fv(sunPositionLoc, 1, sunWorldPosition, 0); // send sun's position to shader
gl.glUniform1f(sunBrightnessLoc, sunBrightness);
gl.glUniform1i(shadowMapLoc, 0);
gl.glViewport(0, 0, screenWidth, screenHeight);
// day-night cycle
float[] color = SkyManager.getSkyColor(time);
gl.glClearColor(color[0], color[1], color[2], 1);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glActiveTexture(GL2.GL_TEXTURE0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, sha.shadowMap);
renderScene(gl, sunMatrix);
Another strange outcome is that only fragments on the z=0 plane relative to the light matrix (the light's rotating, and the plane rotates with it) are lit. All other fragments, behind and in front of the light, are shadowed.
One issue was with the line gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
I was binding the texture to GL_TEXTURE instead of GL_TEXTURE_2D.
I've seen references to this error before but no solution.
Where I am drawing the text, there is only a solid box of the specified color being drawn.
The code is like this:
TrueTypeFont font;
Font awtFont = new Font("Arial Unicode MS", Font.BOLD, 12); //name, style (PLAIN, BOLD, or ITALIC), size
font = new TrueTypeFont(awtFont, true); //base Font, anti-aliasing true/false
while (!Display.isCloseRequested() ) {
render();
font.drawString(10, 10, "ABC123", Color.black); //x, y, string to draw, color
//ENABLE THESE:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//RENDER LIKE THIS:
glPushMatrix();
bodyPosition = body.getPosition().mul(30);
glTranslatef(Position.x, Position.y, 0);
GL11.glDisable(GL11.GL_TEXTURE_2D);
glPopMatrix();
I'm trying to capture all the pen data: touch, pressure at one point, coordinates of the touch ...
Any suggestions?
SigCtl sigCtl = new SigCtl();
DynamicCapture dc = new DynamicCapture();
int rc = dc.capture(sigCtl, "who", "why", null, null);
if(rc == 0) {
System.out.println("signature captured successfully");
String fileName = "sig1.png";
SigObj sig = sigCtl.signature();
sig.extraData("AdditionalData", "CaptureImage.java Additional Data");
int flags = SigObj.outputFilename | SigObj.color32BPP | SigObj.encodeData;
sig.renderBitmap(fileName, 200, 150, "image/png", 0.5f, 0xff0000, 0xffffff, 0.0f, 0.0f, flags );
}
I managed to solve the problem using the wgssStu library, this jar there is PenData class, which has the following methods: getPressure, getX, getY, getRdy, getSw...
I have two images that I want to merge into one and show side by side (right and left). I've searched in websites and have gotten the below code, but it always is coming top and bottom only.
i think This occurs due to the extra code I added to make both images the same size.
my code:
if(c.getWidth() > s.getWidth()) {
width = c.getWidth();
height = c.getHeight() + s.getHeight();
} else {
width = s.getWidth();
height = c.getHeight() + s.getHeight();
}
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(cs);
canvas.drawBitmap(c, 0f, 0f, null);
canvas.drawBitmap(s, c.getWidth(), 0f , null);
and also I am using this code for make both image as same size
Rect dest1 = new Rect(0, 0, width, height / 2); // left,top,right,bottom
canvas.drawBitmap(c, null, dest1, null);
Rect dest2 = new Rect(0, height / 2, width, height); // left,top,right,bottom
canvas.drawBitmap(s, null, dest2, null);
add customdrawable.xml in drawable folder
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="#drawable/image1" android:gravity="left"/>
</item>
<item>
<bitmap android:src="#drawable/image2" android:gravity="right"/>
</item>
</layer-list>
use as #drawable/customdrawable.
Example Link
LayeredDrawable
If you requirement suites, you can use this.
Well, the first if{ is not valid code, I assume you want some condition there to distinguish between side-by-side and above-below?
The if code seems identical to the else code (since they have the same width), you probably want to add the widths instead.
Overall, you probably want something like:
if(sideBySide)
cs = Bitmap.createBitmap(c.getWidth(), c.getHeight() + s.getHeight(), Bitmap.Config.ARGB_8888);
else
cs = Bitmap.createBitmap(c.getWidth() + s.getWidth(), s.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(cs);
canvas.drawBitmap(c, 0f, 0f, null);
if(sideBySide)
canvas.drawBitmap(s, c.getWidth(), 0f , null);
else
canvas.drawBitmap(s, 0, c.getHeight() , null);