📄 window.cpp
字号:
else
errorLog.OutputSuccess("DC and RC released.");
if(!wglDeleteContext(hRC)) //try to delete RC
{
errorLog.OutputError("Release Rendering Context Failed.");
}
else
errorLog.OutputSuccess("Rendering Context Released.");
hRC=NULL; //set RC to NULL
}
if(hDC && !ReleaseDC(hWnd, hDC)) //Are we able to release DC?
{
errorLog.OutputError("Release of Device Context Failed.");
hDC=NULL;
}
else
errorLog.OutputSuccess("Device Context Released.");
if(hWnd && !DestroyWindow(hWnd)) //Can we destroy window?
{
errorLog.OutputError("Could not release hWnd");
hWnd=NULL;
}
else
errorLog.OutputSuccess("hWnd released.");
if (!UnregisterClass("OpenGL", hInstance)) //can we unreg. class?
{
errorLog.OutputError("Could Not Unregister Class.");
hInstance=NULL;
}
else
errorLog.OutputSuccess("Class unregistered.");
}
//DEAL WITH ALL WINDOW MESSAGES
//Message Pump
bool WINDOW::HandleMessages(void)
{
while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //Is there a message waiting?
{
if(msg.message==WM_QUIT)
return false; //if a quit message, return false
//handle input
if(msg.message==WM_KEYDOWN)
SetKeyPressed(msg.wParam);
if(msg.message==WM_KEYUP)
SetKeyReleased(msg.wParam);
if(msg.message==WM_LBUTTONDOWN)
SetLeftButtonPressed();
if(msg.message==WM_RBUTTONDOWN)
SetRightButtonPressed();
TranslateMessage(&msg); //Translate Message
DispatchMessage(&msg); //dispatch message
}
return true;
}
LRESULT CALLBACK WINDOW::WndProc( HWND hWnd, //handle for this window
UINT uMsg, //Message for this window
WPARAM wParam, //Additional message information
LPARAM lParam) //Additional Message information
{
switch (uMsg) //check for windows messages
{
case WM_SYSCOMMAND: //Intercept system commands
{
switch (wParam) //check system calls
{
case SC_SCREENSAVE: //screensaver trying to start?
case SC_MONITORPOWER: //monitor trying to enter powersave?
return 0; //prevent from happening
}
break;
}
case WM_CLOSE: //receive close message?
PostQuitMessage(0); //send quit message
return 0; //quit back
break;
}
//pass all unhandled messages to DefWindowProc, windows can handle
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
void WINDOW::SwapBuffers(void)
{
::SwapBuffers(hDC); //swap buffers
}
//void WINDOW::CheckGLError - check for an opengl error
void WINDOW::CheckGLError(void)
{
GLenum error;
error=glGetError();
if(!(error==GL_NO_ERROR))
{
errorLog.OutputError("OpenGL Error:");
if(error==GL_INVALID_ENUM)
{
errorLog.OutputError(" GL_INVALID_ENUM");
errorLog.OutputError(" GLenum Argument out of range.");
}
if(error==GL_INVALID_VALUE)
{
errorLog.OutputError(" GL_INVALID_VALUE");
errorLog.OutputError(" Numeric Argument out of range.");
}
if(error==GL_INVALID_OPERATION)
{
errorLog.OutputError(" GL_INVALID_OPERATION");
errorLog.OutputError(" Invalid Operation in current state.");
}
if(error==GL_STACK_UNDERFLOW)
{
errorLog.OutputError(" GL_STACK_UNDERFLOW");
errorLog.OutputError(" Stack Underflow.");
}
if(error==GL_STACK_OVERFLOW)
{
errorLog.OutputError(" GL_STACK_OVERFLOW");
errorLog.OutputError(" Stack Overflow.");
}
if(error==GL_OUT_OF_MEMORY)
{
errorLog.OutputError(" GL_OUT_OF_MEMORY");
errorLog.OutputError(" Out of memory.");
}
}
}
void WINDOW::SaveScreenshot(void)
{
FILE * file;
//first calculate the filename to save to
char filename[32];
for(int i=0; i<1000; i++)
{
sprintf(filename, "screen%03d.tga", i);
//try opening this file - if not possible, use this filename
file=fopen(filename, "rb");
if(!file)
{
break;
}
//otherwise, the file exists, try next, except if this is the last one
fclose(file);
if(i==999)
{
errorLog.OutputError("No space to save screenshot - 0-999 exist");
return;
}
}
errorLog.OutputSuccess("Saving %s", filename);
GLubyte TGAheader[12]={0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Uncompressed TGA header
GLubyte infoHeader[6];
unsigned char * data=new unsigned char[4*width*height];
if(!data)
{
errorLog.OutputError("Unable to allocate memory for screen data");
return;
}
//read in the screen data
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
//data needs to be in BGR format
//swap b and r
for(int i=0; i<(int)width*height*4; i+=4)
{
//repeated XOR to swap bytes 0 and 2
data[i] ^= data[i+2] ^= data[i] ^= data[i+2];
}
//open the file
file = fopen(filename, "wb");
//save header
fwrite(TGAheader, 1, sizeof(TGAheader), file);
//save info header
infoHeader[0]=(width & 0x00FF);
infoHeader[1]=(width & 0xFF00) >> 8;
infoHeader[2]=(height & 0x00FF);
infoHeader[3]=(height & 0xFF00) >> 8;
infoHeader[4]=32;
infoHeader[5]=0;
//save info header
fwrite(infoHeader, 1, sizeof(infoHeader), file);
//save the image data
fwrite(data, 1, width*height*4, file);
fclose(file);
errorLog.OutputSuccess("Saved Screenshot: %s", filename);
return;
}
//Text writing functions
void WINDOW::StartTextMode(void)
{
//If not yet created, make display list
if(!startTextModeList)
{
startTextModeList=glGenLists(1);
glNewList(startTextModeList, GL_COMPILE);
{
//save states
glPushAttrib(GL_ALL_ATTRIB_BITS);
glListBase(base-32); //set the list base
//set modelview matrix
glPushMatrix();
glLoadIdentity();
//set projection matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
//set states
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glBlendFunc(GL_ONE, GL_ONE); //if blending, use additive
}
glEndList();
}
glCallList(startTextModeList);
}
void WINDOW::Print(int x, int y, const char * string, ...)
{
char text[256]; //Holds our string
va_list va; //pointer to list of arguments
if(string==NULL) //If there's no text
return; //Do nothing
va_start(va, string); //parse string for variables
vsprintf(text, string, va); //convert to actual numbers
va_end(va); //results stored in text
glRasterPos2i(x, y); //go to correct raster position
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); //call display lists
}
void WINDOW::EndTextMode(void)
{
//restore states
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
//Update input
void WINDOW::Update()
{
//Mouse buttons are marked as pressed by windows messages
//see if any have been released
if(mouseLDown && !GetAsyncKeyState(VK_LBUTTON))
mouseLDown=false;
if(mouseRDown && !GetAsyncKeyState(VK_RBUTTON))
mouseRDown=false;
//Update the mouse position
static POINT mousePosition;
GetCursorPos(&mousePosition);
oldMouseX=mouseX;
oldMouseY=mouseY;
mouseX=mousePosition.x;
mouseY=mousePosition.y;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -