首页 > 代码库 > outdated: 44.3D Lens Flare With Occlusion Testing

outdated: 44.3D Lens Flare With Occlusion Testing

这样的光晕如何实现?

技术分享

其实也就是几个贴图。变着法贴,比如,变大变小贴,变着颜色贴,变着透明度贴,换着距离贴。

技术分享

下面为代码,其中用到了一些很简单的数学知识。

技术分享
#ifndef AFX_GLFONT_H__F5069B5F_9D05_4832_8200_1EC9B4BFECE6__INCLUDED_#define AFX_GLFONT_H__F5069B5F_9D05_4832_8200_1EC9B4BFECE6__INCLUDED_#include <Windows.h>#include <GL\glew.h>#include <GL\glut.h>#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class glFont {public:    glFont();    virtual ~glFont();public:    GLuint GetListBase(void);    GLuint GetTexture(void);    void SetWindowSize(GLint width, GLint height);    void glPrintf(GLint x, GLint y, GLint set, const char* Format, ...);    void BuildFont(GLfloat Scale = 1.0f);    void SetFontTexture(GLuint tex);                    // Texture IDprotected:    GLdouble m_WindowWidth;    GLdouble m_WindowHeight;    GLuint m_ListBase;    GLuint m_FontTexture;};#endif // !AFX_GLFONT_H__F5069B5F_9D05_4832_8200_1EC9B4BFECE6__INCLUDED_
glFont.h
技术分享
#include "glFont.h"#include <stdio.h>#pragma comment(lib, "legacy_stdio_definitions.lib")glFont::glFont(){    m_FontTexture = 0;    m_ListBase = 0;}glFont::~glFont(){    if (m_FontTexture != 0) {        glDeleteTextures(1, &m_FontTexture);    }    if (m_ListBase != 0) {        glDeleteLists(m_ListBase, 256);    }}void glFont::SetFontTexture(GLuint tex){    if (tex != 0) {        m_FontTexture = tex;    }}void glFont::BuildFont(GLfloat Scale){    float cx;    float cy;    m_ListBase = glGenLists(256);    if (m_FontTexture != 0) {        glBindTexture(GL_TEXTURE_2D, m_FontTexture);        for (GLuint loop = 0; loop < 256; ++loop) {            cx = float(loop % 16) / 16.0f;            cy = float(loop / 16) / 16.0f;            glNewList(m_ListBase + loop, GL_COMPILE);            // Building a list            glBegin(GL_QUADS);                glTexCoord2f(cx, 1 - cy - 0.0625f);                glVertex2f(0, 0);                glTexCoord2f(cx + 0.0625f, 1 - cy - 0.0625f);                glVertex2f(16 * Scale, 0);                glTexCoord2f(cx + 0.0625f, 1 - cy);                glVertex2f(16 * Scale, 16 * Scale);                glTexCoord2f(cx, 1 - cy);                glVertex2f(0, 16 * Scale);            glEnd();            glTranslatef(10 * Scale, 0, 0);            glEndList();        }    }}void glFont::glPrintf(GLint x, GLint y, GLint set, const char* Format, ...){    char text[256];    va_list ap;    if (Format == NULL) {        return;    }    va_start(ap, Format);    vsprintf(text, Format, ap);    va_end(ap);    if (set > 1) {        set = 1;    }    glEnable(GL_TEXTURE_2D);    glEnable(GL_BLEND);    glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);    glBindTexture(GL_TEXTURE_2D, m_FontTexture);    glDisable(GL_DEPTH_TEST);        glMatrixMode(GL_PROJECTION);    glPushMatrix();    glLoadIdentity();        glOrtho(0, m_WindowWidth, 0, m_WindowHeight, -1, 1);           // Set up an ortho screen        glMatrixMode(GL_MODELVIEW);    glPushMatrix();    glLoadIdentity();    glTranslatef(x, y, 0);    glListBase(m_ListBase - 32 + (128 * set));    glCallLists(strlen(text), GL_BYTE, text);        glMatrixMode(GL_PROJECTION);    glPopMatrix();    glMatrixMode(GL_MODELVIEW);    glPopMatrix();    glEnable(GL_DEPTH_TEST);    glDisable(GL_BLEND);    glDisable(GL_TEXTURE_2D);}void glFont::SetWindowSize(GLint width, GLint height){    m_WindowWidth = width;    m_WindowHeight = height;}GLuint glFont::GetTexture(){    GLuint result = m_FontTexture;    return result;}GLuint glFont::GetListBase(){    GLuint result = m_ListBase;    return result;}
glFont.cpp
技术分享
#ifndef AFX_GLVECTOR_H__F526A5CF_89B5_4F20_8F2C_517D83879D35__INCLUDED_#define AFX_GLVECTOR_H__F526A5CF_89B5_4F20_8F2C_517D83879D35__INCLUDED_#include <Windows.h>#include <GL\glew.h>#include <GL\glut.h>#include <math.h>#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class glVector {public:    glVector();    virtual ~glVector();public:    void operator=(glVector v);    glVector operator+(glVector v);    glVector operator*(GLfloat scalar);    void Normalize(void);    GLfloat Magnitude(void);    GLfloat m_Msg;    void operator*=(GLfloat scalar);        GLfloat i;    GLfloat j;    GLfloat k;};#endif // !AFX_GLVECTOR_H__F526A5CF_89B5_4F20_8F2C_517D83879D35__INCLUDED_
glVector.h
技术分享
#include "glVector.h"glVector::glVector() : i(0), j(0), k(0) {}glVector::~glVector() {}void glVector::operator*=(GLfloat scalar){    i *= scalar;    j *= scalar;    k *= scalar;}GLfloat glVector::Magnitude(){    GLfloat result;    result = GLfloat(sqrt(i * i + j * j + k * k));    m_Msg = result;    return result;}void glVector::Normalize(){    if (m_Msg != 0.0f) {        i /= m_Msg;        j /= m_Msg;        k /= m_Msg;        Magnitude();    }}glVector glVector::operator*(GLfloat scalar){    glVector r;    r.i = i * scalar;    r.j = j * scalar;    r.k = k * scalar;    return r;}glVector glVector::operator+(glVector v){    glVector r;    r.i = i + v.i;    r.j = j + v.j;    r.k = k + v.k;    return r;}void glVector::operator=(glVector v){    i = v.i;    j = v.j;    k = v.k;    m_Msg = v.m_Msg;}
glVector.cpp
技术分享
#ifndef AFX_GLPOINT_H__ADADC708_0176_471A_8241_5DD4D700BCB2__INCLUDED_#define AFX_GLPOINT_H__ADADC708_0176_471A_8241_5DD4D700BCB2__INCLUDED_#include <Windows.h>#include <GL\glew.h>#include <GL\glut.h>#include "glVector.h"#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class glPoint {public:    glPoint();    virtual ~glPoint();public:    void operator+=(glPoint p);    glPoint operator+(glPoint p);    glVector operator-(glPoint p);    void operator=(glVector v);    void operator=(glPoint p);    GLfloat x;    GLfloat y;    GLfloat z;};#endif // !AFX_GLPOINT_H__ADADC708_0176_471A_8241_5DD4D700BCB2__INCLUDED_
glPoint.h
技术分享
#include "glPoint.h"glPoint::glPoint() : x(0), y(0), z(0) {}glPoint::~glPoint() {}void glPoint::operator=(glPoint p){    x = p.x;    y = p.y;    z = p.z;}void glPoint::operator=(glVector v){    x = v.i;    y = v.j;    z = v.k;}glVector glPoint::operator-(glPoint p){    glVector r;    r.i = x - p.x;    r.j = y - p.y;    r.k = z - p.z;    return r;}glPoint glPoint::operator+(glPoint p){    glPoint r;    r.x = x + p.x;    r.y = y + p.y;    r.z = z + p.z;    return r;}void glPoint::operator+=(glPoint p){    x += p.x;    y += p.y;    z += p.z;}
glPoint.cpp
技术分享
#ifndef AFX_GLCAMERA_H__8E3CD02E_6D82_437E_80DA_50023C60C146__INCLUDED_#define AFX_GLCAMERA_H__8E3CD02E_6D82_437E_80DA_50023C60C146__INCLUDED_#include <windows.h>#include <GL\glew.h>#include <gl\glut.h>#include <math.h>#include "glVector.h"#include "glPoint.h"#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class glCamera {public:    glCamera();    virtual ~glCamera();    BOOL SphereInFrustum(glPoint p, GLfloat Radius);    BOOL SphereInFrustum(GLfloat x, GLfloat y, GLfloat z, GLfloat Radius);    BOOL PointInFrustum(GLfloat x, GLfloat y, GLfloat z);    BOOL PointInFrustum(glPoint p);    void RenderLensFlare(void);                                  // Render lens flare    void RenderStreaks(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale);    void RenderBigGlow(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale);    void RenderGlow(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale);    void RenderHalo(GLfloat r, GLfloat g, GLfloat b, GLfloat a, glPoint p, GLfloat scale);    void UpdateFrustumFaster(void);            // Update the frustum    void UpdateFrustum(void);    void ChangeVelocity(GLfloat vel);           // Change volcity and speed    void ChangeHeading(GLfloat degrees);    void ChangePitch(GLfloat degrees);    void SetPrespective(void);    bool glCamera::IsOccluded(glPoint p);                // Occlusion    glVector vLightSourceToCamera, vLightSourceToIntersect;    glPoint ptIntersect, pt;    GLsizei m_WindowHeight;    GLsizei m_WindowWidth;    GLuint m_StreakTexture;    GLuint m_HaloTexture;    GLuint m_GlowTexture;    GLuint m_BigGlowTexture;    GLfloat m_MaxPointSize;    GLfloat m_Frustum[6][4];    glPoint m_LightSourcePos;    GLfloat m_MaxPitchRate;    GLfloat m_MaxHeadingRate;    GLfloat m_HeadingDegrees;    GLfloat m_PitchDegrees;    GLfloat m_MaxForwardVelocity;    GLfloat m_ForwardVelocity;    glPoint m_Position;    glVector m_DirectionVector;};#endif // !AFX_GLCAMERA_H__8E3CD02E_6D82_437E_80DA_50023C60C146__INCLUDED_
glCamera.h
技术分享
#include "glCamera.h"glCamera::glCamera(){    m_MaxPitchRate             = 0.0f;    m_MaxHeadingRate           = 0.0f;    m_HeadingDegrees           = 0.0f;    m_PitchDegrees             = 0.0f;    m_MaxForwardVelocity       = 0.0f;    m_ForwardVelocity          = 0.0f;    m_LightSourcePos.x         = 0.0f;    m_LightSourcePos.y         = 0.0f;    m_LightSourcePos.z         = 0.0f;    m_GlowTexture              = 0;    m_BigGlowTexture           = 0;    m_HaloTexture              = 0;    m_StreakTexture            = 0;    m_MaxPointSize             = 0.0f;}glCamera::~glCamera(){    if (m_GlowTexture != 0) {        glDeleteTextures(1, &m_GlowTexture);    }    if (m_HaloTexture != 0) {        glDeleteTextures(1, &m_HaloTexture);    }    if (m_BigGlowTexture != 0) {        glDeleteTextures(1, &m_BigGlowTexture);    }    if (m_StreakTexture != 0) {        glDeleteTextures(1, &m_StreakTexture);    }}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);    // Scale the direction by speed    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);}void glCamera::ChangePitch(GLfloat degrees){    if (fabs(degrees) < fabs(m_MaxPitchRate)) {        m_PitchDegrees += degrees;    }    else {        if (degrees < 0) {            m_PitchDegrees -= m_MaxPitchRate;        }        else {            m_PitchDegrees += m_MaxPitchRate;        }    }    if (m_PitchDegrees > 360.0f) {        m_PitchDegrees -= 360.0f;    }    else if (m_PitchDegrees < -360.0f) {        m_PitchDegrees += 360.0f;    }}void glCamera::ChangeHeading(GLfloat degrees){    if (fabs(degrees) < fabs(m_MaxHeadingRate)) {        if ((m_PitchDegrees > 90 && m_PitchDegrees < 270) ||             (m_PitchDegrees < -90 && m_PitchDegrees > -270))        {            m_HeadingDegrees -= degrees;        }        else {            m_HeadingDegrees += degrees;        }    }    else {        if (degrees < 0) {            if ((m_PitchDegrees > 90 && m_PitchDegrees < 270) ||                (m_PitchDegrees < -90 && m_PitchDegrees > -270))            {                m_HeadingDegrees += m_MaxHeadingRate;            }            else {                m_HeadingDegrees -= m_MaxHeadingRate;            }        }        else {            if ((m_PitchDegrees > 90 && m_PitchDegrees < 270) ||                (m_PitchDegrees < -90 && m_PitchDegrees > -270))            {                m_HeadingDegrees -= m_MaxHeadingRate;            }            else {                m_HeadingDegrees += m_MaxHeadingRate;            }        }    }    if (m_HeadingDegrees > 360.0f)    {        m_HeadingDegrees -= 360.0f;    }    else if (m_HeadingDegrees < -360.0f)    {        m_HeadingDegrees += 360.0f;    }}void glCamera::ChangeVelocity(GLfloat vel){    if (fabs(vel) < fabs(m_MaxForwardVelocity)) {        m_ForwardVelocity += vel;    }    else {        if (vel < 0) {            m_ForwardVelocity -= -m_MaxForwardVelocity;        }        else {            m_ForwardVelocity += m_MaxForwardVelocity;        }    }}void glCamera::UpdateFrustum(){    GLfloat clip[16];    GLfloat proj[16];    GLfloat modl[16];    GLfloat t;    // Get current matrix    glGetFloatv(GL_PROJECTION_MATRIX, proj);    glGetFloatv(GL_MODELVIEW_MATRIX, modl);    // Multiply    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];    // Extract the numbers for the right plane    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];    // Normal    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;    // Extract the numbers for the left plane    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];    // Normal    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;    // Extract the numbers for the bottm plane    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];    // Normal    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;    // Extract the numbers for the top plane    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];    // Normal    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;    // Extract the numbers for the far plane    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];    // Normal    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;    // Extract the numbers for the near plane    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];    // Normal    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;}void glCamera::UpdateFrustumFaster(){    GLfloat clip[16];    GLfloat proj[16];    GLfloat modl[16];    GLfloat t;    glGetFloatv(GL_PROJECTION_MATRIX, proj);    glGetFloatv(GL_MODELVIEW_MATRIX, modl);    // Multiply    // This function will only work if you do not rotate or translate your projection matrix    clip[0] = modl[0] * proj[0];    clip[1] = modl[1] * proj[5];    clip[2] = modl[2] * proj[10] + modl[3] * proj[14];    clip[3] = modl[2] * proj[11];    clip[4] = modl[4] * proj[0];    clip[5] = modl[5] * proj[5];    clip[6] = modl[6] * proj[10] + modl[7] * proj[14];    clip[7] = modl[6] * proj[11];    clip[8] = modl[8] * proj[0];    clip[9] = modl[9] * proj[5];    clip[10] = modl[10] * proj[10] + modl[11] * proj[14];    clip[11] = modl[10] * proj[11];    clip[12] = modl[12] * proj[0];    clip[13] = modl[13] * proj[5];    clip[14] = modl[14] * proj[10] + modl[15] * proj[14];    clip[15] = modl[14] * proj[11];    // Extract the numbers for the right plane    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];    // Normal    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;    // Extract the numbers for the left plane    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];    // Normal    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;    // Extract the numbers for the bottm plane    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];    // Normal    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;    // Extract the numbers for the top plane    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];    // Normal    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;    // Extract the numbers for the far plane    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];    // Normal    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;    // Extract the numbers for the near plane    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];    // Normal    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::SphereInFrustum(glPoint p, GLfloat Radius){    for (int 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] <= -Radius) {            return FALSE;        }    }    return TRUE;}BOOL glCamera::PointInFrustum(glPoint p){    for (int 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::SphereInFrustum(GLfloat x, GLfloat y, GLfloat z, GLfloat Radius){    for (int i = 0; i < 6; ++i) {        if (m_Frustum[i][0] * x + m_Frustum[i][1] * y + m_Frustum[i][2] * z + m_Frustum[i][3] <= -Radius) {            return FALSE;        }    }    return TRUE;}BOOL glCamera::PointInFrustum(GLfloat x, GLfloat y, GLfloat z){    for (int i = 0; i < 6; ++i) {        if (m_Frustum[i][0] * x + m_Frustum[i][1] * y + m_Frustum[i][2] * 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;                            // The transformed flare Z    GLfloat bufferZ;                            // The read Z from the buffer    glGetIntegerv(GL_VIEWPORT, viewport);    glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);    glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);    // This asks OGL to guess the 2D position of a 3D point inside the viewport    gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport, &winx, &winy, &winz);    flareZ = winz;    glReadPixels(winx, winy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &bufferZ);    // If the buffer Z is lower than our flare guessed Z then don‘t draw    if (bufferZ < flareZ) {        return true;    }    else {        return false;    }}void glCamera::RenderLensFlare(){    GLfloat Length = 0.0f;    if (SphereInFrustum(m_LightSourcePos, 1.0f) == TRUE) {        // Lets compute the vector that points to the camera from the light source        vLightSourceToCamera = m_Position - m_LightSourcePos;        Length = vLightSourceToCamera.Magnitude();        ptIntersect = m_DirectionVector * Length;        ptIntersect += m_Position;        // Lets compute the vector that points to the Intersect point from the light source        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);            /* Lets compute a point that is 20% away from the light source             *  in the direction of the intersection point.            */            pt = vLightSourceToIntersect * (Length * 0.1f);            pt += m_LightSourcePos;            RenderGlow(0.9f, 0.6f, 0.4f, 0.5f, pt, 0.6f);            /* Lets compute a point that is 30% away from the light source             *  in the direction of the intersection point            */            pt = vLightSourceToIntersect * (Length * 0.15f);            pt += m_LightSourcePos;            RenderHalo(0.8f, 0.5f, 0.6f, 0.5f, pt, 1.7f);            pt = vLightSourceToIntersect * (Length * 0.175f);  // 35%            pt += m_LightSourcePos;            RenderHalo(0.9f, 0.2f, 0.1f, 0.5f, pt, 0.83f);            pt = vLightSourceToIntersect * (Length * 0.285f);  // 57%            pt += m_LightSourcePos;            RenderHalo(0.7f, 0.7f, 0.4f, 0.5f, pt, 1.6f);            pt = vLightSourceToIntersect * (Length * 0.2755f);  // 55.1%            pt += m_LightSourcePos;            RenderGlow(0.9f, 0.9f, 0.2f, 0.5f, pt, 0.8f);            pt = vLightSourceToIntersect * (Length * 0.4775f);  // 95.5%            pt += m_LightSourcePos;            RenderGlow(0.93f, 0.82f, 0.73f, 0.5f, pt, 1.0f);            pt = vLightSourceToIntersect * (Length * 0.49f);    // 98%            pt += m_LightSourcePos;            RenderHalo(0.7f, 0.6f, 0.5f, 0.5f, pt, 1.4f);            pt = vLightSourceToIntersect * (Length * 0.65f);  // 130%            pt += m_LightSourcePos;            RenderGlow(0.7f, 0.8f, 0.3f, 0.5f, pt, 1.8f);            pt = vLightSourceToIntersect * (Length * 0.63f);  // 126%            pt += m_LightSourcePos;            RenderGlow(0.4f, 0.3f, 0.2f, 0.5f, pt, 1.4f);            pt = vLightSourceToIntersect * (Length * 0.8f);  // 160%            pt += m_LightSourcePos;            RenderHalo(0.8f, 0.5f, 0.1f, 0.5f, pt, 0.6f);            pt = vLightSourceToIntersect * (Length * 1.0f);  // 200%            pt += m_LightSourcePos;            RenderGlow(0.5f, 0.5f, 0.7f, 0.5f, pt, 1.7f);            pt = vLightSourceToIntersect * (Length * 0.975f);  // 195%            pt += m_LightSourcePos;            RenderHalo(0.4f, 0.1f, 0.9f, 0.5f, pt, 2.0f);        }        glDisable(GL_BLEND);        glEnable(GL_DEPTH_TEST);        glDisable(GL_TEXTURE_2D);    }}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();}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();}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();}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.x, 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();}
glCamera.cpp
技术分享
#include <windows.h>#include <stdio.h>#include <math.h>#include <gl/glew.h>#include <gl/glut.h>#include <GL/GLUAX.H>#include <mmsystem.h>#include "glFont.h"#include "glCamera.h"#pragma comment(lib, "legacy_stdio_definitions.lib")/**  Every OpenGL program is linked to a Rendering Context.*  A Rendering Context is what links OpenGL calls to the Device Context.*  In order for your program to draw to a Window you need to create a Device Context.*  The DC connects the Window to the GDI (Graphics Device Interface).*/HGLRC     hRC = NULL;         // Permanent rendering contextHDC       hDC = NULL;         // Private GDI device contextHWND      hWnd = NULL;        // Holds our window handleHINSTANCE hInstance;          // Holds the instance of the application/**  It‘s important to make this global so that each procedure knows if*  the program is running in fullscreen mode or not.*/bool keys[256];         // Array used for the keyboard routinebool active = TRUE;     // Window active flag set to TRUE by defaultbool fullscreen = TRUE; // Fullscreen flag set to fullscreen mode by defaultbool infoOn = FALSE;int gFrames = 0;DWORD gStartTime;DWORD gCurrentTime;GLfloat gFPS;glFont gFont;glCamera gCamera;GLUquadricObj* qobj;GLint cylList;LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProcvoid DrawGLInfo(void);void CheckKeys(void);bool LoadTexture(LPSTR szFileName, GLuint& texid){    HBITMAP hBMP;               // Handle    BITMAP BMP;                 // Bitmap structure    glGenTextures(1, &texid);    hBMP = (HBITMAP)LoadImage(GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);        if (!hBMP) {        return FALSE;    }    GetObject(hBMP, sizeof(BMP), &BMP);    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);        // Pixel storage mode    glBindTexture(GL_TEXTURE_2D, texid);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    glTexImage2D(GL_TEXTURE_2D, 0, 3, BMP.bmWidth, BMP.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);    DeleteObject(hBMP);    return TRUE;}GLvoid ReSizeGLScene(GLsizei width, GLsizei height)   // Resize and initialize the GL window{    gCamera.m_WindowHeight = height;    gCamera.m_WindowWidth = width;    if (height == 0) {                                // Prevent a divide by zero by        height = 1;                                   // Making height equal one    }    glViewport(0, 0, width, height);                  // Reset the current viewport    /*    *  The following lines set the screen up for a perspective view.    *  Meaning things in the distance get smaller. This creates a realistic looking scene.    *  The perspective is calculated with a 45 degree viewing angle based on    *  the windows width and height. The 0.1f, 100.0f is the starting point and    *  ending point for how deep we can draw into the screen.    *    *  The projection matrix is responsible for adding perspective to our scene.    *  glLoadIdentity() restores the selected matrix to it‘s original state.    *  The modelview matrix is where our object information is stored.    *   Lastly we reset the modelview matrix.    */    glMatrixMode(GL_PROJECTION);                      // Select the projection matrix    glLoadIdentity();                                 // Reset the projection matrix                                                      // Calculate the aspect ratio of the window    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);    glMatrixMode(GL_MODELVIEW);                       // Seclet the modelview matrix    glLoadIdentity();                                 // Reset the modelview matrix}int InitGL(GLvoid)                                    // All setup for OpenGL goes here{    GLuint tex = 0;    /*    *  Smooth shading blends colors nicely across a polygon, and smoothes out lighting.    */    glShadeModel(GL_SMOOTH);                          // Enables smooth shading    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);             // Black background    glClearDepth(1.0f);                               // Depth buffer setup    glDepthFunc(GL_LEQUAL);    glEnable(GL_DEPTH_TEST);    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   // Really nice perspective calculations    LoadTexture("Art/Font.bmp", tex);    if (tex != 0) {        gFont.SetFontTexture(tex);        gFont.SetWindowSize(1024, 768);        gFont.BuildFont(1.0f);    }    else {        MessageBox(NULL, "Failed to load font texture.", "Error", MB_OK);    }    gCamera.m_MaxHeadingRate = 1.0f;    gCamera.m_MaxPitchRate = 1.0f;    gCamera.m_HeadingDegrees = 0.0f;    LoadTexture("Art/HardGlow2.bmp", gCamera.m_GlowTexture);    if (gCamera.m_GlowTexture == 0) {        MessageBox(NULL, "Failed to load Hard Glow texture.", "Error", MB_OK);        return(FALSE);    }    LoadTexture("Art/BigGlow3.bmp", gCamera.m_BigGlowTexture);    if (gCamera.m_BigGlowTexture == 0) {        MessageBox(NULL, "Failed to load Big Glow texture.", "Error", MB_OK);        return(FALSE);    }    LoadTexture("Art/Halo3.bmp", gCamera.m_HaloTexture);    if (gCamera.m_HaloTexture == 0) {        MessageBox(NULL, "Failed to load Halo texture.", "Error", MB_OK);        return(FALSE);    }    LoadTexture("Art/Streaks4.bmp", gCamera.m_StreakTexture);    if (gCamera.m_StreakTexture == 0) {        MessageBox(NULL, "Failed to load Streaks texture.", "Error", MB_OK);        return(FALSE);    }    cylList = glGenLists(1);    qobj = gluNewQuadric();    gluQuadricDrawStyle(qobj, GLU_FILL);    gluQuadricNormals(qobj, GLU_SMOOTH);    glNewList(cylList, GL_COMPILE);        glEnable(GL_COLOR_MATERIAL);        glColor3f(0.0f, 0.0f, 1.0f);        glEnable(GL_LIGHT0);        glEnable(GL_LIGHTING);        glTranslatef(0.0f, 0.0f, -2.0f);//        gluCylinder(qobj, 0.5f, 0.5f, 4.0f, 15, 5);        glDisable(GL_LIGHTING);        glDisable(GL_LIGHT0);        glDisable(GL_COLOR_MATERIAL);    glEndList();    gStartTime = timeGetTime();    return TRUE;}/**  For now all we will do is clear the screen to the color we previously decided on,*  clear the depth buffer and reset the scene. We wont draw anything yet.*/int DrawGLScene(GLvoid)                                  // Here‘s where we do all the drawing{    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clear the screen and the depth buffer    glLoadIdentity();    glTranslatef(0.0f, 0.0f, -1.0f);    gCamera.m_LightSourcePos.z = gCamera.m_Position .z - 50.0f;    // Pulsing colors based on text position    // glColor3f(1.0f * float(cos(cnt1)), 1.0f * float(sin(cnt2)), 1.0f - 0.5f * float(cos(cnt1 + cnt2)));    // Position the text on the screen    // glRasterPos2f(-0.45f + 0.05f * float(cos(cnt1)), 0.35f * float(sin(cnt2)));        glPushMatrix();        glLoadIdentity();        glTranslatef(0.0f, 0.0f, -20.0f);        glRotatef(timeGetTime() / 50.0f, 0.3f, 0.0f, 0.0f);        glRotatef(timeGetTime() / 50.0f, 0.0f, 0.5f, 0.0f);        glCallList(cylList);    glPopMatrix();        gCamera.SetPrespective();    gCamera.RenderLensFlare();    gCamera.UpdateFrustumFaster();    if (infoOn == TRUE) {        DrawGLInfo();    }    CheckKeys();    return TRUE;                                         // everthing went OK}/**  The job of KillGLWindow() is to release the Rendering Context,*  the Device Context and finally the Window Handle.*/GLvoid KillGLWindow(GLvoid)                              // Properly kill the window{    if (fullscreen) {                                    // Are we in fullscreen mode        /*        *  We use ChangeDisplaySettings(NULL,0) to return us to our original desktop.        *  After we‘ve switched back to the desktop we make the cursor visible again.        */        ChangeDisplaySettings(NULL, 0);                  // if so switch back to the desktop        ShowCursor(TRUE);                                // Show mouse pointer    }    if (hRC) {                                           // Do we have a rendering context        if (!wglMakeCurrent(NULL, NULL)) {                // Are we able to release the DC and RC contexts            MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);        }        if (!wglDeleteContext(hRC)) {                     // Are we able to delete the RC            MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);            hRC = NULL;                                  // Set RC to NULL        }        if (hDC && !ReleaseDC(hWnd, hDC)) {              // Are we able to release the DC            MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);            hDC = NULL;                                  // Set DC to NULL        }        if (hWnd && !DestroyWindow(hWnd)) {              // Are we able to destroy the window            MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);            hWnd = NULL;                                 // Set hWnd to NULL        }        if (!UnregisterClass("OpenGL", hInstance)) {     // Are we able to unregister class            MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);            hInstance = NULL;                            // Set hInstance to NULL        }    }}/** The next section of code creates our OpenGL Window.*/BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){    /*    * Find  a pixel format that matches the one we want    */    GLuint PixelFormat;                                  // Holds the result after serching for a match    /*    * Before you create a window, you MUST register a Class for the window    */    WNDCLASS wc;                                         // Windows class structure    /*    *  dwExStyle and dwStyle will store the Extended and normal Window Style Information.    */    DWORD dwExStyle;                                     // Window extend style    DWORD dwStyle;                                       // Window style    RECT WindowRect;                                     // Grabs rectangle upper left/lower right values    WindowRect.left = (long)0;                           // Set left value to 0    WindowRect.right = (long)width;                      // Set right value to requested width    WindowRect.top = (long)0;                            // Set top value to 0    WindowRect.bottom = (long)height;                    // Set bottom value to requested height    fullscreen = fullscreenflag;                         // Set the global fullscreen flag    /*    *  The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized.    *  CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications.    *  WndProc is the procedure that watches for messages in our program.    *  No extra Window data is used so we zero the two fields. Then we set the instance.    *  Next we set hIcon to NULL meaning we don‘t want an ICON in the Window,    *  and for a mouse pointer we use the standard arrow. The background color doesn‘t matter    *  (we set that in GL). We don‘t want a menu in this Window so we set it to NULL,    *  and the class name can be any name you want. I‘ll use "OpenGL" for simplicity.    */    hInstance = GetModuleHandle(NULL);                   // Grab an instance for our window    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;       // Redraw on move, and own DC for window    wc.lpfnWndProc = (WNDPROC)WndProc;                   // WndProc handles message    wc.cbClsExtra = 0;                                   // No extra window date    wc.cbWndExtra = 0;                                   // No extra window date    wc.hInstance = hInstance;                            // set the instance    wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);              // Load the default icon    wc.hCursor = LoadCursor(NULL, IDC_ARROW);            // Load the arrow pointer    wc.hbrBackground = NULL;                             // No background requried for GL    wc.lpszMenuName = NULL;                              // We don‘t want a menu    wc.lpszClassName = "OpenGL";                         // set the class name    if (!RegisterClass(&wc)) {                           // Attempt to register the window class        MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                    // Exit and return false    }    if (fullscreen) {                                    // attempt fullsreen model        /*        *  There are a few very important things you should keep in mind when switching to full screen mode.        *  Make sure the width and height that you use in fullscreen mode is the same as        *  the width and height you plan to use for your window, and most importantly,        *  set fullscreen mode BEFORE you create your window.        */        DEVMODE dmScreenSettings;                        // Device mode        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory‘s cleared        dmScreenSettings.dmSize = sizeof(dmScreenSettings);     // Size of devmode structure        dmScreenSettings.dmPelsWidth = width;            // Select window width        dmScreenSettings.dmPelsHeight = height;          // Select window height        dmScreenSettings.dmBitsPerPel = bits;            // Select bits per pixel        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;        /*        *  In the line below ChangeDisplaySettings tries to switch to a mode that matches        *  what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes,        *  because it‘s supposed to remove the start bar at the bottom of the screen,        *  plus it doesn‘t move or resize the windows on your desktop when you switch to        *  fullscreen mode and back.        */        //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar        if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {            //If the mode fails, offer two options. Quit or run in a window            if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use"                "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)            {                fullscreen = FALSE;                       // Select windowed mode (fullscreen=FLASE)            }            else {                // Pop up a message box letting user know the programe is closing.                MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP);                return FALSE;                             // Exit and return FALSE            }        }    }    if (fullscreen) {                                     // Are we still in fullscreen mode        /*        *  If we are still in fullscreen mode we‘ll set the extended style to WS_EX_APPWINDOW,        *  which force a top level window down to the taskbar once our window is visible.        *  For the window style we‘ll create a WS_POPUP window.        *  This type of window has no border around it, making it perfect for fullscreen mode.        *  Finally, we disable the mouse pointer. If your program is not interactive,        *  it‘s usually nice to disable the mouse pointer when in fullscreen mode. It‘s up to you though.        */        dwExStyle = WS_EX_APPWINDOW;                      // Window extended style        dwStyle = WS_POPUP;                               // Window style        ShowCursor(FALSE);                                // Hide mosue pointer     }    else {        /*        *  If we‘re using a window instead of fullscreen mode,        *  we‘ll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look.        *  For style we‘ll use WS_OVERLAPPEDWINDOW instead of WS_POPUP.        *  WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border,        *  window menu, and minimize / maximize buttons.        */        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   // Window extended style        dwStyle = WS_OVERLAPPEDWINDOW;                    // Window style    }    /*    *  By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders,    *  instead, the window will be made larger to account for the pixels needed to draw the window border.    *  In fullscreen mode, this command has no effect.    */    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);  // Adjust window to true resqusted    /*    *  WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly.    *  These styles prevent other windows from drawing over or into our OpenGL Window.    */    if (!(hWnd = CreateWindowEx(dwExStyle,                // Extended style for the window        "OpenGL",                                         // Class name        title,                                            // Window title        WS_CLIPSIBLINGS |                                 // Requried window style        WS_CLIPCHILDREN |                                 // Requried window style        dwStyle,                                          // Select window style        0, 0,                                             // Window position        WindowRect.right - WindowRect.left,               // Calculate adjusted window width        WindowRect.bottom - WindowRect.top,               // Calculate adjusted window height        NULL,                                             // No parent window        NULL,                                             // No menu        hInstance,                                        // Instance        NULL)))                                           // Don‘t pass anything to WM_CREATE    {        KillGLWindow();                                   //Reset the display        MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Retrurn FALSE;    }    /*    *  aside from the stencil buffer and the (slow) accumulation buffer    */    static PIXELFORMATDESCRIPTOR pfd =                    // pfd tells windows how we want things to be     {        sizeof(PIXELFORMATDESCRIPTOR),                    // Size of this pixel format descriptor        1,                                                // Version number        PFD_DRAW_TO_WINDOW |                              // Format must support window        PFD_SUPPORT_OPENGL |                              // Format must support OpenGL        PFD_DOUBLEBUFFER,                                 // Must support double buffer        PFD_TYPE_RGBA,                                    // Request an RGBA format        bits,                                             // Select our color depth        0, 0, 0, 0, 0, 0,                                 // Color bits ignored        0,                                                // No alpha buffer        0,                                                // shift bit ignored        0,                                                // No accumulation buffer        0, 0, 0, 0,                                       // Accumulation bits ignored        16,                                               // 16Bits Z_Buffer (depth buffer)        0,                                                // No stencil buffer        0,                                                // No auxiliary buffer        PFD_MAIN_PLANE,                                   // Main drawing layer        0,                                                // Reserved        0, 0, 0                                           // Layer makes ignored    };    if (!(hDC = GetDC(hWnd))) {                           // Did we get a device context        KillGLWindow();                                   // Reset the display        MessageBox(NULL, "Can‘t create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Return FALSE    }    if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {  // Did window find a matching pixel format        KillGLWindow();                                   // Reset the display        MessageBox(NULL, "Can‘t find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Return FALSE;    }    if (!SetPixelFormat(hDC, PixelFormat, &pfd)) {        // Are we able to set the pixel format        KillGLWindow();                                   // Reset the display        MessageBox(NULL, "Can‘t set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Return FALSE;    }    if (!(hRC = wglCreateContext(hDC))) {                 // Are we able to rendering context        KillGLWindow();                                   // Reset the display        MessageBox(NULL, "Can‘t create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Return FASLE;    }    if (!wglMakeCurrent(hDC, hRC)) {                      // Try to activate the rendering context        KillGLWindow();                                   // Reset the display        MessageBox(NULL, "Can‘t activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Return FALSE        }    /*    *  ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen.    */    ShowWindow(hWnd, SW_SHOW);                            // Show the window    SetForegroundWindow(hWnd);                            // slightly higher priority    SetFocus(hWnd);                                       // Sets keyboard focus to the window    ReSizeGLScene(width, height);                         // Set up our perspective GL screen    /*    *  we can set up lighting, textures, and anything else that needs to be setup in InitGL().    */    if (!InitGL()) {                                      // Initialize our newly created GL window        KillGLWindow();                                   // Reset the display        MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);        return FALSE;                                     // Return FALSE    }    return TRUE;}LRESULT CALLBACK WndProc(HWND hWnd,                       // Handle for this window    UINT uMsg,                                            // Message for this window    WPARAM wParam,                                        // Additional message information    LPARAM lParam)                                        // Additional message information{    switch (uMsg) {                                       // Check for window message    case WM_ACTIVATE: {                               // Check minimization state        if (!HIWORD(wParam)) {            active = TRUE;                            // Program is active        }        else {            active = FALSE;                           // Program is no longer active        }        return 0;                                     // Return to the message loop    }    case WM_SYSCOMMAND: {                             // Intercept system commands        switch (wParam) {                             // Check system calls        case SC_SCREENSAVE:                       // Screensaver trying to start        case SC_MONITORPOWER:                     // Monitor trying to enter powersave            return 0;                                 // Prevent form happening        }        break;                                        // Exit    }    case WM_CLOSE: {                                  // Did we receive a close message        PostQuitMessage(0);                           // Send a quit message        return 0;    }    case WM_KEYDOWN: {                                // Is a key being held down        keys[wParam] = TRUE;                          // if so, mark it as TRUE        return 0;                                     // Jump back    }    case WM_KEYUP: {                                  // Has a key been released        keys[wParam] = FALSE;                         // if so, mark it as FALSE        return 0;                                     // Jump back    }    case WM_SIZE: {                                   // Resize the OpenGL window        ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));   // LoWord = width HiWord = height        return 0;                                     // Jump back    }    }    return DefWindowProc(hWnd, uMsg, wParam, lParam);     // Pass all unhandled message to DefWindwProc}int WINAPI WinMain(HINSTANCE hInstance,                   // Instance    HINSTANCE hPrevInstance,                              // Previous instance    LPSTR lpCmdLine,                                      // Command line parameters    int nCmdShow)                                         // Window show state{    MSG msg;                                              // Window message structure    BOOL done = FALSE;                                    // Bool variable to exit loop        // Ask the user which screen mode they prefer    if (MessageBox(NULL, "Would you like to run in fullscreen mode?",        "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO)    {        fullscreen = FALSE;                               // Window mode    }    // Create our OpenGL window    if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {  // (Modified)        return 0;                                         // Quit if window was not create    }    while (!done) {                                       // Loop that runs until donw = TRUE        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {   // Is there a message wating            if (msg.message == WM_QUIT) {                 // Havw we received a quit message                done = TRUE;                              // if so done  = TRUE            }            else {                                        // If not, deal with window message                TranslateMessage(&msg);                   // Translate message                DispatchMessage(&msg);                    // Dispatch message            }        }        else {            // Draw the scene. Watch for ESC key and quit message from DrawGLScene()            if (active) {                                 // Program active                if (keys[VK_ESCAPE]) {                    // Was ESC pressed                    done = TRUE;                          // ESC signalled a quit                }                else {                                    // Not time to quit, update screen                    DrawGLScene();                        // Draw scene                    SwapBuffers(hDC);                     // Swap buffers (double buffering)                }            }            /*            *  It allows us to press the F1 key to switch from fullscreen mode to            *  windowed mode or windowed mode to fullscreen mode.            */            if (keys[VK_F1]) {                            // Is F1 being pressed                keys[VK_F1] = FALSE;                      // If so make key FASLE                KillGLWindow();                           // Kill our current window                fullscreen = !fullscreen;                 // Toggle fullscreen / window mode                                                          //Recreate our OpenGL window(modified)                if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {                    return 0;                             // Quit if window was not create                }            }        }    }    gluDeleteQuadric(qobj);    glDeleteLists(cylList, 1);    // Shutdown    KillGLWindow();    return msg.wParam;}void DrawGLInfo(void){    GLfloat modelMatrix[16];             // The model view matrix    GLfloat projMatrix[16];              // The projection matrix    GLfloat DiffTime;                    // The difference in time    char String[64];                     // A temporary string to use to format information    glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);    glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);    // The cameras position    sprintf(String, "m_Position............. = %.02f, %.02f, %.02f",         gCamera.m_Position.x, gCamera.m_Position.y, gCamera.m_Position.z);    gFont.glPrintf(10, 720, 1, String);    // The cameras direction    sprintf(String, "m_DirectionVector...... = %.02f, %.02f, %.02f",         gCamera.m_DirectionVector.i, gCamera.m_DirectionVector.j, gCamera.m_DirectionVector.k);    gFont.glPrintf(10, 700, 1, String);    // The light sources position    sprintf(String, "m_LightSourcePos....... = %.02f, %.02f, %.02f",         gCamera.m_LightSourcePos.x, gCamera.m_LightSourcePos.y, gCamera.m_LightSourcePos.z);    gFont.glPrintf(10, 680, 1, String);    // The intersection point    sprintf(String, "ptIntersect............ = %.02f, %.02f, %.02f",         gCamera.ptIntersect.x, gCamera.ptIntersect.y, gCamera.ptIntersect.x);    gFont.glPrintf(10, 660, 1, String);    // The vector that points from the light source to the camera    sprintf(String, "vLightSourceToCamera... = %.02f, %.02f, %.02f",         gCamera.vLightSourceToCamera.i, gCamera.vLightSourceToCamera.j, gCamera.vLightSourceToCamera.k);    gFont.glPrintf(10, 640, 1, String);    // The vector that points from the light source to the intersection point    sprintf(String, "vLightSourceToIntersect = %.02f, %.02f, %.02f",         gCamera.vLightSourceToIntersect.i, gCamera.vLightSourceToIntersect.j, gCamera.vLightSourceToIntersect.k);    gFont.glPrintf(10, 620, 1, String);    // The below matrix is the model view matrix    sprintf(String, "GL_MODELVIEW_MATRIX");    gFont.glPrintf(10, 580, 1, String);    // The model view matrix    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         modelMatrix[0], modelMatrix[1], modelMatrix[2], modelMatrix[3]);    gFont.glPrintf(10, 560, 1, String);        sprintf(String, "%.02f, %.02f, %.02f, %.02f",         modelMatrix[4], modelMatrix[5], modelMatrix[6], modelMatrix[7]);    gFont.glPrintf(10, 540, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         modelMatrix[8], modelMatrix[9], modelMatrix[10], modelMatrix[11]);    gFont.glPrintf(10, 520, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         modelMatrix[12], modelMatrix[13], modelMatrix[14], modelMatrix[15]);    gFont.glPrintf(10, 500, 1, String);    // The below matrix is the projection matrix    sprintf(String, "GL_PROJECTION_MATRIX");    gFont.glPrintf(10, 460, 1, String);    // The projection view matrix    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         projMatrix[0], projMatrix[1], projMatrix[2], projMatrix[3]);    gFont.glPrintf(10, 440, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         projMatrix[4], projMatrix[5], projMatrix[6], projMatrix[7]);    gFont.glPrintf(10, 420, 1, String);    sprintf(String, "%.02f, %.02f, %.03f, %.03f",         projMatrix[8], projMatrix[9], projMatrix[10], projMatrix[11]);    gFont.glPrintf(10, 400, 1, String);    sprintf(String, "%.02f, %.02f, %.03f, %.03f",         projMatrix[12], projMatrix[13], projMatrix[14], projMatrix[15]);    gFont.glPrintf(10, 380, 1, String);    // The below values are the Frustum clipping planes    gFont.glPrintf(10, 320, 1, "FRUSTUM CLIPPING PLANES");    // The clipping plane    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         gCamera.m_Frustum[0][0], gCamera.m_Frustum[0][1], gCamera.m_Frustum[0][2], gCamera.m_Frustum[0][3]);    gFont.glPrintf(10, 300, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         gCamera.m_Frustum[1][0], gCamera.m_Frustum[1][1], gCamera.m_Frustum[1][2], gCamera.m_Frustum[1][3]);    gFont.glPrintf(10, 280, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         gCamera.m_Frustum[2][0], gCamera.m_Frustum[2][1], gCamera.m_Frustum[2][2], gCamera.m_Frustum[2][3]);    gFont.glPrintf(10, 260, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",        gCamera.m_Frustum[3][0], gCamera.m_Frustum[3][1], gCamera.m_Frustum[3][2], gCamera.m_Frustum[3][3]);    gFont.glPrintf(10, 240, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         gCamera.m_Frustum[4][0], gCamera.m_Frustum[4][1], gCamera.m_Frustum[4][2], gCamera.m_Frustum[4][3]);    gFont.glPrintf(10, 220, 1, String);    sprintf(String, "%.02f, %.02f, %.02f, %.02f",         gCamera.m_Frustum[5][0], gCamera.m_Frustum[5][1], gCamera.m_Frustum[5][2], gCamera.m_Frustum[5][3]);    gFont.glPrintf(10, 200, 1, String);    if (gFrames >= 100) {        gCurrentTime = timeGetTime();        DiffTime = GLfloat(gCurrentTime - gStartTime);        gFPS = (gFrames / DiffTime) * 1000.0f;        gStartTime = gCurrentTime;        gFrames = 1;    }    else {        gFrames++;    }    sprintf(String, "FPS %.02f", gFPS);    gFont.glPrintf(10, 160, 1, String);}void CheckKeys(void){    if (keys[S] == TRUE) {        gCamera.ChangePitch(-0.05f);    }    if (keys[W] == TRUE) {        gCamera.ChangePitch(0.05f);    }    if (keys[A] == TRUE) {        gCamera.ChangeHeading(0.05f);    }    if (keys[D] == TRUE) {        gCamera.ChangeHeading(-0.05f);    }    if (keys[Z] == TRUE) {        gCamera.m_ForwardVelocity = 0.02f;    }    if (keys[C] == TRUE) {        gCamera.m_ForwardVelocity = -0.02f;    }    if (keys[X] == TRUE) {        gCamera.m_ForwardVelocity = 0.0f;    }    if (keys[1] == TRUE) {        infoOn = TRUE;    }    if (keys[2] == TRUE) {        infoOn = FALSE;    }}
Main.cpp

Thanks for Nehe‘s tutorials, this is his home.

outdated: 44.3D Lens Flare With Occlusion Testing