Forum in repository mode. No new members allowed.
Quote from: Charles Pegge on September 03, 2019, 05:28:55 PMOur o2 Opengl framework uses GDI+ both for loading textures and producing image files.
Currently, the opengl buffer bits are transferred pixel by pixel into a gdi+ bitmap.
QuoteCurrently, the opengl buffer bits are transferred pixel by pixel into a gdi+ bitmap. Though I wonder if there is a more efficient way of making the transfer, bearing in mind that the red and blue colors of each pixel have to be swapped.
I suspect that 90% of the effort goes into the final 10% of each project
sub PrintBitmap(byval hPrintBitmap as dword, byval hDCprint as dword, byval xTop as long, byval yTop as long, byval fxSize as long, byval fySize as long)
local bm as BITMAP
local dcBitmap as dword
dcBitmap = CreateCompatibleDC(%NULL)
GetObject(hPrintBitmap, sizeof(bm), bm)
local bi as BITMAPINFO
bi.bmiHeader.biSize = sizeof(bi.bmiHeader)
bi.bmiHeader.biWidth = bm.bmWidth
bi.bmiHeader.biHeight = bm.bmHeight
bi.bmiHeader.biPlanes = 1
bi.bmiHeader.biBitCount = bm.bmBitsPixel
bi.bmiHeader.biCompression = %BI_RGB
'// Calculate space needed for the dib bits
local nBufSize as long
nBufSize = (bi.bmiHeader.biWidth + 1) * (bi.bmiHeader.biBitCount / 8)
nBufSize = ((nBufSize + 3) / 4) * 4
nBufSize *= bi.bmiHeader.biHeight
local ghnd, gptr as dword
ghnd = GlobalAlloc(%GMEM_MOVEABLE, nBufSize)
gptr = GlobalLock(ghnd)
local nDI as long
nDI = GetDIBits(dcBitmap, hPrintBitmap, 0, bm.bmHeight, byval gptr, bi, %DIB_RGB_COLORS)
'// Use this to print a full bitmap
nDI = StretchDIBits(hDCprint, xTop, yTop, fxSize, fySize, 0, 0, bm.bmWidth, bm.bmHeight, BYVAL gptr, bi, %DIB_RGB_COLORS, %SRCCOPY)
GlobalUnlock(ghnd)
GlobalFree(ghnd)
DeleteDC(dcBitmap)
end sub
function SendToPrinter() as long
local nRet, Wdth, Hght, X, Y, hSize, vSize, hRes, vRes, Landscape as long
local hTmp as dword
local sFilName as string
local rc as RECT
GetWindowRect (gP.hMain, rc)
Wdth = ((rc.nRight - rc.left) - 438) / 2 - 48
Hght = ((rc.nBottom - rc.top) - 314) / 2 - 52
X = rc.left + Wdth
Y = rc.top + Hght
hTmp = CreateWindowEx(0, "STATIC", "", %WS_POPUP, X, Y, 0, 0, gP.hMain, 0, gP.hinstance, byval %NULL)
'// Setup the print common dialog
local pd as PRINTDLGAPI
pd.lStructSize = sizeof(pd)
pd.hwndOwner = hTmp
pd.hDevMode = 0
pd.hDevNames = 0
pd.nFromPage = 0
pd.nToPage = 0
pd.nMinPage = 0
pd.nMaxPage = 0
pd.nCopies = 0
pd.hInstance = gP.hinstance
pd.Flags = %PD_RETURNDC or %PD_NOPAGENUMS or %PD_PRINTSETUP
pd.lpfnSetupHook = 0
pd.lpPrintSetupTemplateName = 0
pd.lpfnPrintHook = 0
pd.lpPrintTemplateName = 0
if (PrintDlg(pd)) then
hSize = GetDeviceCaps(pd.hDC, %HORZSIZE)
vSize = GetDeviceCaps(pd.hDC, %VERTSIZE)
hRes = GetDeviceCaps(pd.hDC, %HORZRES)
vRes = GetDeviceCaps(pd.hDC, %VERTRES)
sFilName = EXE.Name$ + "_output"
local dinfo as DOCINFO
dinfo.cbSize = sizeof(dinfo)
dinfo.lpszDocName = strptr(sFilName)
dinfo.lpszOutput = 0
'// Detect printer orientation mode
Landscape = -1: if (vSize > hSize) then Landscape = 0
'// Compute the printing size
local offsetX, offsetY as long
if (Landscape) then
offsetX = 60: offsetY = 0
else
offsetX = 15: offsetY = 60
end if
local img as dword
GetClientRect(gP.hGL, rc)
dim buffer(rc.nRight * rc.nBottom * 3) as byte
glPixelStorei(GL_PACK_ALIGNMENT, 1)
glReadPixels(0, 0, rc.nRight, rc.nBottom, GL_BGR, GL_UNSIGNED_BYTE, byval varptr(buffer(0)))
if (GdipCreateBitmapFromScan0(rc.nRight, rc.nBottom, rc.nRight * 3, %PixelFormat24bppRGB, buffer(0), img) = 0) then
if (img) then
if (GdipImageRotateFlip(img, 6) = 0) then
local hPrintBitmap as dword
local background as long
if (GdipCreateHBITMAPFromBitmap(img, hPrintBitmap, background) = 0) then
local rCoef as single
rCoef = min((hRes - (offsetX * 2)) / rc.nRight, (vRes - (offsetY * 2)) / rc.nBottom)
local fxSize, fySize, xTop, yTop as long
fxSize = (rc.nRight * rCoef)
fySize = (rc.nBottom * rCoef)
xTop = (hRes - fxSize) \ 2 + offsetX
yTop = (vRes - fySize) \ 2 + offsetY
if (StartDoc(pd.hDC, dinfo) > 0) then
if (StartPage(pd.hDC) > 0) then
'// Paint the DIB bitmap
PrintBitmap(hPrintBitmap, pd.hDC, xTop, yTop, fxSize, fySize)
if (EndPage(pd.hDC) > 0) then
nRet = -1
EndDoc(pd.hDC)
end if
end if
end if
DeleteObject(hPrintBitmap)
end if
end if
GdipDisposeImage(img)
end if
end if
DeleteDC(pd.hDC)
end if
DestroyWindow(hTmp)
function = nRet
end function
// 05-22-2015
long SendToPrinter() {
long nRet = 0;
RECT rc = { 0 };
GetWindowRect(gP.hMain, &rc);
long Wdth = ((rc.right - rc.left) - 438) / 2 - 48;
long Hght = ((rc.bottom - rc.top) - 314) / 2 - 52;
long X = rc.left + Wdth;
long Y = rc.top + Hght;
HWND hTmp = CreateWindowEx(0, L"STATIC", $NULL, WS_POPUP, X, Y, 0, 0, gP.hMain, 0, gP.hInstance, NULL);
// Setup the print common dialog
PRINTDLG pd;
pd.lStructSize = sizeof(pd);
pd.hwndOwner = hTmp;
pd.hDevMode = NULL;
pd.hDevNames = NULL;
pd.nFromPage = 0;
pd.nToPage = 0;
pd.nMinPage = 0;
pd.nMaxPage = 0;
pd.nCopies = 0;
pd.hInstance = gP.hInstance;
pd.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_PRINTSETUP;
pd.lpfnSetupHook = NULL;
pd.lpSetupTemplateName = NULL;
pd.lpfnPrintHook = NULL;
pd.lpPrintTemplateName = NULL;
if (PrintDlg(&pd)) {
long hSize = GetDeviceCaps(pd.hDC, HORZSIZE);
long vSize = GetDeviceCaps(pd.hDC, VERTSIZE);
long hRes = GetDeviceCaps(pd.hDC, HORZRES);
long vRes = GetDeviceCaps(pd.hDC, VERTRES);
WCHAR PathName[MAX_PATH] = { 0 };
WCHAR FilName[MAX_PATH] = { 0 };
zSplitN(zExeName(), &PathName[0], &FilName[0]);
Add_Str(FilName, L"_output");
DOCINFO dinfo;
dinfo.cbSize = sizeof(dinfo);
dinfo.lpszDocName = &FilName[0];
dinfo.lpszOutput = NULL;
// Detect printer orientation mode
long Landscape = -1; if (vSize > hSize) { Landscape = 0; }
// Compute the printing size
long offsetX, offsetY;
if (Landscape) {
offsetX = 60; offsetY = 0;
} else {
offsetX = 15; offsetY = 60;
}
LONG_PTR img = 0;
GetClientRect(gP.hGL, &rc);
// 07-17-2017 respect boundary alignment
rc.right = (rc.right / 4) * 4;
rc.bottom = (rc.bottom / 4) * 4;
BYTE* buffer = new BYTE[rc.right * rc.bottom * 3];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, rc.right, rc.bottom, GL_BGR, GL_UNSIGNED_BYTE, &buffer[0]);
if (GdipCreateBitmapFromScan0(rc.right, rc.bottom, rc.right * 3, PixelFormat24bppRGB, &buffer[0], img) == 0) {
if (img) {
if (GdipImageRotateFlip(img, 6) == 0) {
HBITMAP hPrintBitmap = 0; long background = 0;
if (GdipCreateHBITMAPFromBitmap(img, hPrintBitmap, background) == 0) {
float rCoef = min((float)((hRes - (offsetX * 2)) / (float)rc.right), (float)((vRes - (offsetY * 2)) / (float)rc.bottom));
long fxSize = (long)(rc.right * rCoef);
long fySize = (long)(rc.bottom * rCoef);
long xTop = (hRes - fxSize) / 2 + offsetX;
long yTop = (vRes - fySize) / 2 + offsetY;
if (StartDoc(pd.hDC, &dinfo) > 0) {
if (StartPage(pd.hDC) > 0) {
// Paint the DIB bitmap
PrintBitmap(hPrintBitmap, pd.hDC, xTop, yTop, fxSize, fySize);
nRet = EndPage(pd.hDC);
if (nRet > 0) {
nRet = -1;
EndDoc(pd.hDC);
} else {
nRet = 0;
}
}
}
DeleteObject(hPrintBitmap);
}
}
GdipDisposeImage(img);
}
}
delete[] buffer;
DeleteDC(pd.hDC);
}
DestroyWindow(hTmp);
return nRet;
}
Page created in 0.082 seconds with 13 queries.