3D C/C++ tutorials -> OpenGL 2.1 -> Atmospheric light scattering
Use for personal or educational purposes only. Commercial and other profit uses strictly prohibited. Exploitation of content on a website or in a publication prohibited.
opengl_21_tutorials_win32_framework.h
...
class COpenGLRenderer
{
protected:
...
protected:
CTexture Texture, DirtTexture;
CShaderProgram Sky, SunDepthTest, BlurH, BlurV, SunRaysLensFlareHalo;
GLuint /*ScreenTexture,*/ DepthTexture, SunTextures[4], FBO, VBO;
int SunTextureWidth, SunTextureHeight;
public:
bool Pause;
float SunR;
vec3 SunCPos, SunRotVec;
public:
...
};
...
opengl_21_tutorials_win32_framework.cpp
...
COpenGLRenderer::COpenGLRenderer()
{
Pause = false;
SunR = 15.0f;
SunRotVec = normalize(vec3(0.0f, -0.66f, -1.0f));
SunCPos = rotate(vec3(-512.0f, 0.0f, 0.0f), -22.5f, SunRotVec);
Camera.SetViewMatrixPointer(&ViewMatrix);
}
COpenGLRenderer::~COpenGLRenderer()
{
}
bool COpenGLRenderer::Init()
{
bool Error = false;
if(!GLEW_ARB_texture_non_power_of_two)
{
ErrorLog.Append("GL_ARB_texture_non_power_of_two not supported!\r\n");
Error = true;
}
if(!GLEW_ARB_depth_texture)
{
ErrorLog.Append("GL_ARB_depth_texture not supported!\r\n");
Error = true;
}
if(!GLEW_EXT_framebuffer_object)
{
ErrorLog.Append("GL_EXT_framebuffer_object not supported!\r\n");
Error = true;
}
Error |= !Texture.LoadTexture2D("texture.jpg");
Error |= !DirtTexture.LoadTexture2D("lensdirt_lowc.jpg");
Error |= !Sky.Load("skyfromatmosphere.vs", "skyfromatmosphere.fs");
Error |= !SunDepthTest.Load("sundepthtest.vs", "sundepthtest.fs");
Error |= !BlurH.Load("blur.vs", "blurh.fs");
Error |= !BlurV.Load("blur.vs", "blurv.fs");
Error |= !SunRaysLensFlareHalo.Load("sunrayslensflarehalo.vs", "sunrayslensflarehalo.fs");
if(Error)
{
return false;
}
glUseProgram(SunDepthTest);
glUniform1i(glGetUniformLocation(SunDepthTest, "SunTexture"), 0);
glUniform1i(glGetUniformLocation(SunDepthTest, "DepthTexture"), 1);
glUseProgram(0);
glUseProgram(SunRaysLensFlareHalo);
glUniform1i(glGetUniformLocation(SunRaysLensFlareHalo, "LowBlurredSunTexture"), 0);
glUniform1i(glGetUniformLocation(SunRaysLensFlareHalo, "HighBlurredSunTexture"), 1);
glUniform1i(glGetUniformLocation(SunRaysLensFlareHalo, "DirtTexture"), 2);
glUniform1f(glGetUniformLocation(SunRaysLensFlareHalo, "Dispersal"), 0.1875f);
glUniform1f(glGetUniformLocation(SunRaysLensFlareHalo, "HaloWidth"), 0.45f);
glUniform1f(glGetUniformLocation(SunRaysLensFlareHalo, "Intensity"), 2.25f);
glUniform3f(glGetUniformLocation(SunRaysLensFlareHalo, "Distortion"), 0.94f, 0.97f, 1.00f);
glUseProgram(0);
float Kr = 0.0030f;
float Km = 0.0015f;
float ESun = 16.0f;
float g = -0.75f;
float InnerRadius = 10.0f;
float OuterRadius = 10.25f;
float Scale = 1.0f / (OuterRadius - InnerRadius);
float ScaleDepth = 0.25f;
float ScaleOverScaleDepth = Scale / ScaleDepth;
glUseProgram(Sky);
glUniform3f(glGetUniformLocation(Sky, "v3CameraPos"), 0.0f, InnerRadius, 0.0f);
glUniform3f(glGetUniformLocation(Sky, "v3InvWavelength"), 1.0f / powf(0.650f, 4.0f), 1.0f / powf(0.570f, 4.0f), 1.0f / powf(0.475f, 4.0f));
glUniform1f(glGetUniformLocation(Sky, "fCameraHeight"), InnerRadius);
glUniform1f(glGetUniformLocation(Sky, "fCameraHeight2"), InnerRadius * InnerRadius);
glUniform1f(glGetUniformLocation(Sky, "fInnerRadius"), InnerRadius);
glUniform1f(glGetUniformLocation(Sky, "fInnerRadius2"), InnerRadius * InnerRadius);
glUniform1f(glGetUniformLocation(Sky, "fOuterRadius"), OuterRadius);
glUniform1f(glGetUniformLocation(Sky, "fOuterRadius2"), OuterRadius * OuterRadius);
glUniform1f(glGetUniformLocation(Sky, "fKrESun"), Kr * ESun);
glUniform1f(glGetUniformLocation(Sky, "fKmESun"), Km * ESun);
glUniform1f(glGetUniformLocation(Sky, "fKr4PI"), Kr * 4.0f * (float)M_PI);
glUniform1f(glGetUniformLocation(Sky, "fKm4PI"), Km * 4.0f * (float)M_PI);
glUniform1f(glGetUniformLocation(Sky, "fScale"), Scale);
glUniform1f(glGetUniformLocation(Sky, "fScaleDepth"), ScaleDepth);
glUniform1f(glGetUniformLocation(Sky, "fScaleOverScaleDepth"), ScaleOverScaleDepth);
glUniform1f(glGetUniformLocation(Sky, "g"), g);
glUniform1f(glGetUniformLocation(Sky, "g2"), g * g);
glUniform1i(glGetUniformLocation(Sky, "Samples"), 4);
glUseProgram(0);
vec3 *SkyDomeVertices = new vec3[112 * 3], va, vb, vc, vd;
float stepa = (float)M_PI * 2.0f / 16, startb = asin(InnerRadius / OuterRadius), stepb = ((float)M_PI_2 - startb) / 4;
int pos = 0;
for(int y = 0; y < 3; y++)
{
float b = startb + stepb * y;
for(int x = 0; x < 16; x++)
{
float a = stepa * x;
va = vec3(sin(a) * cos(b) * OuterRadius, sin(b) * OuterRadius, -cos(a) * cos(b) * OuterRadius);
vb = vec3(sin(a + stepa) * cos(b) * OuterRadius, sin(b) * OuterRadius, -cos(a + stepa) * cos(b) * OuterRadius);
vc = vec3(sin(a + stepa) * cos(b + stepb) * OuterRadius, sin(b + stepb) * OuterRadius, -cos(a + stepa) * cos(b + stepb) * OuterRadius);
vd = vec3(sin(a) * cos(b + stepb) * OuterRadius, sin(b + stepb) * OuterRadius, -cos(a) * cos(b + stepb) * OuterRadius);
SkyDomeVertices[pos + 0] = va;
SkyDomeVertices[pos + 1] = vb;
SkyDomeVertices[pos + 2] = vc;
pos += 3;
SkyDomeVertices[pos + 0] = vc;
SkyDomeVertices[pos + 1] = vd;
SkyDomeVertices[pos + 2] = va;
pos += 3;
}
}
float b = startb + stepb * 3;
for(int x = 0; x < 16; x++)
{
float a = stepa * x;
va = vec3(sin(a) * cos(b) * OuterRadius, sin(b) * OuterRadius, -cos(a) * cos(b) * OuterRadius);
vb = vec3(sin(a + stepa) * cos(b) * OuterRadius, sin(b) * OuterRadius, -cos(a + stepa) * cos(b) * OuterRadius);
vc = vec3(0, OuterRadius, 0);
SkyDomeVertices[pos + 0] = va;
SkyDomeVertices[pos + 1] = vb;
SkyDomeVertices[pos + 2] = vc;
pos += 3;
}
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 112 * 3 * 3 * sizeof(float), SkyDomeVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete [] SkyDomeVertices;
//glGenTextures(1, &ScreenTexture);
glGenTextures(1, &DepthTexture);
glGenTextures(4, SunTextures);
glGenFramebuffersEXT(1, &FBO);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &vec4(vec3(0.0f), 1.0f));
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &vec4(1.0f));
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &vec4(1.0f));
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
Camera.Look(vec3(10.0f, 1.75f, 0.0f), vec3(-512.0f, 0.0f, 0.0f), false);
return true;
}
void COpenGLRenderer::Render(float FrameTime)
{
// calculate sun direction, position and color
vec3 SunCDir = normalize(SunCPos);
vec3 SunWPos = Camera.Position + SunCPos;
float RefractionFactor = (1.0f - sqrt(max(0.0f, SunCDir.y)));
vec3 SunColor = 1.0f - vec3(0.0f, 0.5f, 1.0f) * RefractionFactor;
// calculate ambient and diffuse light color
vec3 LightColor = 1.0f - vec3(0.0f, 0.25f, 0.5f) * RefractionFactor;
float AmbientIntensity = 0.0625f + 0.1875f * min(1.0f, max(0.0f, (0.375f + SunCDir.y) / 0.25f));
float DiffuseIntensity = 0.75f * min(1.0f, max(0.0f, (0.03125f + SunCDir.y) / 0.0625f));
glViewport(0, 0, Width, Height);
//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ScreenTexture, 0);
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, DepthTexture, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&ProjectionMatrix);
// render sky
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&ViewMatrix);
glTranslatef(Camera.Position.x, Camera.Position.y - 10.0f /*InnerRadius*/, Camera.Position.z);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexPointer(3, GL_FLOAT, 0, NULL);
glUseProgram(Sky);
glUniform3fv(glGetUniformLocation(Sky, "v3LightPos"), 1, &SunCDir);
glDrawArrays(GL_TRIANGLES, 0, 112 * 3);
glUseProgram(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
// render scene
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&ViewMatrix);
glLightfv(GL_LIGHT0, GL_AMBIENT, &vec4(vec3(AmbientIntensity), 1.0f));
glLightfv(GL_LIGHT0, GL_DIFFUSE, &vec4(LightColor * DiffuseIntensity, 1.0f));
glLightfv(GL_LIGHT0, GL_POSITION, &vec4(SunWPos, 1.0f));
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glColor3f(1.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, 0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f);
glNormal3f( 0.0f, 0.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5f, -0.5f, -0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5f, 0.5f, -0.5f);
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, -0.5f, -0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, 0.5f, -0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5f, 0.5f, 0.5f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f);
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, 0.5f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, 0.5f, -0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f);
glNormal3f( 0.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, -0.5f, -0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, -0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, -0.5f, 0.5f);
glEnd();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-4.0f, -0.5f, 4.0f);
glVertex3f( 4.0f, -0.5f, 4.0f);
glVertex3f( 4.0f, -0.5f, -4.0f);
glVertex3f(-4.0f, -0.5f, -4.0f);
glEnd();
GLUquadric *obj = gluNewQuadric();
for(int z = -2; z <= 2; z += 1)
{
for(int x = -2; x <= 2; x += 1)
{
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&ViewMatrix);
glTranslatef((float)x, -0.25f, (float)z);
gluSphere(obj, 0.25f, 32, 32);
}
}
gluDeleteQuadric(obj);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
// copy depth buffer to texture
glBindTexture(GL_TEXTURE_2D, DepthTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glBindTexture(GL_TEXTURE_2D, 0);
//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// test if sun is inside camera frustum
bool CalculateSunRaysLensFlareHalo = false;
int Test = 0, Tests = 16;
float Angle = 0.0f, AngleInc = 360.0f / Tests;
mat4x4 VPB = BiasMatrix * ProjectionMatrix * ViewMatrix;
while(Test < Tests && !CalculateSunRaysLensFlareHalo)
{
vec3 SunWEdge = SunWPos + rotate(Camera.X, Angle, Camera.Z) * SunR;
if(SunWEdge.y - Camera.Position.y > 0.0f)
{
vec4 SunPosProj = VPB * vec4(SunWEdge, 1.0f);
SunPosProj /= SunPosProj.w;
CalculateSunRaysLensFlareHalo |= (SunPosProj.x >= 0.0f && SunPosProj.x <= 1.0f && SunPosProj.y >= 0.0f && SunPosProj.y <= 1.0f && SunPosProj.z >= 0.0f && SunPosProj.z <= 1.0f);
}
Angle += AngleInc;
Test++;
}
// if it is then calculate lens flare
if(CalculateSunRaysLensFlareHalo)
{
vec4 SunPosProj = VPB * vec4(SunWPos, 1.0f);
SunPosProj /= SunPosProj.w;
glViewport(0, 0, SunTextureWidth, SunTextureHeight);
// render sun sphere
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[1], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&ViewMatrix);
double pl[] = {0.0f, 1.0f, 0.0f, -Camera.Position.y};
glClipPlane(GL_CLIP_PLANE0, pl);
glEnable(GL_CLIP_PLANE0);
glTranslatef(SunWPos.x, SunWPos.y, SunWPos.z);
glColor3fv(&SunColor);
glEnable(GL_CULL_FACE);
GLUquadric *obj = gluNewQuadric();
gluSphere(obj, SunR, 16, 16);
gluDeleteQuadric(obj);
glDisable(GL_CULL_FACE);
glDisable(GL_CLIP_PLANE0);
// test if sun sphere is behind scene geometry
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[0], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, SunTextures[1]);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, DepthTexture);
glUseProgram(SunDepthTest);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0);
// blur sun sphere horizontally (low)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[3], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glBindTexture(GL_TEXTURE_2D, SunTextures[0]);
glUseProgram(BlurH);
glUniform1i(glGetUniformLocation(BlurH, "Width"), 1);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
// blur sun sphere vertically (low)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[1], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glBindTexture(GL_TEXTURE_2D, SunTextures[3]);
glUseProgram(BlurV);
glUniform1i(glGetUniformLocation(BlurV, "Width"), 1);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
// blur sun sphere horizontally (high)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[3], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glBindTexture(GL_TEXTURE_2D, SunTextures[0]);
glUseProgram(BlurH);
glUniform1i(glGetUniformLocation(BlurH, "Width"), 10);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
// blur sun sphere vertically (high)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[2], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glBindTexture(GL_TEXTURE_2D, SunTextures[3]);
glUseProgram(BlurV);
glUniform1i(glGetUniformLocation(BlurV, "Width"), 10);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
// blur sun sphere radially and calculate lens flare and halo and apply dirt texture
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SunTextures[3], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, SunTextures[1]);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, SunTextures[2]);
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, DirtTexture);
glUseProgram(SunRaysLensFlareHalo);
glUniform2fv(glGetUniformLocation(SunRaysLensFlareHalo, "SunPosProj"), 1, &SunPosProj);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glViewport(0, 0, Width, Height);
}
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&ortho(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, ScreenTexture);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);*/
// blend sun texture over the screen
if(CalculateSunRaysLensFlareHalo)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, SunTextures[3]);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f);
glEnd();
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
// move sun
if(!Pause)
{
SunCPos = rotate(SunCPos, 0.25f * FrameTime, SunRotVec);
}
}
void COpenGLRenderer::Resize(int Width, int Height)
{
this->Width = Width;
this->Height = Height;
ProjectionMatrix = perspective(45.0f, (float)Width / (float)Height, 0.125f, 512.0f);
/*glBindTexture(GL_TEXTURE_2D, ScreenTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);*/
glBindTexture(GL_TEXTURE_2D, DepthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_DEPTH_COMPONENT24, Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
SunTextureWidth = Width / 2;
SunTextureHeight = Height / 2;
for(int i = 0; i < 4 ;i++)
{
glBindTexture(GL_TEXTURE_2D, SunTextures[i]);
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_RGBA8, SunTextureWidth, SunTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
}
glUseProgram(BlurH);
glUniform1f(glGetUniformLocation(BlurH, "odw"), 1.0f / (float)SunTextureWidth);
glUseProgram(BlurV);
glUniform1f(glGetUniformLocation(BlurV, "odh"), 1.0f / (float)SunTextureHeight);
glUseProgram(0);
}
void COpenGLRenderer::Destroy()
{
Texture.Destroy();
DirtTexture.Destroy();
//glDeleteTextures(1, &ScreenTexture);
glDeleteTextures(1, &DepthTexture);
glDeleteTextures(4, SunTextures);
Sky.Destroy();
SunDepthTest.Destroy();
BlurH.Destroy();
BlurV.Destroy();
SunRaysLensFlareHalo.Destroy();
glDeleteBuffers(1, &VBO);
if(GLEW_EXT_framebuffer_object)
{
glDeleteFramebuffersEXT(1, &FBO);
}
}
...
void COpenGLView::OnKeyDown(UINT Key)
{
switch(Key)
{
case VK_ADD:
OpenGLRenderer.SunCPos = rotate(OpenGLRenderer.SunCPos, OpenGLRenderer.SunRotVec, + M_PI / 180.0f);
break;
case VK_SUBTRACT:
OpenGLRenderer.SunCPos = rotate(OpenGLRenderer.SunCPos, OpenGLRenderer.SunRotVec, - M_PI / 180.0f);
break;
case VK_SPACE:
OpenGLRenderer.Stop = !OpenGLRenderer.Stop;
break;
}
}
...
Download
|