#define WIND32_LEAN_AND_MEAN // trim the excess fat from Windows
////// Includes
#include <windows.h> // standard Windows app include
#include <gl/gl.h> // standard OpenGL include
#include <gl/glu.h> // OpenGL utilities
#include <gl/glaux.h> // OpenGL auxiliary functions
////// Global Variables
float angle = 0.0f; // current angle of the rotating triangle
HDC g_HDC; // global device context
bool fullScreen = false; // start off in full-screen mode
unsigned char *imageData;
// function to set the pixel format for the device context
void SetupPixelFormat(HDC hDC)
{
int nPixelFormat; // your pixel format index
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), //size of the structure
1, // version, always set to 1
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // support double buffering
PFD_TYPE_RGBA, // RGBA color mode
32, // go for 32 bit color mode
0, 0, 0, 0, 0, 0, // ignore color bits, not used
0, // no alpha buffer
0, // ignore shift bit
0, // no accumulation buffer
0, 0, 0, 0, // ignore accumulation bits
16, // 16-bit z-buffer size
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main drawing plane
0, // reserved
0, 0, 0}; // layer masks ignored
// choose best matching pixel format, return index
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
// set pixel format to device context
SetPixelFormat(hDC, nPixelFormat, &pfd);
}
// the Windows Procedure event handler
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC; // rendering context
static HDC hDC; // device context
char string[] = "Hello, world!"; // text to be displayed
int width, height;
switch(message)
{
case WM_CREATE: // window is being created
hDC = GetDC(hwnd); // get current window's device context
g_HDC = hDC;
SetupPixelFormat(hDC); // call your pixel format setup function
// create rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
return 0;
break;
case WM_CLOSE: // windows is closing
// deselect rendering context and delete it
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
// send WM_QUIT to message queue
PostQuitMessage(0);
return 0;
break;
case WM_SIZE:
height = HIWORD(lParam); // retrieve width and height
width = LOWORD(lParam);
if (height==0) // don't wnat a divide by zero
{
height = 1;
}
// reset the viewport to new dimensions
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // set projection matrix
glLoadIdentity(); // reset projection matrix
//calculate aspect ratio of window
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // reset modelview matrix
return 0;
break;
default:
break;
}
return (DefWindowProc(hwnd, message, wParam, lParam));
}
// the main Windows entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass; // window class
HWND hwnd; // window handle
MSG msg; // message
bool done; // flag saying when you app is complete
DEVMODE devModeScreen;
DWORD extendedWindowStyle;
DWORD windowStyle;
RECT windowRect; // client area coordinates of the window
// fill out the window class structure
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // default icon
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // default arrow
windowClass.hbrBackground = NULL; // don't need background
windowClass.lpszMenuName = NULL; // no menu
windowClass.lpszClassName = "MyClass";
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // small icon
// register the window class
if (!RegisterClassEx(&windowClass))
return 0;
if (fullScreen==true)
{
//set display to full-screen
memset(&devModeScreen, 0, sizeof(devModeScreen)); // clear the DEVMODE structure
devModeScreen.dmSize = sizeof(devModeScreen); // size of the structure
devModeScreen.dmPelsWidth = 800; // set the width 1152
devModeScreen.dmPelsHeight = 600; // set the height 864
devModeScreen.dmBitsPerPel = 32; // set the bits per pixel
devModeScreen.dmFields = DM_PELSWIDTH |DM_PELSHEIGHT | DM_BITSPERPEL;
if (ChangeDisplaySettings(&devModeScreen, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
// change has failed, you'll run in windowed mode
fullScreen = false;
}
if (fullScreen)
{
extendedWindowStyle = WS_EX_APPWINDOW; // hide top level windows
windowStyle = WS_POPUP; // no border on your window
ShowCursor(false);
}
else
{
extendedWindowStyle = NULL; // same as earlier example
windowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE |
WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
}
// readjust window
windowRect.top = 0; // top left
windowRect.left = 0;
windowRect.bottom = 600;
windowRect.right = 800;
AdjustWindowRectEx(&windowRect, windowStyle, false, extendedWindowStyle);
// class registered, so now create your window
hwnd = CreateWindowEx( extendedWindowStyle, // extended style
"MyClass", // class name
"The OpenGL Window Applicaion", // app name
windowStyle, // style
0, 0, // x,y coordinate
windowRect.right - windowRect.left, // width
windowRect.bottom - windowRect.top, // height
NULL, // handle to parent
NULL, // handle to menu
hInstance, // application instance
NULL); // no extra params
// check if window creation failed (hwnd would equal NULL)
if (!hwnd)
return 0;
ShowWindow(hwnd, SW_SHOW); // display the window
UpdateWindow(hwnd); // update the window
done = false; // initialize the loop condition variable
imageData = NULL;
// main message loop
while (!done)
{
PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);
if (msg.message == WM_QUIT) // do you receive a WM_QUIT message?
{
done = true; // if so, time to quit the application
}
else
{
// do rendering here
// clear screen and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // reset modelview matrix
angle = angle + 5.0f; // increase your rotation angle counter
if (angle >= 360.0f) // reset angle counter
angle = 0.0f;
glTranslatef(0.0f, 0.0f, -5.0f); //move back 5 units
glRotatef(angle, 0.0f, 1.0f, 0.0f); //rotate along z-axis
glColor3f(1.0f, 0.0f, 0.0f); // set color to red
glBegin(GL_TRIANGLES); // draw the triangle
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glEnd();
//glRasterPos3i(intX, intY, -50);
//glReadPixels(intX, intY, intWidth, intHeight, GL_RGB, GL_UNSIGNED_BYTE, uchrImageData);
//glDrawPixels(intWidth, intHeight, GL_RGB, GL_UNSIGNED_BYTE, uchrImageData);
imageData = new unsigned char [42*42*3];
memset(imageData, 0, 42 * 42 * 3); // clear the allocated memory
glReadPixels(400, 300, 42, 42, GL_RGB, GL_UNSIGNED_BYTE, imageData);
delete [] imageData;
SwapBuffers(g_HDC); // bring back buffer to foreground
TranslateMessage(&msg); // translate/dispatch to event queue
DispatchMessage(&msg);
}
}
return msg.wParam;
}
delete problem after using glReadPixels
Hi! Newbie alert! I'm just starting to learn OpenGL programming and ran into something I've been banging my head on for almost a week now. My code below simply renders a rotating triangle. I wanted to try and capture some of the frames and save it on bmp files but I'm having trouble with delete [] (at the end of the code, inside the main loop). If I simply create a pointer to an array of unsigned char and just delete it every iteration, no problem. But if I place the glReadPixels call in between I get a problem saying
Debug Error!
Program: ...\HomeTest.exe
DAMAGE: after Normal block (#39) at 0x028551C0
I'm stumped. Can anybody help me please? I included the whole code so you might see any mistakes I made in setting up OpenGL.
You did not take the data-alignment into account. Read up about glPixelStore for more information.
In short what happens is, that the rows are aligned to 4 bytes. So, if i.e. your row is 3 pixel wide, it only has 3 * 3 = 9 bytes. Than it is aligned to the next multiple of 4, in this case to 12 bytes. Instead of your expected 9 bytes every row of your pixeldata takes up 12 bytes with 3 bytes padded.
Solutions:
1. Change the Alignment with glPixelStore
2. Change your buffer to take the padding into account.
In short what happens is, that the rows are aligned to 4 bytes. So, if i.e. your row is 3 pixel wide, it only has 3 * 3 = 9 bytes. Than it is aligned to the next multiple of 4, in this case to 12 bytes. Instead of your expected 9 bytes every row of your pixeldata takes up 12 bytes with 3 bytes padded.
Solutions:
1. Change the Alignment with glPixelStore
2. Change your buffer to take the padding into account.
Bullseye! It finally worked!!! Both solutions worked like a charm. I used GL_PACK_ALIGNMENT = 1 and GL_UNPACK_ALIGNMENT = 1 (for glDrawPixels). What I still don't get is why using =3 (since I have a pixelwidth of 3) doesn't work. Hmm... You're right that I don't know much about glPixelStorei and to tell you the truth I'm still trying to digest your explanation but I think I get the gist of it. I'll take your advice and read up on it.
Hope you can help me next time I'm in a rut. Thanks!!!
Hope you can help me next time I'm in a rut. Thanks!!!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement