SHARE
Facebook X Pinterest WhatsApp

OpenGL screen savers

How to develop a fantastic 3D screen saver with OpenGL 1.1 Environment: VC5.0, Win95/98, NT4.0 This article just gives a description about how to use some new render functions in OpenGL 1.1 with a fantastic 3D screen saver. And give a practical method to solve the problem about how to instance the setting dialogbox successfully […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Mar 17, 1999
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

How to develop a fantastic 3D screen saver with OpenGL 1.1

Environment: VC5.0, Win95/98, NT4.0

This article just gives a description about how to use some
new render functions in OpenGL 1.1 with a fantastic 3D screen
saver. And give a practical method to solve the problem about how to
instance the setting dialogbox successfully from windows
system properties dialogbox both in Win95 and NT. The code also give
a demo to use function pointer.

  1. Interleaved arrays and indices array for rendering.
    In OpenGl 1.1, there are some new functions quite different
    from old Version, which make rendering 3D picture faster and easily in
    coding.
  2. One of new methods in OpenGl 1.1 is that it can allow the
    developer to set the most important data , such as texture, colors,
    normals, vertexs, in an interleaved data structure body and build one vertex
    array. Besides that, an indices array is necessary for rendering. The two key
    functions in this realization are “glInterleavedArrays” and
    “glDrawArrays”. The definition of vertex structure for “glInterleavedArrays”
    function depends on what format will be used in “glInterleavedArrays”. The
    definition of the indices array also bases on what type of rendering index in
    “glDrawArrays” The following is the vertex structure and indices (with C++
    template) in this demo.
    //Vertex value of the object
    template <class Typeclass vertex
    {
    public:
        Type m_texture[2];
        Type m_normal[3];
        Type m_vertex[3];
    public:
        vertex(){};
        ~vertex(){};
        void SetTexture(Type texture1, Type texture2)
        {
            m_texture[0] = texture1;
            m_texture[1] = texture2;
        };
        void GetTexture(Type* texture1, Type* texture2)
        {
            *texture1 = m_texture[0];
            *texture2 = m_texture[1];
        };
        void SetNormal(Type normal1, Type normal2, Type normal3)
        {
            m_normal[0] = normal1;
            m_normal[1] = normal2;
            m_normal[2] = normal3;
        };
        void GetNormal(Type* normal1, Type* normal2, Type* normal3)
        {
            *normal1 = m_normal[0];
            *normal2 = m_normal[1];
            *normal3 = m_normal[2];
        };
        void SetVertex(Type vertex1, Type vertex2, Type vertex3)
        {
            m_vertex[0] = vertex1;
            m_vertex[1] = vertex2;
            m_vertex[2] = vertex3;
        };
        void GetVertex(Type* vertex1, Type* vertex2, Type* vertex3)
        {
            *vertex1 = m_vertex[0];
            *vertex2 = m_vertex[1];
            *vertex3 = m_vertex[2];
        };
    };
    typedef vertex<float fVertex;
    //Indices value of the object
    template <class Typeclass indices
    {
    public:
        Type m_indice[2];
    public:
        indices(){};
        ~indices(){};
        void SetIndices(Type indice1, Type indice2)
        {
             m_indice[0] = indice1;
             m_indice[1] = indice2;
        };
        void GetIndices(Type* indice1, Type* indice2)
        {
             *indice1 = m_indice[0];
             *indice2 = m_indice[1];
        };
    };
    typedef indices<unsigned int uiIndice;
    The rendering implementation in code is
    class CSGObject : public CObject
    {
    //Attribute
    private:
    …………
        fVertex*    m_vertex;   //vertex array
        uiIndice*   m_indice;   //indices array
    …………
        float       m_x;        //x-coordinate of the center of object
        float       m_y;        //y-coordinate of the center of object
        float       m_z;        //z-coordinate of the center of object
        float       m_sx;       //scale in x-axis
        float       m_sy;       //scale in y-axis
        float       m_sz;       //scale in z-axis
        float       m_rx;       //rotating angle around x-axis
        float       m_ry;       //rotating angle around y-axis
        float       m_rz;       //rotating angle around z-axis
        BOOL        m_bWire;    //flag for showing wireframe or not
    public:
    …………
        void DrawObject(void);
    …………
    };
    void CSGObject::DrawObject(void)
    {
        int k;
        int i;
        if(m_bWire)
        {
             m_dvalue.SetValue(m_dMemvalue.m_dX*4, m_dMemvalue.m_dY*4, m_dMemvalue.m_dZ*4);
             m_size.SetValue((int)(m_Memsize.m_row*2.5), (int)(m_Memsize.m_col*2.5));
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        }
        else
        {
             m_dvalue.SetValue(m_dMemvalue.m_dX, m_dMemvalue.m_dY, m_dMemvalue.m_dZ);
             m_size.SetValue(m_Memsize.m_row*10, m_Memsize.m_col*10);
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        }
        if(m_Oldsize.m_row != m_size.m_row || m_Oldsize.m_col != m_size.m_col)
        {
            if(m_vertex)
                 delete []m_vertex;
            if(m_indice)
                 delete []m_indice;
            m_vertex = new fVertex[(m_size.m_row+1) * (m_size.m_col+1)];
            m_indice = new uiIndice[m_size.m_row * (m_size.m_col+1)];
            (*FuncIndice)(m_indice, m_size);
            m_Oldsize.m_row = m_size.m_row;
            m_Oldsize.m_col = m_size.m_col;
        }
        (*FuncVertex)(m_vertex, m_size, m_factor, m_dvalue);
        SetTexture();
        glInterleavedArrays(GL_T2F_N3F_V3F, 0, m_vertex);
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glEnable(GL_COLOR_MATERIAL);
        glMatrixMode(GL_MODELVIEW);
        glTranslatef(m_x, m_y, m_z);
        glScalef(m_sx, m_sy, m_sz);
        glRotatef(m_rx, 1.0, 0.0, 0.0);
        glRotatef(m_ry, 0.0, 1.0, 0.0);
        glRotatef(m_rz, 0.0, 0.0, 1.0);
        for(i=0; i< m_size.m_row; i++)
        {
            k = i*(m_size.m_col+1);
            glDrawElements(GL_TRIANGLE_STRIP, 2*(m_size.m_col+1), GL_UNSIGNED_INT, &m_indice[k]);
        }
        glRotatef((float)(-1.0 * m_rz), 0.0, 0.0, 1.0);
        glRotatef((float)(-1.0 * m_ry), 0.0, 1.0, 0.0);
        glRotatef((float)(-1.0 * m_rx), 1.0, 0.0, 0.0);
        glScalef((float)(1.0f/m_sx), (float)(1.0f/m_sy), (float)(1.0f/m_sz));
        glTranslatef((float)(-1.0 * m_x), (float)(-1.0 * m_y), (float)(-1.0 * m_z));
    }
    
  3. Texture
    By the way of calling glEnable(GL_TEXTURE_2D),
    glTexImage2D(………) and
    glInterleavedArrays(………), the texture map can be
    realized.
  4. Fogs
    The fogs in rendering is implemented by the functions of glFog
    and glEnable(GL_FOG).
  5. Function pointer
    In this code, there is only one universal geometry object
    class. In this class, there is a pointer of geometry data calculation
    function. Signing different 3D geometry data generating
    function to this function pointer can create different geometry object.
  6. About triggering setting dialogbox from Windows properties
    dialog box.
    This sample gives a practical method to solve the problem of
    instancing the setting dialogbox. The key point is that the message for
    clicking setting button in Windows system properties dialogbox in Win95
    is different from in NT. In Win95, command line __argv[1] for clicking
    setting dialogbox is “/c”, but in NT, is “/c XXXXXX”, XXXXXX is a number, may be
    the system dialogbox window handle or other window handle (I am not sure).
    So parsing the __argv[1] should be in single character not
    string. This part of code is shown following:
    BOOL CGlsaverApp::InitInstance()
    {
        // Standard initialization
        // If you are not using these features and wish to reduce the size
        //  of your final executable, you should remove from the following
        //  the specific initialization routines you do not need.
        Enable3dControls();
        enmCMDline cmdLine;
        cmdLine = getCMDline(__argv[1]);
        if (__argc == 1 || getCMDline(__argv[1]) == CMD_SETTING)
             DoSaverSetting();
        else if(getCMDline(__argv[1]) == CMD_PREVIEW)
        {
             DoSaverPreview();
             return TRUE;
        }
        else if(getCMDline(__argv[1]) == CMD_SAVER)
        {
             DoScreenSaver();
             return TRUE;
        }
        // Nothing happened, return FALSE so that we exit the
        //  application, rather than start the application’s message pump.
        return FALSE;
    }
    enmCMDline CGlsaverApp::getCMDline(LPTSTR pszCmd)
    {
        if (pszCmd[0] == _T(‘-‘) || pszCmd[0] == _T(‘/’))
             pszCmd++;
        LPTSTR  pszChar = pszCmd;
        switch(*pszChar)
        {
            case _T(‘c’):
                  return CMD_SETTING;
            case _T(‘C’):
                  return CMD_SETTING;
            case _T(‘p’):
                  return CMD_PREVIEW;
            case _T(‘P’):
                  return CMD_PREVIEW;
            case _T(‘s’):
                  return CMD_SAVER;
            case _T(‘S’):
                  return CMD_SAVER;
            default:
                  return CMD_NONE;
        }
    }

Download source – 48KB

Date Posted: 03/17/99

Recommended for you...

Drawing 3D OpenGL Graphics on Google Maps
Mandelbrot Using C++ AMP
CodeGuru Staff
Jan 27, 2012
Simple C++ MP3 Player Class
CodeGuru Staff
Aug 22, 2011
Library for Raw Video Processing
CodeGuru Staff
Jun 14, 2011
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.