0xAA55 发表于 2014-9-14 20:02:31

【屏保】某扭曲效果的屏保

这个程序用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:

小鴻 发表于 2014-9-14 20:54:24

哈哈,不會吧,被我沙發了哈哈...

感謝AA55老大哈哈...

Jackeriss 发表于 2014-9-15 13:46:43

简直不能更吊!
页: [1]
查看完整版本: 【屏保】某扭曲效果的屏保