【屏保】某扭曲效果的屏保
这个程序用OpenGL编写。使用了OpenGL EW库,在Windows上使用了高版本的OpenGL,因此需要一个glew32.dll原理很简单。全屏截一张图。然后使用Fragment Shader也就是块着色器将其中的纹理坐标全部扭一边就行啦。
注意是会动的哦。它会一直在那儿鬼畜,直到你把它干掉为止。
按Alt+F4退出。切记是Alt+F4
#define GLEW_STATIC/*使用静态glew库*/
#include<stdio.h>
#include<GL/glew.h>
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
WNDCLASSEX g_WCEx=
{
sizeof(WNDCLASSEX),
0,
(WNDPROC)WndProc,
0,
0,
NULL,//hInstance
NULL,//hIcon
NULL,//hCursor
(HBRUSH)(COLOR_BTNFACE+1),
NULL,//Menu name
TEXT("FuckingWave"),
NULL
};
HWND g_hWnd=NULL;
HDC g_hDC=NULL;//窗口的绘图句柄
HGLRC g_hRC=NULL;//OpenGL句柄
GLuint g_uTex;//纹理
GLuint g_uProgram;//着色器程序
GLuint g_uUniform_g_fTime;
UINT g_uWidth;
UINT g_uHeight;
//=============================================================================
//Get2ndValue:
//取得最小的大于Val的2的N次方数
//-----------------------------------------------------------------------------
GLsizei Get2ndValue(GLsizei Val)
{
GLsizei Ret=1;
while(Ret<Val)
Ret<<=1;
return Ret;
}
//=============================================================================
//CreateFullScreenWindow:
//创建全屏窗口
//-----------------------------------------------------------------------------
BOOL CreateFullScreenWindow()
{
ATOM aClass;
g_WCEx.hInstance=GetModuleHandle(NULL);
g_WCEx.hCursor=LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW));
aClass=RegisterClassEx(&g_WCEx);
if(!aClass)
return FALSE;
g_uWidth=GetSystemMetrics(SM_CXSCREEN);
g_uHeight=GetSystemMetrics(SM_CYSCREEN);
g_hWnd=CreateWindowEx(0,(LPCTSTR)aClass,TEXT(""),WS_POPUP|WS_SYSMENU,
0,0,g_uWidth,g_uHeight,
NULL,NULL,g_WCEx.hInstance,NULL);
if(!g_hWnd)
return FALSE;
return TRUE;
}
//=============================================================================
//InitGL:
//初始化图形库
//-----------------------------------------------------------------------------
void ShowShaderOutput(GLuint uProgram)
{
GLsizei Length;
glGetProgramiv(uProgram,GL_INFO_LOG_LENGTH,&Length);
if(Length)
{
GLsizei BytesRet;
char*pBuffer=(char*)malloc(Length);
if(!pBuffer)
return;
glGetProgramInfoLog(uProgram,Length,&BytesRet,pBuffer);
if(strlen(pBuffer))
fprintf(stderr,"Shader Output:\n%s\n",pBuffer);
free(pBuffer);
}
}
void CleanupGL()
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(g_hRC);
}
BOOL InitGL(HWND hWnd)
{
PIXELFORMATDESCRIPTOR PFD={0};
int nPixelFormat;
BITMAPINFOHEADER BMIF={0};//BMP信息头
void *pBits=NULL;//BMP位图
size_t Pitch;//位图数据每行字节数
size_t cbBytes;//位图数据总字节数
HDC hScreenDC;//屏幕绘图句柄
HDC hBufferDC;//缓冲区绘图句柄
HBITMAP hBMPDC;//缓冲区位图
//取得屏幕绘图句柄
hScreenDC=GetDC(NULL);
if(!hScreenDC)
goto Cleanup;
//颜色数据是红绿蓝:8:8:8,因此每个像素3个字节
//但是BMP位图规定每行字节数必须是4的倍数
Pitch=((g_uWidth*3-1)/4+1)*4;
//总字节数
cbBytes=Pitch*g_uHeight;
BMIF.biSize=sizeof(BMIF);
BMIF.biWidth=g_uWidth;
BMIF.biHeight=g_uHeight;
BMIF.biPlanes=1;
BMIF.biBitCount=24;
BMIF.biSizeImage=cbBytes;
//建立缓冲区
hBufferDC=CreateCompatibleDC(NULL);
if(!hBufferDC)
goto Cleanup;
hBMPDC=CreateDIBSection(hBufferDC,(LPBITMAPINFO)&BMIF,DIB_RGB_COLORS,&pBits,NULL,0);
if(!hBMPDC)
goto Cleanup;
SelectObject(hBufferDC,hBMPDC);
g_hDC=GetDC(hWnd);
//画到缓冲区
BitBlt(hBufferDC,0,0,g_uWidth,g_uHeight,hScreenDC,0,0,SRCCOPY);
BitBlt(g_hDC,0,0,g_uWidth,g_uHeight,hScreenDC,0,0,SRCCOPY);
PFD.nSize =sizeof(PFD);
PFD.nVersion =1;
PFD.dwFlags =PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
PFD.iPixelType=PFD_TYPE_RGBA;
PFD.cDepthBits=0;
PFD.cBlueBits =8; PFD.cBlueShift=16;
PFD.cGreenBits=8; PFD.cGreenShift =8;
PFD.cRedBits =8; PFD.cRedShift =0;
PFD.iLayerType=PFD_MAIN_PLANE;
nPixelFormat=ChoosePixelFormat(g_hDC,&PFD);
SetPixelFormat(g_hDC,nPixelFormat,&PFD);
g_hRC=wglCreateContext(g_hDC);
if(!g_hRC)
goto Cleanup;
wglMakeCurrent(g_hDC,g_hRC);
glewInit();
glViewport(0,0,g_uWidth,g_uHeight);
glGenTextures(1,&g_uTex);
glBindTexture(GL_TEXTURE_2D,g_uTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,g_uWidth,g_uHeight,0,GL_RGB,GL_UNSIGNED_BYTE,pBits);
glBindTexture(GL_TEXTURE_2D,0);
DeleteDC(hBufferDC);
ReleaseDC(NULL,hScreenDC);
{
GLsizei VS,FS;
GLchar szVS[]=
"varying vec2 TexCoord;"
"void main()"
"{"
" TexCoord=gl_MultiTexCoord0.xy;"
" gl_Position=gl_Vertex;"
"}";
GLchar szFS[]=
"uniform float g_fTime;"
"uniform sampler2D tex;"
"const float PI=3.1415926535897932384626433832795;"
"varying vec2 TexCoord;"
"void main()"
"{"
" float ftime=g_fTime*0.5;"
" vec2 tcoord=vec2(TexCoord.x+sin((ftime+(TexCoord.x+TexCoord.y)*10.0)*PI)*0.01,TexCoord.y+cos((ftime+(TexCoord.x+TexCoord.y)*10.0)*PI)*0.01);"
" vec4 vOrgColor=texture2D(tex,tcoord);"
" gl_FragColor.x=vOrgColor.z*vOrgColor.a;"
" gl_FragColor.y=vOrgColor.y*vOrgColor.a;"
" gl_FragColor.z=vOrgColor.x*vOrgColor.a;"
" gl_FragColor.a=vOrgColor.a;"
"}";
GLint sizeVS=sizeof(szVS);
GLint sizeFS=sizeof(szFS);
GLchar*pszVS=szVS;
GLchar*pszFS=szFS;
g_uProgram=glCreateProgram();
VS=glCreateShader(GL_VERTEX_SHADER);
FS=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(VS,1,&pszVS,&sizeVS);
glShaderSource(FS,1,&pszFS,&sizeFS);
glCompileShader(VS);
glCompileShader(FS);
glAttachShader(g_uProgram,VS);
glAttachShader(g_uProgram,FS);
glLinkProgram(g_uProgram);
ShowShaderOutput(g_uProgram);
g_uUniform_g_fTime=glGetUniformLocation(g_uProgram,"g_fTime");
}
wglMakeCurrent(NULL,NULL);
return TRUE;
Cleanup:
DeleteDC(hBufferDC);
ReleaseDC(NULL,hScreenDC);
CleanupGL();
return FALSE;
}
void RenderOnce()
{
if(!g_hRC)
return;
wglMakeCurrent(g_hDC,g_hRC);
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(g_uUniform_g_fTime,(GLfloat)GetTickCount()*0.01f);
//=========================================================================
//BGR转RGB
glBindTexture(GL_TEXTURE_2D,g_uTex);
glUseProgram(g_uProgram);
//画一个全屏BillBoard,使用着色器程序
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0,0);glVertex2f(-1,-1);
glTexCoord2f(1,0);glVertex2f( 1,-1);
glTexCoord2f(0,1);glVertex2f(-1, 1);
glTexCoord2f(1,1);glVertex2f( 1, 1);
glEnd();
glFlush();
glBindTexture(GL_TEXTURE_2D,0);
SwapBuffers(g_hDC);
wglMakeCurrent(NULL,NULL);
}
int main(int argc,char**argv)
{
MSG msg;
Sleep(200);
if(!CreateFullScreenWindow())
{
fputs("创建全屏窗口失败。\n",stderr);
return 1;
}
ShowWindow(g_hWnd,SW_SHOW);
UpdateWindow(g_hWnd);
for(;;)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
RenderOnce();
}
CleanupGL();
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wp,LPARAM lp)
{
switch(uMsg)
{
default:
return DefWindowProc(hWnd,uMsg,wp,lp);
case WM_CREATE:
InitGL(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
}BIN:
新版本编译器生成:
老版本编译器生成:
SRC: 哈哈,不會吧,被我沙發了哈哈...
感謝AA55老大哈哈... 简直不能更吊!
页:
[1]