Opengl:why Glcolor4Fv() Does Not Change Color?

Started by
6 comments, last by nickme 7 years, 9 months ago

hi everyone

when i called the glColor4fv(v), it did not set the color to v. let me show the codes then the screen output:


const GLfloat White[4] = { 1.0, 1.0, 1.0, 1.0 }; // solid White
const GLfloat Transparent_White[4] = { 1.0, 1.0, 1.0, 0.65f }; // ~ half White
const GLfloat Black[4] = { 0.0, 0.0, 0.0, 1.0 }; // Black
const GLfloat Blue[4] = { 0.0, 0.0, 1.0, 1.0 }; // Blue
const GLfloat Yellow[4] = { 1.0, 1.0, 0.0, 1.0 }; // Yellow
const GLfloat Green[4] = { 0.0, 1.0, 0.0, 1.0 }; // Green
const GLfloat Red[4] = { 1.0, 0.0, 0.0, 1.0 }; // Red
const GLfloat Cyan[4] = { 1.0, 0.0, 1.0, 1.0 }; // Cyan
void clear()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
void draw_box(GLint l, GLint b, GLint r, GLint t, const GLfloat c[4])
{
glColor4fv( c );
glBegin(GL_QUADS); // draw the foreground color box
glVertex2i(l, b);
glVertex2i(r, b);
glVertex2i(r, t);
glVertex2i(l, t);
glEnd();
}
void Msg(GLint x, GLint y, char *c, const GLfloat fg[4], const GLfloat bg[4])
{
int wl = 0, strlenght = strlen(c);
for (int i = 0; i <= strlenght; i++)
wl = wl + glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, c);
draw_box(x - 10, y + 10, x + wl + 10, y - 18 - 4, bg); // draw background
glColor4fv(fg);
glRasterPos2i(x, y);
for (int i = 0; i <= strlenght; i++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, c);
}
void render()
{
if (once) {
once = false;
clear();
Msg(100, 100, " this is a test ", Red, Blue);
draw_box(200, 300, 250, 200, Yellow); // draw rect
draw_box(300, 300, 350, 200, Cyan); // draw rect
glFlush();
}
}
how to set colors to it intended. I tried to add glClear() and/or glClearColor() but they were not what i intended. it either clear the screen or did not works.
Advertisement

Ok, first things first.

Calling glClear(GL_COLOR_BUFFER_BIT) will clear the color buffer (ie. the screen) with the color you specify with glClearColor().

You also only need to set the clear color once, so call glClearColor() once when you initialize your program, and then, you only need to call glClear() at the start of every frame to clear the color buffer (instead of calling both everytime, like you do on your clear function).

Next, in order for transparency to work, you need to enable blending.

To do this, call


//Enable alpha blending
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

You also only need to do this once, when you initialize your program, just like glClearColor().

Now, inspecting your rendering code and your screen shot, it appear that the text's background box is not being drawn at all, and that every subsequent draw uses that first box' color (red).

Honestly I can't really see what's causing the problem.

Can you post you're entire code? If so I'll be able to test it in my computer, and I'll be able to help you more.

I don't know exactly why this doesn't work but I recall something with opengl that if you enable texturing then colours no longer function as you expect (It might be using lighting that causes the change, I am not sure). Since those are bitmap characters you are drawing they will be using texturing and this may be messing around with how your colours work. Try disabling texturing before drawing those boxes and see what happens.


void draw_box(GLint l, GLint b, GLint r, GLint t, const GLfloat c[4])
{
  glDisable(GL_TEXTURE_2D);
  glDisable(GL_LIGHTING);
  glColor4fv( c );
  glBegin(GL_QUADS); // draw the foreground color box
  glVertex2i(l, b);
  glVertex2i(r, b);
  glVertex2i(r, t);
  glVertex2i(l, t);
  glEnd();
}

It might be worth showing your initialisation code.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

I don't know exactly why this doesn't work but I recall something with opengl that if you enable texturing then colours no longer function as you expect

Yes, i thought that too, but if i recall correctly, having texturing enabled without specifying a texture ( with an ID of 0) will prevent any non-textured objects to appear at all.

The lighting could also be a problem, but even if he had light enabled by mistake, the objects should appear black (or grey?) if he didn't specify a light color/position.

And he would also have to enable texturing and lighting, because they're disabled by default.

I might be wrong though.

It might be worth showing your initialisation code.

Yeah, or the whole code, if possible.

I could be wrong, but usually the vertex attributes are set after starting a drawing command, try this:

glBegin(GL_QUADS); // draw the foreground color box
glColor4fv( c );
glVertex2i(l, b);
glVertex2i(r, b);
glVertex2i(r, t);
glVertex2i(l, t);
glEnd();
Also, inb4 OpenGL 1.1 nonsense.

hi everyone.

here is my new codes

#include "source.h"

GLuint tex;
const int sizeX = 640, sizeY = 480;
const GLint iw = 839, ih = 665;
const int l = 0, r = sizeX, b = sizeY, t = 0;
const int texture_width = 16, texture_height = 16;
const int col = 3, row = 8;
const int bw = 280, bh = 82;
const int mx = 1910, my = 1100, maxbuttons = 18;
const int ss = texture_width * texture_height;
const GLfloat White[4] = { 1.0, 1.0, 1.0, 1.0 }; // solid White
const GLfloat Transparent_White[4] = { 1.0, 1.0, 1.0, 0.65f }; // ~ half White
const GLfloat Black[4] = { 0.0, 0.0, 0.0, 1.0 }; // Black
const GLfloat Blue[4] = { 0.0, 0.0, 1.0, 1.0 }; // Blue
const GLfloat Yellow[4] = { 1.0, 1.0, 0.0, 1.0 }; // Yellow
const GLfloat Green[4] = { 0.0, 1.0, 0.0, 1.0 }; // Green
const GLfloat Red[4] = { 1.0, 0.0, 0.0, 1.0 }; // Red
const GLfloat Cyan[4] = { 1.0, 0.0, 1.0, 1.0 }; // Cyan
typedef struct { double su, sv, eu, ev; int x, y, ix, iy; } Coordv;
Coordv V[maxbuttons+1];
GLuint MenuID, buttonsID, palID, ID2, ID3;
bool once = true;
void Msg(GLint x, GLint y, char *c, const GLfloat fg[4], const GLfloat bg[4]);
void clear()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
void cleanup() {
glDeleteTextures(1, &palID);
glDeleteTextures(1, &buttonsID);
glDeleteTextures(1, &MenuID);
}
void show_error_msg(const char* filename)
{
char buffer[140] = "File \"";
strcat_s(buffer, filename);
strcat_s(buffer, "\" not found.");
clear();
Msg(sizeX/2-100, sizeY/2, buffer, White, Red);
glFlush();
cleanup();
printf(" error in downloading file : [%s] \n\n", filename);
system("pause");
exit(1);
}
void LoadTexture2D(const char *filename)
{
GLuint textureID;
textureID = SOIL_load_OGL_texture(filename, SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID, SOIL_FLAG_TEXTURE_REPEATS);
if (0 == textureID) {
show_error_msg(filename);
}
return textureID;
}
GLuint LoadTexture1D(char * filename, int size)
{
GLuint texture;
GLubyte * data = new unsigned char[size * 3]; // texture data for color bar file
FILE * texture_file;
fopen_s(&texture_file, filename, "rb");
if (texture_file == NULL) {
show_error_msg(filename);
}
fread(data, 1, size * 3, texture_file);
fclose(texture_file);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, size * 3, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
delete[] data;
return texture;
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{ // doesnot allow window size change
glutReshapeWindow(sizeX, sizeY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(l, r, b, t);
glMatrixMode(GL_MODELVIEW);
}
void draw_box(GLint l, GLint b, GLint r, GLint t, const GLfloat c[4])
{
glColor4fv(c);
glRecti(l, b, r, t); // draw the foreground color box
}
void Msg(GLint x, GLint y, char *c, const GLfloat fg[4], const GLfloat bg[4])
{
int wl = 0, strlenght = strlen(c);
for (int i = 0; i <= strlenght; i++)
wl += glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, c); //height = 18
glColor4fv(bg);
glRectd(x - 10, y + 10, x + wl + 10, y - 18 - 4); // draw background
glColor4fv(fg);
glRasterPos2i(x, y);
for (int i = 0; i <= strlenght; i++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, c);
}
void render()
{
GLdouble ds = 4.0f, x = 10.0;
if (once) {
once = false;
clear();
Msg(100, 100, " this is a test ", White, Green);
draw_box(200, 300, 250, 200, Yellow); // draw background
draw_box(300, 300, 350, 200, Cyan); // draw background
glColor4fv(White);
glRectd(400, 200, 500, 250);
glFlush();
}
}
void init()
{
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
}
void processNormalKeys(unsigned char key, int x, int y)
{
if (true || key == ' ' || key == 27) { //any key will quit
cleanup();
exit(0);
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(sizeX, sizeY);
glutCreateWindow("Testing Program");
init();
glutIgnoreKeyRepeat(1);
glutReshapeFunc(winReshapeFcn);
glutKeyboardFunc(processNormalKeys);
glutDisplayFunc(render);
glutMainLoop();
cleanup();
return 0;
}

Ok, just by glancing at it, you have GL_TEXTURE_2D enabled.

Call glDisable(GL_TEXTURE_2D) before you draw non-textured polygons.

I could be wrong, but usually the vertex attributes are set after starting a drawing command

Both work.

You can put glColor*() calls both outside or inside glBegin() glEnd() calls.

I usually put it outside if using a single color for the whole polygon, and inside if using per vertex color (when I use old fixed function OpenGL anyway).

hi

per your suggestion, I disabled the texturing in the init() and it works.

thanks everyone.

This topic is closed to new replies.

Advertisement