⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 butterflyscreensaver.cpp

📁 这个屏保程序是基于c++下面的用OpenGL语言开发的
💻 CPP
字号:

#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>	
#include <gl\gl.h>
#include <gl\glu.h>	
#include <scrnsave.h>
#include "resource.h"

GLuint texture[3];

HDC				hDC=NULL;
HGLRC			hRC=NULL;
HWND			hWnd=NULL;	
HINSTANCE		hInstance;

DEVMODE			DMsaved;
UINT			uTimer;	

struct object						// 定义一个对象结构体(蝴蝶)
{
	int   tex;						// 纹理ID
	float x;						// X 坐标
	float y;						// Y 坐标
	float z;						// Z 坐标
	float yi;						// Y 速度
	float spinz;					// Z 轴旋转
	float spinzi;					// Z 轴旋转速度
	float flap;						// 翼拍打的面片,用于绘制
	float fi;						// 翼拍打的方向
};

object obj[50];						// 创建50个对象

void SetObject(int loop)			// 设置对象的初始属性(随机)
{
	obj[loop].tex=rand()%3;	
	obj[loop].x=rand()%34-17.0f;
	obj[loop].y=18.0f;	
	obj[loop].z=-((rand()%30000/1000.0f)+10.0f);
	obj[loop].spinzi=(rand()%10000)/5000.0f-1.0f;
	obj[loop].flap=0.0f;	
	obj[loop].fi=0.05f+(rand()%100)/1000.0f;
	obj[loop].yi=0.001f+(rand()%1000)/10000.0f;	
}

void LoadGLTextures()				// 生成纹理ID
{
	HBITMAP hBMP;	
	BITMAP	BMP;

	byte	Texture[]={	IDB_BUTTERFLY1,	IDB_BUTTERFLY2,	IDB_BUTTERFLY3 };

	glGenTextures(sizeof(Texture), &texture[0]);
	for (int loop=0; loop<sizeof(Texture); loop++)	
	{
		hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(Texture[loop]), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
		if (hBMP)		
		{										
			GetObject(hBMP,sizeof(BMP), &BMP);
			glPixelStorei(GL_UNPACK_ALIGNMENT,4);
			glBindTexture(GL_TEXTURE_2D, texture[loop]);					// 捆绑纹理
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	// 线性过滤
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
			gluBuild2DMipmaps(GL_TEXTURE_2D, 3, BMP.bmWidth, BMP.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);
		}
	}
}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		// 缩放OpenGL窗口
{
	if (height==0)		
	{
		height=1;	
	}

	glViewport(0,0,width,height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();	
	gluPerspective (45.0f, (GLfloat)(width)/(GLfloat)(height),1.0f, 1000.0f);		
	glMatrixMode(GL_MODELVIEW);	
	glLoadIdentity();	
}

int InitGL(GLvoid)											// 初始化OpenGL
{
	LoadGLTextures();										// 装入纹理
	glClearColor (0.0f, 0.0f, 0.0f, 0.5f);					// 黑色背景
	glClearDepth (1.0f);
	glDepthFunc (GL_LEQUAL);
	glDisable(GL_DEPTH_TEST);
	glShadeModel (GL_SMOOTH);
	glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	
	glEnable(GL_TEXTURE_2D);								// 2D纹理映射
	glBlendFunc(GL_ONE,GL_SRC_ALPHA);	
	glEnable(GL_BLEND);
	
	for (int loop=0; loop<50; loop++)	
	{
		SetObject(loop);									// 生成50个对象
	}
	return TRUE;
}

int DrawGLScene(GLvoid)	            // 绘制场景
{								
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// 清除屏幕和深度缓存
	for (int loop=0; loop<50; loop++)							// 绘制50个对象(蝴蝶)
	{
		glLoadIdentity ();	
		glBindTexture(GL_TEXTURE_2D, texture[obj[loop].tex]);	// 捆绑纹理
		glTranslatef(obj[loop].x,obj[loop].y,obj[loop].z);		// 对象位置
		glRotatef(45.0f,1.0f,0.0f,0.0f);						// 绕X-Axis旋转
		glRotatef((obj[loop].spinz),0.0f,0.0f,1.0f);			// 绕Z-Axis旋转

		glBegin(GL_TRIANGLES);									// 绘制三角形
			// 第一个三角形		
			glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);	
			glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f, obj[loop].flap);
			glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);	

			// 第二个三角形
			glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);	
			glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);	
			glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f,-1.0f, obj[loop].flap);

		glEnd();	

		obj[loop].y-=obj[loop].yi;		
		obj[loop].spinz+=obj[loop].spinzi;	
		obj[loop].flap+=obj[loop].fi;	

		if (obj[loop].y<-18.0f)	
		{
			SetObject(loop);	
		}

		if ((obj[loop].flap>1.0f) || (obj[loop].flap<-1.0f))
		{
			obj[loop].fi=-obj[loop].fi;			
		}
	}
	Sleep(15);			
	glFlush ();	
	return TRUE;
}

GLvoid KillGLWindow(GLvoid)	
{
	if (hRC)											// 如果渲染上下文存在
	{
		if (!wglMakeCurrent(NULL,NULL))					// 渲染上下文设置为空
		{
			MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}

		if (!wglDeleteContext(hRC))						// 删除渲染上下文RC
		{
			MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}
		hRC=NULL;
	}

	if (hDC && !ReleaseDC(hWnd,hDC))					// 释放DC
	{
		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hDC=NULL;
	}
}

BOOL CreateGLWindow(HWND hWnd, int bits)
{
	GLuint		PixelFormat;
	RECT		WindowRect;	
	int width;
	int height;

	hInstance			= GetModuleHandle(NULL);				// 获得窗口句柄

	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DMsaved); // 保存当前的显示状态

	static	PIXELFORMATDESCRIPTOR pfd = { 
	    sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小 
	    1,                                // 版本号 
	    PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图 
	    PFD_SUPPORT_OPENGL |              // 支持 OpenGL 
	    PFD_DOUBLEBUFFER,                 // 双缓存模式 
	    PFD_TYPE_RGBA,                    // RGBA 颜色模式 
	    24,                               // 24 位颜色深度 
	    0, 0, 0, 0, 0, 0,                 // 忽略颜色位 
	    0,                                // 没有非透明度缓存 
	    0,                                // 忽略移位位 
	    0,                                // 无累加缓存 
	    0, 0, 0, 0,                       // 忽略累加位 
	    32,                               // 32 位深度缓存     
	    0,                                // 无模板缓存 
	    0,                                // 无辅助缓存 
	    PFD_MAIN_PLANE,                   // 主层 
	    0,                                // 保留 
	    0, 0, 0                           // 忽略层,可见性和损毁掩模 
	}; 		
	
	if (!(hDC=GetDC(hWnd)))							// 获得设备上下文
	{
		KillGLWindow();							
		MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回FALSE
	}

	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	// 选择合适的像素格式
	{
		KillGLWindow();	
		MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回FALSE
	}

	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		// 设置像素格式
	{
		KillGLWindow();	
		MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回FALSE
	}

	if (!(hRC=wglCreateContext(hDC)))				// 获取绘制上下文
	{
		KillGLWindow();	
		MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回FALSE
	}

	if(!wglMakeCurrent(hDC,hRC))					// 激活绘制上下文
	{
		KillGLWindow();
		MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回FALSE
	}

    GetClientRect (hWnd, &WindowRect); 
	
	width = WindowRect.right - WindowRect.left;
	height = WindowRect.bottom - WindowRect.top;
	ReSizeGLScene(width, height);


    if (!InitGL())									// 初始化OpenGL窗口
	{
		KillGLWindow();	
		MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 出错,返回FALSE
	}

	return TRUE;									// 成功,返回Success
}

LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, 
					 WPARAM wParam, LPARAM lParam) 
{

	switch (message)								// 检查Windows消息
	{
        case WM_CREATE:
		{
			if (!CreateGLWindow(hWnd,16))
			{
				return -1;									
			}
            uTimer = SetTimer(hWnd, 1, 10, NULL); 
			return 0;
		}

        case WM_TIMER: 
			DrawGLScene();                      
			SwapBuffers(hDC);					
			break;

        case WM_DESTROY: 
            if (uTimer) 
                KillTimer(hWnd, uTimer); 
			KillGLWindow();									
			glDeleteTextures(3,texture);
            break; 
	}

    return DefScreenSaverProc(hWnd, message, wParam, lParam); 
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, 
								WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_INITDIALOG:
		return TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDOK:
			EndDialog(hDlg, TRUE);
			return TRUE;
		}
	}

	return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -