glsl实现图像2DFFT
来源:互联网 发布:大数据的关键技术是 编辑:程序博客网 时间:2024/05/29 08:35
gpgpu.cpp
#include <windows.h>
#include <gl/glew.h>
#define FFT_LEVEL 11
#define TEX_SIZE (1<<FFT_LEVEL)
void main(void)
{
unsigned int fb,texReal[2],texImage[2];
unsigned int fs,prg;
unsigned char bmpHead[54];
unsigned char *tex;
HANDLE fin,fout,fCode;
char *code;
unsigned int len,i;
unsigned int real,image,level,state;
unsigned int buffers[2];
unsigned long flag;
PIXELFORMATDESCRIPTOR pfd;
unsigned int pf;
WNDCLASS wc;
HDC hDC;
HGLRC hRC;
HWND hWnd;
//OpenGL初始化
ZeroMemory(&wc,sizeof(WNDCLASS));
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = GetModuleHandle(0);
wc.lpszClassName = "GPGPU";
ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
RegisterClass(&wc);
hWnd=CreateWindow("GPGPU","GPGPU",0,0,0,0,0,0,0,wc.hInstance,0);
hDC=GetDC(hWnd);
pf=ChoosePixelFormat(hDC,&pfd);
SetPixelFormat(hDC,pf,&pfd);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
glViewport(0,0,TEX_SIZE,TEX_SIZE);
//GLSL初始化
glewInit();
fCode = CreateFile("2dfft.fs",GENERIC_READ,0,0,OPEN_EXISTING,0,0);
len = GetFileSize(fCode,&flag);
code = new char[len];
ReadFile(fCode,code,len,&flag,0);
CloseHandle(fCode);
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs,1,(const char**)&code,0);
glCompileShader(fs);
prg = glCreateProgram();
glAttachShader(prg,fs);
glLinkProgram(prg);
state = glGetUniformLocation(prg,"state");
level = glGetUniformLocation(prg,"level");
real = glGetUniformLocation(prg,"real");
image = glGetUniformLocation(prg,"image");
glUseProgram(prg);
delete []code;
//纹理初始化
glEnable(GL_TEXTURE_2D);
glGenTextures(2,texReal);
glGenTextures(2,texImage);
fin = CreateFile("in.bmp",GENERIC_READ,0,0,OPEN_EXISTING,0,0);
tex = new unsigned char[3*TEX_SIZE*TEX_SIZE];
ReadFile(fin,bmpHead,54,&flag,0);
ReadFile(fin,tex,3*TEX_SIZE*TEX_SIZE,&flag,0);
CloseHandle(fin);
glBindTexture(GL_TEXTURE_2D,texReal[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TEX_SIZE, TEX_SIZE, 0, GL_BGR, GL_UNSIGNED_BYTE, tex);
ZeroMemory(tex,3*TEX_SIZE*TEX_SIZE);
glBindTexture(GL_TEXTURE_2D,texReal[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TEX_SIZE, TEX_SIZE, 0, GL_BGR, GL_UNSIGNED_BYTE, tex);
glBindTexture(GL_TEXTURE_2D,texImage[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TEX_SIZE, TEX_SIZE, 0, GL_BGR, GL_UNSIGNED_BYTE, tex);
glBindTexture(GL_TEXTURE_2D,texImage[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TEX_SIZE, TEX_SIZE, 0, GL_BGR, GL_UNSIGNED_BYTE, tex);
//离屏缓冲初始化
glGenFramebuffers(1,&fb);
glBindFramebuffer(GL_FRAMEBUFFER,fb);
buffers[0] = GL_COLOR_ATTACHMENT0;
buffers[1] = GL_COLOR_ATTACHMENT1;
glUniform1i(real,0);
glUniform1i(image,1);
flag = 1;
//横向重排序
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,1);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//横向FFT
for(i=1;i<=FFT_LEVEL;i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,2);
glUniform1i(level,i);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
}
//纵向重排序
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,3);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//纵向FFT
for(i=1;i<=FFT_LEVEL;i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,4);
glUniform1i(level,i);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
}
//低通滤波
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,7);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//求共轭
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,5);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//横向重排序
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,1);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//横向FFT
for(i=1;i<=FFT_LEVEL;i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,2);
glUniform1i(level,i);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
}
//纵向重排序
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,3);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//纵向FFT
for(i=1;i<=FFT_LEVEL;i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,4);
glUniform1i(level,i);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
}
//归一化
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[0],GL_TEXTURE_2D,texReal[flag],0);
glFramebufferTexture2D(GL_FRAMEBUFFER,buffers[1],GL_TEXTURE_2D,texImage[flag],0);
glDrawBuffers(2,buffers);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texImage[1-flag]);
glUniform1i(state,6);
glUniform1i(level,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-1,-1);
glTexCoord2f(1.0f,0.0f);glVertex2f(1,-1);
glTexCoord2f(1.0f,1.0f);glVertex2f(1,1);
glTexCoord2f(0.0f,1.0f);glVertex2f(-1,1);
glEnd();
flag = 1 - flag;
//取回纹理数据
glBindTexture(GL_TEXTURE_2D,texReal[1-flag]);
glGetTexImage(GL_TEXTURE_2D,0,GL_BGR,GL_UNSIGNED_BYTE,tex);
fout = CreateFile("out.bmp",GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0);
WriteFile(fout,bmpHead,54,&flag,0);
WriteFile(fout,tex,3*TEX_SIZE*TEX_SIZE,&flag,0);
CloseHandle(fout);
delete [] tex;
//释放OpenGL相关变量
glDeleteShader(fs);
glDeleteProgram(prg);
glDeleteTextures(2,texReal);
glDeleteTextures(2,texImage);
glDeleteFramebuffers(1,&fb);
}
2DFFT.FS
uniform int state;
uniform int level;
uniform sampler2D real;
uniform sampler2D image;
void main(void)
{
int coordInt,newCoordInt,texSize,i,bfSize,dist;
float angle;
vec4 hr,hi,gr,gi;
if(state == 1)
{
texSize = textureSize(real,0).x;
coordInt = int(gl_TexCoord[0].s * float(texSize));
newCoordInt = 0;
for(i=2;i<texSize;i<<=1)
{
newCoordInt += coordInt & 1;
newCoordInt <<= 1;
coordInt >>= 1;
}
newCoordInt += coordInt & 1;
gl_FragData[0] = texture2D(real,vec2(float(newCoordInt)/float(texSize),gl_TexCoord[0].t));
gl_FragData[1] = texture2D(image,vec2(float(newCoordInt)/float(texSize),gl_TexCoord[0].t));
}
else if(state == 2)
{
bfSize = (1 << level);
texSize = textureSize(real,0).x;
coordInt = int(gl_TexCoord[0].s * float(texSize));
if( (coordInt & (bfSize/2) ) == 0 )
{
newCoordInt = coordInt + bfSize/2;
dist = (coordInt % (bfSize/2));
angle = float(dist) * 6.2832 / float(bfSize);
gr = texture2D(real,gl_TexCoord[0].st);
gi = texture2D(image,gl_TexCoord[0].st);
hr = texture2D(real,vec2(float(newCoordInt)/float(texSize),gl_TexCoord[0].t));
hi = texture2D(image,vec2(float(newCoordInt)/float(texSize),gl_TexCoord[0].t));
gl_FragData[0] = gr + cos(angle) * hr + sin(angle) * hi;
gl_FragData[1] = gi - sin(angle) * hr + cos(angle) * hi;
}
else
{
newCoordInt = coordInt - bfSize/2;
dist = (newCoordInt % (bfSize/2));
angle = float(dist) * 6.2832 / float(bfSize);
gr = texture2D(real,vec2(float(newCoordInt)/float(texSize),gl_TexCoord[0].t));
gi = texture2D(image,vec2(float(newCoordInt)/float(texSize),gl_TexCoord[0].t));
hr = texture2D(real,gl_TexCoord[0].st);
hi = texture2D(image,gl_TexCoord[0].st);
gl_FragData[0] = gr - cos(angle) * hr - sin(angle) * hi;
gl_FragData[1] = gi + sin(angle) * hr - cos(angle) * hi;
}
}
else if(state == 3)
{
texSize = textureSize(real,0).x;
coordInt = int(gl_TexCoord[0].t * float(texSize));
newCoordInt = 0;
for(i=2;i<texSize;i<<=1)
{
newCoordInt += coordInt & 1;
newCoordInt <<= 1;
coordInt >>= 1;
}
newCoordInt += coordInt & 1;
gl_FragData[0] = texture2D(real,vec2(gl_TexCoord[0].s,float(newCoordInt)/float(texSize)));
gl_FragData[1] = texture2D(image,vec2(gl_TexCoord[0].s,float(newCoordInt)/float(texSize)));
}
else if(state == 4)
{
bfSize = (1 << level);
texSize = textureSize(real,0).y;
coordInt = int(gl_TexCoord[0].t * float(texSize));
if( (coordInt & (bfSize/2) ) == 0 )
{
newCoordInt = coordInt + bfSize/2;
dist = (coordInt % (bfSize/2));
angle = float(dist) * 6.2832 / float(bfSize);
gr = texture2D(real,gl_TexCoord[0].st);
gi = texture2D(image,gl_TexCoord[0].st);
hr = texture2D(real,vec2(gl_TexCoord[0].s,float(newCoordInt)/float(texSize)));
hi = texture2D(image,vec2(gl_TexCoord[0].s,float(newCoordInt)/float(texSize)));
gl_FragData[0] = gr + cos(angle) * hr + sin(angle) * hi;
gl_FragData[1] = gi - sin(angle) * hr + cos(angle) * hi;
}
else
{
newCoordInt = coordInt - bfSize/2;
dist = (newCoordInt % (bfSize/2));
angle = float(dist) * 6.2832 / float(bfSize);
gr = texture2D(real,vec2(gl_TexCoord[0].s,float(newCoordInt)/float(texSize)));
gi = texture2D(image,vec2(gl_TexCoord[0].s,float(newCoordInt)/float(texSize)));
hr = texture2D(real,gl_TexCoord[0].st);
hi = texture2D(image,gl_TexCoord[0].st);
gl_FragData[0] = gr - cos(angle) * hr - sin(angle) * hi;
gl_FragData[1] = gi + sin(angle) * hr - cos(angle) * hi;
}
}
else if(state == 5)
{
gl_FragData[0] = texture2D(real,gl_TexCoord[0].st) ;
gl_FragData[1] = -texture2D(image,gl_TexCoord[0].st) ;
}
else if(state == 6)
{
texSize = textureSize(real,0).x;
gl_FragData[0] = texture2D(real,gl_TexCoord[0].st) / (float(texSize) * float(texSize));
gl_FragData[1] = texture2D(image,gl_TexCoord[0].st) / (float(texSize) *float(texSize));
}
else if(state == 7)
{
if(gl_TexCoord[0].s > 0.02f && gl_TexCoord[0].s < 0.98f || gl_TexCoord[0].t > 0.02f && gl_TexCoord[0].t < 0.98f)
{
gl_FragData[0] = vec4(0.0,0.0,0.0,0.0);
gl_FragData[1] = vec4(0.0,0.0,0.0,0.0);
}
else
{
gl_FragData[0] = texture2D(real,gl_TexCoord[0].st);
gl_FragData[1] = texture2D(image,gl_TexCoord[0].st);
}
}
}
in.bmp
任意准备一副2048*2048的24位位图,文件名为in.bmp
- glsl实现图像2DFFT
- GLSL实现图像处理
- GLSL实现图像处理
- GLSL实现图像处理
- GLSL实现图像处理
- Shader特效——“Voronoi 图像”的实现 【GLSL】
- GLSL 图像处理
- GLSL核心课程---纹理图像
- GLSL核心课程---纹理图像
- GLSL实现Glow效果
- GLSL实现Ambient Occlusion
- GLSL实现Image Filter
- GLSL实现HDR Rendering
- GLSL实现Interactive Fluid
- GLSL实现Glow效果
- GLSL实现Ambient Occlusion
- GLSL实现Image Filter
- GLSL实现HDR Rendering
- 学习Ubuntu的那个地方
- 查找链表中倒数第 k个结点
- RAC集群
- 求二元查找树的镜像
- 嵌入SQL/C语言---(informix)
- glsl实现图像2DFFT
- C语言中嵌入式SQL语句
- FLEX内存优化技巧集合
- Java设计模式--单例模式2
- linux环境下oracle版本升级(10.2.0.1-10.2.0.4)
- Linux 共享库: LD_LIBRARY_PATH 与ld.so.conf
- 数据挖掘
- JSTL标签库
- ldconfig命令详细介绍