OpenGL study notes: color (RGBA color, color index mode)

OpenGL supports two color modes : one is RGBA and the other is color index mode

Regardless of the color mode, the computer must save some data for each pixel.

The difference is that in the RGBA mode, the data directly represents the color; in the color index mode, the data represents an index. To get the real color, you must look up the index table.

1. RGBA color
In RGBA mode, each pixel will save the following data: R value (red component), G value (green component), B value (blue component) and A value (alpha component). Among them, the combination of red, green, and blue can get the various colors we need, and alpha does not directly affect the color, it will be introduced later.
 Choosing a color in RGBA mode is very simple, and only needs a function to do it. 
The glColor* series of functions can be used to set colors. The three-parameter version can specify the values ​​of R, G, and B, and the A value is the default;
the four-parameter version can specify the values ​​of R, G, B, and A respectively.

E.g:

void glColor3f(GLfloat red, GLfloat green, GLfloat blue);
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
(3f means that there are three floating-point parameters ~ please see the description of the glVertex* function in the second lesson.) 
Use floating-point numbers as parameters, where 0.0 means not to use this color, and 1.0 means to use this color the most.

E.g:

glColor3f(1.0f, 0.0f, 0.0f); //Indicates that green and blue are not used, but red is used the most, so the purest red is obtained.
glColor3f(0.0f, 1.0f, 1.0f); //Indicates to use green, blue to the most, not red. The result of the blend is a light blue.
glColor3f(0.5f, 0.5f, 0.5f); //Indicates that half of each color is used, and the effect is gray.
Note: Floating-point numbers can be accurate to a few decimal places, which does not mean that computers can display so many colors.
In reality, the number of colors a computer can display will be determined by the hardware. If OpenGL can't find an exact color, it does something like "rounding up".

You can draw rectangles of different colors by changing the parameter value of glColor3f in the following code.

void myDisplay1(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0f, 1.0f, 1.0f);
    glRectf(-0.5f, -0.5f, 0.0f, 0.0f);
    glFlush();
}
Note: The glColor series functions, when the parameter types are different, the value representing the "largest" color is also different. 
A function suffixed with f and d, with 1.0 for maximum usage. 
A function that uses b as a suffix, with 127 representing the maximum use. 
A function that uses ub as the suffix, with 255 representing the maximum use. 
A function suffixed with s, with 32767 representing the maximum usage. 
The function that uses us as the suffix is ​​65535 to indicate the maximum use. 

These rules may seem cumbersome, but after being familiar with them, there will be no obstacles in actual use.

2. Indexed color 
In indexed color mode, OpenGL requires a color table. This table is equivalent to a painter's palette: although many colors can be called up, the number of colors that exist on the palette at the same time will not exceed the number of grids in the palette. Think of each entry in the color table as a grid on the palette: it holds a color. 
When drawing in indexed color mode, when I say "I set the ith color to so-and-so", I actually set the ith style of the palette to so-and-so color. "I need the kth color to paint", then use the brush to dip the kth color palette. The size of the color table is very limited, generally between 256 and 4096, and is always an integer power of 2. When plotting with indexed color, always set the color table first, then select the color.
2.1. Selecting a color 
Use the glIndex* series of functions to select a color in the color table. The most common of these is probably glIndexi, whose argument is an integer. 
void glIndexi(GLint c);
2.2, set the color table 

OpenGL does not directly provide a method for setting the color table, so setting the color table requires the support of the operating system. Windows and most other graphical operating systems we use have this feature, but use a different function. Just as I didn't describe how to write my own code to create a window under Windows, I also won't describe how to set the color table under Windows. The GLUT toolkit provides the function glutSetColor to set the color table, but my tests always have problems. Now to give you a taste of indexed colors, I introduce you to another OpenGL toolkit: aux. This toolkit comes with VisualStudio and does not need to be installed separately, but it is out of date, here is just an experience, you don't need to go deep.

/* glaux.h is not installed, we will discuss it later
#include <GL/glaux.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glaux.lib")

const GLdouble Pi = 3.1415926536;
void myDisplay5(void)
{
    int i;
    for(i=0; i<8; ++i)
        auxSetOneColor(i, (float)(i&0x04), (float)(i&0x02), (float)(i&0x01));
    glShadeModel(GL_FLAT);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLE_FAN);
    glVertex2f(0.0f, 0.0f);
    for(i=0; i<=8; ++i)
    {
        glIndexi(i);
        glVertex2f(cos(i*Pi/4), sin(i*Pi/4));
    }
    glEnd();
    glFlush();
}*/
You can ignore other parts, just look at the myDisplay function.
First, use auxSetOneColor to set a cell in the color table. Eight grids can be set by looping eight times. glShadeModel will be discussed later, so I won't mention it here. 
Then use glVertex in the loop to set the vertex, and use glIndexi to change the color represented by the vertex. 
The end result is eight triangles of the same shape and different colors. Indexed colors are a bit more talkative though.

The main advantage of indexed color is that it takes up less space (each pixel does not have to save its own color separately, and only a few binary bits can represent the position of its color in the color table), it consumes less system resources, and the graphics operation speed is fast, But its programming is a little less convenient, and the picture effect will be worse than RGB color. "StarCraft" may represent the visual effect of the 256-color color table, and although it can run smoothly on a bad PC, the visual effect of the current point of view is insufficient. The current PC performance is enough to use RGB colors in various occasions, so in the development of PC programs, the use of indexed colors is no longer the mainstream. Of course, for some small devices such as GBA, mobile phones, etc., indexed color still has its place.

3. Specify the color used to clear the screen 
glClear(GL_COLOR_BUFFER_BIT);
means to clear the color on the screen. 
But what actually is "empty"? In the universe, black represents "empty"; on a white paper, white represents "empty"; on an envelope, the color of the envelope is "empty". 
OpenGL uses the following functions to define the colors the screen will have when the screen is cleared. 
In RGB mode, use glClearColor to specify the "empty" color, which requires four parameters, the meaning of which is similar to that of glColor4f. 

In indexed color mode, use glClearIndex to specify the index of the "empty" color, which requires a parameter, which is similar in meaning to glIndexi.

/* Specify the color used to clear the screen */
void myDisplay3(void)
{
    glClearColor(1.0f, 1.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
}
4. Specify the shading model 

OpenGL allows specifying different colors for different vertices of the same polygon. E.g:

/* Specify shading model */
const GLdouble Pi = 3.1415926536;
void myDisplay4(void)
{
    int i;
    // glShadeModel(GL_FLAT);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLE_FAN);
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex2f(0.0f, 0.0f);
    for(i=0; i<=8; ++i)
    {
        glColor3f(i&0x04, i&0x02, i&0x01);
        glVertex2f(cos(i*Pi/4), sin(i*Pi/4));
    }
    glEnd();
    glFlush();
}
By default, OpenGL will calculate other points between two vertices and fill them with "appropriate" colors, so that the color values ​​of adjacent points are relatively close. If you use RGB mode, it looks like a gradient. If the color index mode is used, the index values ​​of its adjacent points are close, and if the close items in the color table are set to close colors, it also looks like a gradient effect. But if the colors of items that are close to each other in the color table are very different, it may look like a strange effect. 
This calculation can be turned off using the glShadeModel function, and if the vertices have different colors, all other points between the vertices are set to be the same as one point. (The color of the points specified after the line will prevail, while the polygon will follow the color of any vertex, which is up to the implementation.) To avoid this uncertainty, try to use the same color in the polygon. 

How to use glShadeModel

glShadeModel(GL_SMOOTH); // smoothing mode, which is also the default
glShadeModel(GL_FLAT); // Monochrome
Summary:
This lesson learned how to set colors. Among them, the RGB color method is the commonly used method on PCs at present. 
You can set the color left on the screen after glClear clears. 

You can set the color fill method: smooth or monochrome.

Operating environment:

CentOS7
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
OpenGL implementation vendor's name: VMware, Inc.
Renderer identifier: Gallium 0.4 on llvmpipe (LLVM 3.9, 256 bits)
Version number of OpenGL implementation: 2.1 Mesa 17.0.1
OGLU tool library version: 1.3

The source code is given below :

/**
 * "OpenGL Introductory Tutorial"
 * RGBA color, color index mode.
 */
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

/*RGBA color*/
void myDisplay1(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0f, 1.0f, 1.0f);
    glRectf(-0.5f, -0.5f, 0.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glRectf(-0.5f, -0.5f, 0.0f, 0.0f);
    glFlush();
}

/*RGBA color kettle outline*/
void myDisplay2(void)
{
    glClearColor(1.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glOrtho (-5, 5, -5, 5, 5, 15);
    glMatrixMode(GL_MODELVIEW);
    gluLookAt (0, 0, 10, 0, 0, 0, 0, 1, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 0);
    glutWireTeapot(3);
    glFlush();

}
/* Specify the color used to clear the screen */
void myDisplay3(void)
{
    glClearColor(1.0f, 1.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
}
/* Specify shading model */
const GLdouble Pi = 3.1415926536;
void myDisplay4(void)
{
    int i;
    // glShadeModel(GL_FLAT);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLE_FAN);
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex2f(0.0f, 0.0f);
    for(i=0; i<=8; ++i)
    {
        glColor3f(i&0x04, i&0x02, i&0x01);
        glVertex2f(cos(i*Pi/4), sin(i*Pi/4));
    }
    glEnd();
    glFlush();
}
/* glaux.h is not installed, we will discuss it later
#include <GL/glaux.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glaux.lib")

const GLdouble Pi = 3.1415926536;
void myDisplay5(void)
{
    int i;
    for(i=0; i<8; ++i)
        auxSetOneColor(i, (float)(i&0x04), (float)(i&0x02), (float)(i&0x01));
    glShadeModel(GL_FLAT);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLE_FAN);
    glVertex2f(0.0f, 0.0f);
    for(i=0; i<=8; ++i)
    {
        glIndexi(i);
        glVertex2f(cos(i*Pi/4), sin(i*Pi/4));
    }
    glEnd();
    glFlush();
}*/

int main(int argc, char *argv[])
{
    /*initialization*/
    glutInit(&argc, argv);
    /* Set display mode: RGB color, single buffer */
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    /* Set to the center of the window */
    glutInitWindowPosition (100, 100);
    /* set window size */
    glutInitWindowSize (200, 200);
    /* create window */
    glutCreateWindow("Paint1");
    /* set a function */
    glutDisplayFunc(&myDisplay1);
    /* create window */
    glutCreateWindow("Paint2");
    /* set a function */
    glutDisplayFunc(&myDisplay2);
    /* create window */
    glutCreateWindow("Paint3");
    /* set a function */
    glutDisplayFunc(&myDisplay3);
    /* create window */
    glutCreateWindow("Paint4");
    /* set a function */
    glutDisplayFunc(&myDisplay4);

    /* Do a message loop */
    glutMainLoop();
    return 0;
}

Compile and run:

$ make
gcc test.c -lGL -lglut -lGLU -lXmu -Bstatic -Bdyanmic -lm
./a.out

Result graph:


The code and content are from " OpenGL Introductory Tutorial (fine) ", if there is any infringement, please contact to delete it.

The last code written for a Terrence Ma :

// Name     : OpenGL Color Cube
// Author   : Terrence Ma
// Email    : [email protected]
// Web      : http://www.terrence.com
// Date     : 10/25/2001
// Modified : Tutorial sample from Mesa3d.org (http://www.mesa3d.org)
 
/*
 * Copyright (c) 1993-1997, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 * Permission to use, copy, modify, and distribute this software for
 * any purpose and without fee is hereby granted, provided that the above
 * copyright notice appear in all copies and that both the copyright notice
 * and this permission notice appear in supporting documentation, and that
 * the name of Silicon Graphics, Inc. not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission.
 *
 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * US Government Users Restricted Rights
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
 * clause at DFARS 252.227-7013 and/or in similar or successor
 * clauses in the FAR or the DOD or NASA FAR Supplement.
 * Unpublished-- rights reserved under the copyright laws of the
 * United States.  Contractor/manufacturer is Silicon Graphics,
 * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
 *
 * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
 */
 
/*
 *  aapoly.c
 *  This program draws filled polygons with antialiased
 *  edges.  The special GL_SRC_ALPHA_SATURATE blending
 *  function is used.
 *  Pressing the 't' key turns the antialiasing on and off.
 */
#include <GL/glut.h>
#include <stdlib.h>
 
GLboolean polySmooth = GL_TRUE;
 
static void init(void)
{
    glCullFace (GL_BACK);
    glEnable (GL_CULL_FACE);
    glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);
    glClearColor (0.0, 0.0, 0.0, 0.0);
}
 
#define NFACE 6
#define NVERT 8
void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1,
        GLdouble z0, GLdouble z1)
{
   static GLfloat v[8][3];
   static GLfloat c[8][4] = {
      {0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 1.0},
      {0.0, 1.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 1.0},
      {0.0, 0.0, 1.0, 1.0}, {1.0, 0.0, 1.0, 1.0},
      {0.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}
   };
 
/*  indices of front, top, left, bottom, right, back faces  */
   static GLubyte indices[NFACE][4] = {
      {4, 5, 6, 7}, {2, 3, 7, 6}, {0, 4, 7, 3},
      {0, 1, 5, 4}, {1, 5, 6, 2}, {0, 3, 2, 1}
   };
 
   v [0] [0] = v [3] [0] = v [4] [0] = v [7] [0] = x0;
   v[1][0] = v[2][0] = v[5][0] = v[6][0] = x1;
   v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
   v [2] [1] = v [3] [1] = v [6] [1] = v [7] [1] = y1;
   v [0] [2] = v [1] [2] = v [2] [2] = v [3] [2] = z0;
   v[4][2] = v[5][2] = v[6][2] = v[7][2] = z1;
 
#ifdef GL_VERSION_1_1
   glEnableClientState (GL_VERTEX_ARRAY);
   glEnableClientState (GL_COLOR_ARRAY);
   glVertexPointer (3, GL_FLOAT, 0, v);
   glColorPointer (4, GL_FLOAT, 0, c);
   glDrawElements (GL_QUADS, NFACE*4, GL_UNSIGNED_BYTE, indices);
   glDisableClientState (GL_VERTEX_ARRAY);
   glDisableClientState (GL_COLOR_ARRAY);
#else
   printf ("If this is GL Version 1.0, ");
   printf ("vertex arrays are not supported.\n");
   exit(1);
#endif
}
 
/*  Note:  polygons must be drawn from front to back
 *  for proper blending.
 */
void display(void)
{
   if (polySmooth) {
      glClear (GL_COLOR_BUFFER_BIT);
      glEnable (GL_BLEND);
      glEnable (GL_POLYGON_SMOOTH);
      glDisable (GL_DEPTH_TEST);
   }
   else {
      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glDisable (GL_BLEND);
      glDisable (GL_POLYGON_SMOOTH);
      glEnable (GL_DEPTH_TEST);
   }
 
   glPushMatrix ();
      glTranslatef (0.0, 0.0, -8.0);    
      glRotatef (30.0, 1.0, 0.0, 0.0);
      glRotatef (60.0, 0.0, 1.0, 0.0);
      drawCube(-0.8, 0.8, -0.8, 0.8, -0.8, 0.8);
   glPopMatrix ();
 
   glFlush ();
}
 
void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(30.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}
 
/* ARGSUSED1 */
void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 'T':
      case 't':
         polySmooth = !polySmooth;
         glutPostRedisplay();
         break;
      case 27:
         exit(0);  /*  Escape key  */
         break;
      default:
         break;
   }
}
 
/*  Main Loop
 */
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
                        | GLUT_ALPHA | GLUT_DEPTH);
   glutInitWindowSize (200, 200);
   glutCreateWindow("OpenGL Color Cube");
   init ();
   glutReshapeFunc (reshape);
   glutKeyboardFunc (keyboard);
   glutDisplayFunc (display);
   glutMainLoop();
   return 0;
}

The compilation method is the same as above, and the result is:


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325853411&siteId=291194637