转自【翻译】NeHe OpenGL 教程

前言

声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改。对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢。

NeHe OpenGL第四十四课:3D光晕

3D 光晕

当镜头对准太阳的时候就会出现这种效果,模拟它非常的简单,一点数学和纹理贴图就够了。好好看看吧。

 

大家好,欢迎来到新的一课,在这一课中我们将扩展glCamera类,来实现镜头光晕的效果。在日常生活中,当我们对着光源看时,会发现强烈的反光。

为了完成这个效果,我们需要一些数学知识。首先,我们需要一些函数,用来检测某个点或球是否在当前的视景体内。接着我们需要一些纹理作为我们的光晕效果,我们可以把它贴在显示面上。

在我的上一个摄像机类里把下面函数写错了,现在修正如下:

 

void glCamera::SetPrespective(){ GLfloat Matrix[16];

glVector v;

// 根据当前的偏转角旋转视线

glRotatef(m_HeadingDegrees, 0.0f, 1.0f, 0.0f);

glRotatef(m_PitchDegrees, 1.0f, 0.0f, 0.0f);

// 返回模型变换矩阵

glGetFloatv(GL_MODELVIEW_MATRIX, Matrix);

// 获得视线的方向

m_DirectionVector.i = Matrix[8];

m_DirectionVector.j = Matrix[9];

m_DirectionVector.k = -Matrix[10];

// 重置矩阵

glLoadIdentity();

// 旋转场景

glRotatef(m_PitchDegrees, 1.0f, 0.0f, 0.0f);

glRotatef(m_HeadingDegrees, 0.0f, 1.0f, 0.0f);

// 设置当前摄像机的位置

v = m_DirectionVector;

v *= m_ForwardVelocity;

m_Position.x += v.i;

m_Position.y += v.j;

m_Position.z += v.k;

// 变换到新的位置

glTranslatef(-m_Position.x, -m_Position.y, -m_Position.z);

}

好了,我们现在开始吧。我将使用4个对立的纹理来制造我们的镜头光晕,第一和二个光晕图像被放置在光源处,第三和第四个图像将根据视点的位置和方向动态的生成。纹理的图像如下所示:



现在你在头脑里应该有了一个大慨地图像了吧。我们来说说何时我们应该绘制光晕,一般来说平时我们是看不见这些光晕的,只有当我们对准光源的时候才能看见这些。所以我们首先要获得视景体的数据,下面的函数可

以帮我们完成这个功能。

 

// 获得当前视景体的6个平面方程的参数void glCamera::UpdateFrustum(){    GLfloat  
clip[16]; GLfloat   proj[16];    GLfloat   modl[16];    GLfloat   t;

//返回投影矩阵

glGetFloatv( GL_PROJECTION_MATRIX, proj );

//返回模型变换矩阵

glGetFloatv( GL_MODELVIEW_MATRIX, modl );

//计算剪切矩阵,即上面两个矩阵的乘积

clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];

clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];

clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];

clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];

clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];

clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];

clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];

clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];

clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];

clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];

clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];

clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];

clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];

clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];

clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];

clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];

//提取右面的平面方程系数

m_Frustum[0][0] = clip[ 3] - clip[ 0];

m_Frustum[0][1] = clip[ 7] - clip[ 4];

m_Frustum[0][2] = clip[11] - clip[ 8];

m_Frustum[0][3] = clip[15] - clip[12];

t = GLfloat(sqrt( m_Frustum[0][0] * m_Frustum[0][0] + m_Frustum[0][1] * m_Frustum[0][1] + m_Frustum[0][2] * m_Frustum[0][2] ));

m_Frustum[0][0] /= t;

m_Frustum[0][1] /= t;

m_Frustum[0][2] /= t;

m_Frustum[0][3] /= t;

//提取左面的平面方程系数

m_Frustum[1][0] = clip[ 3] + clip[ 0];

m_Frustum[1][1] = clip[ 7] + clip[ 4];

m_Frustum[1][2] = clip[11] + clip[ 8];

m_Frustum[1][3] = clip[15] + clip[12];

t = GLfloat(sqrt( m_Frustum[1][0] * m_Frustum[1][0] + m_Frustum[1][1] * m_Frustum[1][1] + m_Frustum[1][2] * m_Frustum[1][2] ));

m_Frustum[1][0] /= t;

m_Frustum[1][1] /= t;

m_Frustum[1][2] /= t;

m_Frustum[1][3] /= t;

//提取下面的平面方程系数

m_Frustum[2][0] = clip[ 3] + clip[ 1];

m_Frustum[2][1] = clip[ 7] + clip[ 5];

m_Frustum[2][2] = clip[11] + clip[ 9];

m_Frustum[2][3] = clip[15] + clip[13];

t = GLfloat(sqrt( m_Frustum[2][0] * m_Frustum[2][0] + m_Frustum[2][1] * m_Frustum[2][1] + m_Frustum[2][2] * m_Frustum[2][2] ));

m_Frustum[2][0] /= t;

m_Frustum[2][1] /= t;

m_Frustum[2][2] /= t;

m_Frustum[2][3] /= t;

//提取上面的平面方程系数

m_Frustum[3][0] = clip[ 3] - clip[ 1];

m_Frustum[3][1] = clip[ 7] - clip[ 5];

m_Frustum[3][2] = clip[11] - clip[ 9];

m_Frustum[3][3] = clip[15] - clip[13];

t = GLfloat(sqrt( m_Frustum[3][0] * m_Frustum[3][0] + m_Frustum[3][1] * m_Frustum[3][1] + m_Frustum[3][2] * m_Frustum[3][2] ));

m_Frustum[3][0] /= t;

m_Frustum[3][1] /= t;

m_Frustum[3][2] /= t;

m_Frustum[3][3] /= t;

//提取远面的平面方程系数

m_Frustum[4][0] = clip[ 3] - clip[ 2];

m_Frustum[4][1] = clip[ 7] - clip[ 6];

m_Frustum[4][2] = clip[11] - clip[10];

m_Frustum[4][3] = clip[15] - clip[14];

t = GLfloat(sqrt( m_Frustum[4][0] * m_Frustum[4][0] + m_Frustum[4][1] * m_Frustum[4][1] + m_Frustum[4][2] * m_Frustum[4][2] ));

m_Frustum[4][0] /= t;

m_Frustum[4][1] /= t;

m_Frustum[4][2] /= t;

m_Frustum[4][3] /= t;

//提取近面的平面方程系数

m_Frustum[5][0] = clip[ 3] + clip[ 2];

m_Frustum[5][1] = clip[ 7] + clip[ 6];

m_Frustum[5][2] = clip[11] + clip[10];

m_Frustum[5][3] = clip[15] + clip[14];

t = GLfloat(sqrt( m_Frustum[5][0] * m_Frustum[5][0] + m_Frustum[5][1] * m_Frustum[5][1] + m_Frustum[5][2] * m_Frustum[5][2] ));

m_Frustum[5][0] /= t;

m_Frustum[5][1] /= t;

m_Frustum[5][2] /= t;

m_Frustum[5][3] /= t;

}

现在我们可以测试一个点或圆是否在视景体内了。下面的函数可以测试一个点是否在视景体内。 

  

BOOL glCamera::PointInFrustum(glPoint p){ int i; for(i = 0; i < 6;
i++) {  if(m_Frustum[i][0] * p.x + m_Frustum[i][1] * p.y +

m_Frustum[i][2] * p.z + m_Frustum[i][3] <= 0)  {   return(FALSE);  } } return(TRUE);}

下面的函数用来测试某个点是否位于当前场景物体的前面:

 

bool glCamera::IsOccluded(glPoint p){ GLint viewport[4];       GLdouble mvmatrix[16], projmatrix[16];

GLdouble winx, winy, winz;     GLdouble flareZ;       GLfloat bufferZ;

glGetIntegerv (GL_VIEWPORT, viewport);

glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);

glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);

// 返回顶点p在单位立方体中的位置

gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport, &winx, &winy, &winz);

flareZ = winz;

// 读取点(winx,winy)的深度坐标

glReadPixels(winx, winy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &bufferZ);

// 如果深度坐标小于点的坐标,则返回true

if (bufferZ < flareZ)

return true;

//否则返回false

else

return false;

}

我们通过检测光源是否正对我们的视线来决定是否绘制光晕,但如果你的视点超过了光源的位置,则会发生看不见光晕的现象。为了避免这种现象,我们在移动视点的使用,也相应的移动我们的光源。为了在视点和光

源之间绘制多个光晕,我们需要计算之间的向量,下面的代码完成这个功能: 

  

//下面的函数完成具体的渲染光晕的任务void glCamera::RenderLensFlare(){ GLfloat Length = 0.0f;

// 如果我们的光源在我们的视线范围内,则绘制它

if(SphereInFrustum(m_LightSourcePos, 1.0f) == TRUE)

{

vLightSourceToCamera = m_Position - m_LightSourcePos; // 计算光源到我们视线的距离

Length = vLightSourceToCamera.Magnitude();

//下面三个函数计算光源位置到光晕结束位置之间的向量

ptIntersect = m_DirectionVector * Length;

ptIntersect += m_Position;

vLightSourceToIntersect = ptIntersect - m_LightSourcePos;

Length = vLightSourceToIntersect.Magnitude();

vLightSourceToIntersect.Normalize();

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE);

glDisable(GL_DEPTH_TEST);

glEnable(GL_TEXTURE_2D);

首先我们需要找到光源位置和视点位置之间的向量,接下来我们需要在视线的方向设置一个插值点,这个点的距离必须和光源位置和视点位置之间的距离相等。完成以后,我们找出可以产生光晕的方向,即下图红线的

方向,在这个线上我们可以绘制我们的光晕。



  if (!IsOccluded(m_LightSourcePos)) //如果光晕可见  {   // 渲染中间的光晕   RenderBigGlow(0.60f,

0.60f, 0.8f, 1.0f, m_LightSourcePos, 16.0f);   RenderStreaks(0.60f, 0.60f, 0.8f, 1.0f, m_LightSourcePos, 16.0f);

RenderGlow(0.8f, 0.8f, 1.0f, 0.5f, m_LightSourcePos, 3.5f);

//绘制到光晕结束位置的0.1处的光晕

pt = vLightSourceToIntersect * (Length * 0.1f);

pt += m_LightSourcePos;

RenderGlow(0.9f, 0.6f, 0.4f, 0.5f, pt, 0.6f);

//绘制到光晕结束位置的0.15处的光晕

pt = vLightSourceToIntersect * (Length * 0.15f);

pt += m_LightSourcePos;

RenderHalo(0.8f, 0.5f, 0.6f, 0.5f, pt, 1.7f);

//绘制到光晕结束位置的0.175处的光晕

pt = vLightSourceToIntersect * (Length * 0.175f);

pt += m_LightSourcePos;

RenderHalo(0.9f, 0.2f, 0.1f, 0.5f, pt, 0.83f);

//绘制到光晕结束位置的0.285处的光晕

pt = vLightSourceToIntersect * (Length * 0.285f);

pt += m_LightSourcePos;

RenderHalo(0.7f, 0.7f, 0.4f, 0.5f, pt, 1.6f);

//绘制到光晕结束位置的0.2755处的光晕

pt = vLightSourceToIntersect * (Length * 0.2755f);

pt += m_LightSourcePos;

RenderGlow(0.9f, 0.9f, 0.2f, 0.5f, pt, 0.8f);

//绘制到光晕结束位置的0.4755处的光晕

pt = vLightSourceToIntersect * (Length * 0.4775f);

pt += m_LightSourcePos;

RenderGlow(0.93f, 0.82f, 0.73f, 0.5f, pt, 1.0f);

//绘制到光晕结束位置的0.49处的光晕

pt = vLightSourceToIntersect * (Length * 0.49f);

pt += m_LightSourcePos;

RenderHalo(0.7f, 0.6f, 0.5f, 0.5f, pt, 1.4f);

//绘制到光晕结束位置的0.65处的光晕

pt = vLightSourceToIntersect * (Length * 0.65f);

pt += m_LightSourcePos;

RenderGlow(0.7f, 0.8f, 0.3f, 0.5f, pt, 1.8f);

//绘制到光晕结束位置的0.63处的光晕

pt = vLightSourceToIntersect * (Length * 0.63f);

pt += m_LightSourcePos;

RenderGlow(0.4f, 0.3f, 0.2f, 0.5f, pt, 1.4f);

//绘制到光晕结束位置的0.8处的光晕

pt = vLightSourceToIntersect * (Length * 0.8f);

pt += m_LightSourcePos;

RenderHalo(0.7f, 0.5f, 0.5f, 0.5f, pt, 1.4f);

//绘制到光晕结束位置的0.7825处的光晕

pt = vLightSourceToIntersect * (Length * 0.7825f);

pt += m_LightSourcePos;

RenderGlow(0.8f, 0.5f, 0.1f, 0.5f, pt, 0.6f);

//绘制到光晕结束位置的1.0处的光晕

pt = vLightSourceToIntersect * (Length * 1.0f);

pt += m_LightSourcePos;

RenderHalo(0.5f, 0.5f, 0.7f, 0.5f, pt, 1.7f);

//绘制到光晕结束位置的0.975处的光晕

pt = vLightSourceToIntersect * (Length * 0.975f);

pt += m_LightSourcePos;

RenderGlow(0.4f, 0.1f, 0.9f, 0.5f, pt, 2.0f);

}

glDisable(GL_BLEND );

glEnable(GL_DEPTH_TEST);

glDisable(GL_TEXTURE_2D);

}

}

好了,下面的函数用来绘制四种不同的光晕 

  

//绘制Halo形的光晕void glCamera::RenderHalo(GLfloat r, GLfloat g, GLfloat b,
GLfloat a, glPoint p, GLfloat scale){ glPoint q[4];  q[0].x = (p.x -

scale);            q[0].y = (p.y - scale);

q[1].x = (p.x - scale);

q[1].y = (p.y + scale);              q[2].x =

(p.x + scale);            q[2].y = (p.y - scale);

q[3].x = (p.x + scale);

q[3].y = (p.y + scale);

glPushMatrix();              glTranslatef(p.x, p.y, p.z);

glRotatef(-m_HeadingDegrees, 0.0f, 1.0f, 0.0f); glRotatef(-m_PitchDegrees, 1.0f, 0.0f,

0.0f); glBindTexture(GL_TEXTURE_2D, m_HaloTexture);      glColor4f(r, g, b, a);

glBegin(GL_TRIANGLE_STRIP);

glTexCoord2f(0.0f, 0.0f);       glVertex2f(q[0].x, q[0].y);  glTexCoord2f(0.0f,

1.0f);  glVertex2f(q[1].x, q[1].y);  glTexCoord2f(1.0f, 0.0f);  glVertex2f(q[2].x, q[2].y);  glTexCoord2f(1.0f,

1.0f);  glVertex2f(q[3].x, q[3].y); glEnd();           glPopMatrix

();             }

//绘制Gloew形的光晕

void glCamera::RenderGlow(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale)

{

glPoint q[4];

q[0].x = (p.x - scale);

q[0].y = (p.y - scale);

q[1].x = (p.x - scale);

q[1].y = (p.y + scale);

q[2].x = (p.x + scale);

q[2].y = (p.y - scale);

q[3].x = (p.x + scale);

q[3].y = (p.y + scale);

glPushMatrix();

glTranslatef(p.x, p.y, p.z);

glRotatef(-m_HeadingDegrees, 0.0f, 1.0f, 0.0f);

glRotatef(-m_PitchDegrees, 1.0f, 0.0f, 0.0f);

glBindTexture(GL_TEXTURE_2D, m_GlowTexture);

glColor4f(r, g, b, a);

glBegin(GL_TRIANGLE_STRIP);

glTexCoord2f(0.0f, 0.0f);

glVertex2f(q[0].x, q[0].y);

glTexCoord2f(0.0f, 1.0f);

glVertex2f(q[1].x, q[1].y);

glTexCoord2f(1.0f, 0.0f);

glVertex2f(q[2].x, q[2].y);

glTexCoord2f(1.0f, 1.0f);

glVertex2f(q[3].x, q[3].y);

glEnd();

glPopMatrix();

}

//绘制BigGlow形的光晕

void glCamera::RenderBigGlow(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale)

{

glPoint q[4];

q[0].x = (p.x - scale);

q[0].y = (p.y - scale);

q[1].x = (p.x - scale);

q[1].y = (p.y + scale);

q[2].x = (p.x + scale);

q[2].y = (p.y - scale);

q[3].x = (p.x + scale);

q[3].y = (p.y + scale);

glPushMatrix();

glTranslatef(p.x, p.y, p.z);

glRotatef(-m_HeadingDegrees, 0.0f, 1.0f, 0.0f);

glRotatef(-m_PitchDegrees, 1.0f, 0.0f, 0.0f);

glBindTexture(GL_TEXTURE_2D, m_BigGlowTexture);

glColor4f(r, g, b, a);

glBegin(GL_TRIANGLE_STRIP);

glTexCoord2f(0.0f, 0.0f);

glVertex2f(q[0].x, q[0].y);

glTexCoord2f(0.0f, 1.0f);

glVertex2f(q[1].x, q[1].y);

glTexCoord2f(1.0f, 0.0f);

glVertex2f(q[2].x, q[2].y);

glTexCoord2f(1.0f, 1.0f);

glVertex2f(q[3].x, q[3].y);

glEnd();

glPopMatrix();

}

//绘制Streaks形的光晕

void glCamera::RenderStreaks(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale)

{

glPoint q[4];

q[0].x = (p.x - scale);

q[0].y = (p.y - scale);

q[1].x = (p.x - scale);

q[1].y = (p.y + scale);

q[2].x = (p.x + scale);

q[2].y = (p.y - scale);

q[3].x = (p.x + scale);

q[3].y = (p.y + scale);

glPushMatrix();

glTranslatef(p.x, p.y, p.z);

glRotatef(-m_HeadingDegrees, 0.0f, 1.0f, 0.0f);

glRotatef(-m_PitchDegrees, 1.0f, 0.0f, 0.0f);

glBindTexture(GL_TEXTURE_2D, m_StreakTexture);

glColor4f(r, g, b, a);

glBegin(GL_TRIANGLE_STRIP);

glTexCoord2f(0.0f, 0.0f);

glVertex2f(q[0].x, q[0].y);

glTexCoord2f(0.0f, 1.0f);

glVertex2f(q[1].x, q[1].y);

glTexCoord2f(1.0f, 0.0f);

glVertex2f(q[2].x, q[2].y);

glTexCoord2f(1.0f, 1.0f);

glVertex2f(q[3].x, q[3].y);

glEnd();

glPopMatrix();

}

原文及其个版本源代码下载:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=44

 
 

NeHe OpenGL教程 第四十四课:3D光晕的更多相关文章

  1. NeHe OpenGL教程 第三十四课:地形

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. NeHe OpenGL教程 第三十八课:资源文件

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. NeHe OpenGL教程 第三十六课:从渲染到纹理

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. NeHe OpenGL教程 第三十五课:播放AVI

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. NeHe OpenGL教程 第三十二课:拾取游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. NeHe OpenGL教程 第三十九课:物理模拟

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. NeHe OpenGL教程 第三十课:碰撞检测

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. NeHe OpenGL教程 第四十八课:轨迹球

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. NeHe OpenGL教程 第四十五课:顶点缓存

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  10. NeHe OpenGL教程 第四十六课:全屏反走样

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

随机推荐

  1. nginx配置说明

    #user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error.log notice; #error ...

  2. 【转】 iOS日常学习 - iOS10上关于NSPhotoLibraryUsageDescription等问题

    原文网址:http://blog.csdn.net/wang631106979/article/details/52578001 最近升级了Xcode8.0,真是很多坑啊,填完一个来另外一个,今天又遇 ...

  3. mysql学习之-三种安装方式与版本介绍

    MYSQL版本介绍 mysql分alpha,beta,rc,GA四个版本. alpha  暗示这是一个以展示新特性为目的的版本,存在比较多的不稳定因素,还会向代码中添加新新特性beta 以后的beta ...

  4. SQL注入脚本(基于时间)

    #encoding=utf-8 import httplib import time import string import sys import urllib header = {'Accept' ...

  5. Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇

    一.面向对象之多态 1.多态:简而言子就是多种形态或多种类型 python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型, java多态传参:必须是传参数的数据类型或传 ...

  6. xenserver

    Citrix XenServer is the complete server virtualization platform from Citrix. citrix xenserver是来自citr ...

  7. leaflet 了解

    Leaflet 是一个为建设移动设备友好的互动地图,而开发的现代的.开源的 JavaScript 库.它是由 Vladimir Agafonkin 带领一个专业贡献者团队开发,虽然代码仅有 33 KB ...

  8. svn安装

    方法三.无法连接网络的情况(link链接) 1.从官网下载 Site-1.6.5.zip 2.解压Site-1.6.5.zip至${eclipse}PluginsSubclipse-1.6.5.zip ...

  9. windows中用eclipse开发Android环境搭建SDK安装异常

    SDK更新时的“https://dl-ssl.google.com refused”错误 Download interrupted: hostname in certificate didn't ma ...

  10. postman使用教程

    最近很多朋友在问postman的使用方法,现我经过整理,分享给大家. Postman 是一个很强大的 API调试.Http请求的工具,当你还准备拿着记事本傻傻的去写 Form 表单的时候,你来试试 P ...