the grayscale.fs does not rendering the result i want

Hello,
I am a learner to opengl, and i write the codes below to test the grayscale.fs which is an example of chapter 17 in OpenGL Superbible. But the result was all the items were black.


void renderScene(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2], 
		0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	glViewport(0, 0, windowWidth, windowHeight);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

	// Draw red cube
	glColor3f(1.0f, 0.0f, 0.0f);
	glutSolidCube(48.0f);

	// Draw green sphere
	glColor3f(0.0f, 1.0f, 0.0f);
	glPushMatrix();
	glTranslatef(-60.0f, 0.0f, 0.0f);
	glutSolidSphere(25.0f, 50, 50);
	glPopMatrix();

	// Draw magenta torus
	glColor3f(1.0f, 0.0f, 1.0f);
	glPushMatrix();
	glTranslatef(0.0f, 0.0f, 60.0f);
	glutSolidTorus(8.0f, 16.0f, 50, 50);
	glPopMatrix();
	glutSwapBuffers();
}

Many thanks,

Hi,

i see no code setting up and using a shader at all. Does the code work without a shader? From your code it’s also not clear in which matrix mode you are in.
May i also give you a hint: if you want to learn OpenGL, don’t waste your time with the old fixed function pipeline.

Hi,
the main code is below, and the problem is the plane,cube, sphere, torus,cone and teapot were black. what i want is the items in different gray color.

#include <stdio.h>
#include <stdlib.h>
#include <gl/glew.h>
#include <gl/glut.h>
#include <windows.h>
#include “…/creader/CReader.h”

#define MAX_INFO_LOG_SIZE 2048

GLuint v,f,p;
float lpos[4] = {1,0.5,1,0};
float a = 0;
GLuint time_id;
GLfloat lightPos = { 140.0f, 250.0f, 140.0f, 1.0f};
GLfloat ambientLight = { 0.2f, 0.2f, 0.2f, 1.0f};
GLfloat diffuseLight = { 0.7f, 0.7f, 0.7f, 1.0f};
GLfloat specularMaterial = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat cameraPos = { 100.0f, 75.0f, 150.0f, 1.0f};
GLint windowWidth = 1024; // window size
GLint windowHeight = 768;
GLint success;

void DrawModel()
{
// Draw plane that the objects rest on
glColor3f(0.0f, 0.0f, 0.90f); // Blue
glNormal3f(0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-100.0f, -25.0f, -100.0f);
glVertex3f(-100.0f, -25.0f, 100.0f);
glVertex3f(100.0f, -25.0f, 100.0f);
glVertex3f(100.0f, -25.0f, -100.0f);
glEnd();

// Draw red cube
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidCube(48.0f);

// Draw green sphere
glColor3f(0.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(-60.0f, 0.0f, 0.0f);
glutSolidSphere(25.0f, 50, 50);
glPopMatrix();

// Draw magenta torus
glColor3f(1.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(0.0f, 0.0f, 60.0f);
glutSolidTorus(8.0f, 16.0f, 50, 50);
glPopMatrix();

// Draw yellow cone
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glTranslatef(60.0f, 0.0f, -24.0f);
glutSolidCone(25.0f, 50.0f, 50, 50);
glPopMatrix();

// Draw cyan teapot
glColor3f(0.0f, 1.0f, 1.0f);
glPushMatrix();
glTranslatef(0.0f, 0.0f, -60.0f);
glutSolidTeapot(25.0f);
glPopMatrix();
}

void changeSize(int w, int h) {
// Prevent a divide by zero, when window is too short
if(h == 0) h = 1;
float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the viewport to be the entire window
glViewport(0, 0, w, h);

// Set the correct perspective.
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
}

void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2],
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glViewport(0, 0, windowWidth, windowHeight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
DrawModel();
glUniform1f(time_id, a);
glutSwapBuffers();
}

void setShaders()
{
char *vs = NULL,*fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);

CReader reader;
vs = reader.textFileRead(“passthrough.vert”);
fs = reader.textFileRead(“uniform.frag”);

const char * vv = vs;
const char * ff = fs;

glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);

free(vs);free(fs);
glCompileShader(v);
glGetShaderiv(v, GL_COMPILE_STATUS, &success);
if (!success)
{
GLchar infoLog[MAX_INFO_LOG_SIZE];
glGetShaderInfoLog(v, MAX_INFO_LOG_SIZE, NULL, infoLog);
fprintf(stderr, "Error in fragment shader #%s compilation!
", “v”);
fprintf(stderr, "Info log: %s
", infoLog);
Sleep(10000);
exit(0);
}
glCompileShader(f);
glGetShaderiv(f, GL_COMPILE_STATUS, &success);
if (!success)
{
GLchar infoLog[MAX_INFO_LOG_SIZE];
glGetShaderInfoLog(f, MAX_INFO_LOG_SIZE, NULL, infoLog);
fprintf(stderr, "Error in fragment shader #%s compilation!
", “f”);
fprintf(stderr, "Info log: %s
", infoLog);
Sleep(10000);
exit(0);
}

p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);
glLinkProgram(p);
glUseProgram(p);

time_id = glGetUniformLocation(p, “v_time”);
}

int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(windowWidth,windowHeight);
glutCreateWindow(“GPGPU Tutorial”);
glutDisplayFunc(renderScene);
/glutIdleFunc(renderScene);/
glutReshapeFunc(changeSize);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularMaterial);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128.0f);

glClearColor(1.0,1.0,1.0,1.0);
glColor3f(0.0,0.0,1.0);
glEnable(GL_CULL_FACE);
glewInit();

setShaders();

glutMainLoop();

return 0;
}

the shader:
//passthrough.vert
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

//uniform.frag
void main()
{
float gray = dot(gl_Color.rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(gray, gray, gray, 1.0);
}

Don’t use [ quote ] for code blocks. Use [ code ]. Keeps the formatting, and gives you a scroll window so it doesn’t take up so much thread space.

Here’s your code with the Windows-isms and CReader (which you didn’t provide) hacked out of it so it should be cross platform:


#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
#ifdef WIN32
#  include <windows.h>
#else
#  include <unistd.h>
#endif

#define MAX_INFO_LOG_SIZE 2048

GLuint v,f,p;
float lpos[4] = {1,0.5,1,0};
float a = 0;
GLuint time_id;
GLfloat lightPos[] = { 140.0f, 250.0f, 140.0f, 1.0f};
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f};
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f};
GLfloat specularMaterial[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat cameraPos[] = { 100.0f, 75.0f, 150.0f, 1.0f};
GLint windowWidth = 1024; // window size
GLint windowHeight = 768;
GLint success;

static const char Vertex_src[] = 
  "//passthrough.vert 
"
  "void main()"
  "{ 
"
  "  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
  "}";

static const char Fragment_src[] = 
  "//uniform.frag 
"
  "void main()"
  "{"
  "  float gray = dot(gl_Color.rgb, vec3(0.299, 0.587, 0.114));"
  "  gl_FragColor = vec4(gray, gray, gray, 1.0);"
  "}";

void mySleep( int sec )
{
#ifdef WIN32
  Sleep( sec * 1000 );
#else
  sleep( sec );
#endif
}

void DrawModel()
{
// Draw plane that the objects rest on
  glColor3f(0.0f, 0.0f, 0.90f); // Blue
  glNormal3f(0.0f, 1.0f, 0.0f);
  glBegin(GL_QUADS);
  glVertex3f(-100.0f, -25.0f, -100.0f);
  glVertex3f(-100.0f, -25.0f, 100.0f);
  glVertex3f(100.0f, -25.0f, 100.0f);
  glVertex3f(100.0f, -25.0f, -100.0f);
  glEnd();

// Draw red cube
  glColor3f(1.0f, 0.0f, 0.0f);
  glutSolidCube(48.0f);

// Draw green sphere
  glColor3f(0.0f, 1.0f, 0.0f);
  glPushMatrix();
  glTranslatef(-60.0f, 0.0f, 0.0f);
  glutSolidSphere(25.0f, 50, 50);
  glPopMatrix();

// Draw magenta torus
  glColor3f(1.0f, 0.0f, 1.0f);
  glPushMatrix();
  glTranslatef(0.0f, 0.0f, 60.0f);
  glutSolidTorus(8.0f, 16.0f, 50, 50);
  glPopMatrix();

// Draw yellow cone
  glColor3f(1.0f, 1.0f, 0.0f);
  glPushMatrix();
  glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
  glTranslatef(60.0f, 0.0f, -24.0f);
  glutSolidCone(25.0f, 50.0f, 50, 50);
  glPopMatrix();

// Draw cyan teapot
  glColor3f(0.0f, 1.0f, 1.0f);
  glPushMatrix();
  glTranslatef(0.0f, 0.0f, -60.0f);
  glutSolidTeapot(25.0f);
  glPopMatrix();
}

void changeSize(int w, int h) {
// Prevent a divide by zero, when window is too short
  if(h == 0) h = 1;
  float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

// Set the viewport to be the entire window
  glViewport(0, 0, w, h);

// Set the correct perspective.
  gluPerspective(45,ratio,1,1000);
  glMatrixMode(GL_MODELVIEW);
}

void renderScene(void) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2],
            0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
  glViewport(0, 0, windowWidth, windowHeight);
  glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  DrawModel();
  glUniform1f(time_id, a);
  glutSwapBuffers();
}

void setShaders()
{
  char *vs = NULL,*fs = NULL;
  v = glCreateShader(GL_VERTEX_SHADER);
  f = glCreateShader(GL_FRAGMENT_SHADER);

  const char * vv = Vertex_src;
  const char * ff = Fragment_src;

  glShaderSource(v, 1, &vv,NULL);
  glShaderSource(f, 1, &ff,NULL);

  free(vs);free(fs);
  glCompileShader(v);
  glGetShaderiv(v, GL_COMPILE_STATUS, &success);
  if (!success)
  {
    GLchar infoLog[MAX_INFO_LOG_SIZE];
    glGetShaderInfoLog(v, MAX_INFO_LOG_SIZE, NULL, infoLog);
    fprintf(stderr, "Error in fragment shader #%s compilation!
", "v");
    fprintf(stderr, "Info log: %s
", infoLog);
    mySleep(10);
    exit(0);
  }
  glCompileShader(f);
  glGetShaderiv(f, GL_COMPILE_STATUS, &success);
  if (!success)
  {
    GLchar infoLog[MAX_INFO_LOG_SIZE];
    glGetShaderInfoLog(f, MAX_INFO_LOG_SIZE, NULL, infoLog);
    fprintf(stderr, "Error in fragment shader #%s compilation!
", "f");
    fprintf(stderr, "Info log: %s
", infoLog);
    mySleep(10);
    exit(0);
  }

  p = glCreateProgram();
  glAttachShader(p,v);
  glAttachShader(p,f);
  glLinkProgram(p);
  glUseProgram(p);

  time_id = glGetUniformLocation(p, "v_time");
}

int main(int argc, char **argv) {
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  glutInitWindowPosition(100,100);
  glutInitWindowSize(windowWidth,windowHeight);
  glutCreateWindow("GPGPU Tutorial");
  glutDisplayFunc(renderScene);
/*glutIdleFunc(renderScene);*/
  glutReshapeFunc(changeSize);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_LIGHTING);
  glEnable(GL_COLOR_MATERIAL);
  glEnable(GL_NORMALIZE);
  glEnable(GL_LIGHT0);
  glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularMaterial);
  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128.0f);

  glClearColor(1.0,1.0,1.0,1.0);
  glColor3f(0.0,0.0,1.0);
  glEnable(GL_CULL_FACE);
  glewInit();

  setShaders();

  glutMainLoop();

  return 0;
}

Now to your question, I think I see what you’re referring to. That being if you comment our your setShaders() call in main, you get a lit, colored screen full of objects (sphere, torus, cone, teapot, plane).

However, when you plug in a shader does basically nothing besides transform the positions properly, you of course won’t get such a pretty scene.

But the reason you see black rather than just something in unlit grayscale is you’re not passing your vertex attribute colors down from the vertex shader.

Try these shaders instead:

Vertex:


//passthrough.vert
varying vec4 color;
void main()
{
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  color       = gl_Color;
}

Fragment:


//uniform.frag
varying vec4 color;
void main()
{
  // float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
  // gl_FragColor = vec4(gray, gray, gray, 1.0);
  gl_FragColor = color;
};

Now you’ll see that you’re getting the vertex colors rendered and you can put your grayscale effect back in there.

I wrote it this way because this is more like what you’d write if you were coding shaders for a newer GLSL version (any >= 1.3) where the built-ins are no longer there.

However in the legacy GLSL versions (like you’re using here), there’s a reason why your shader compiled but didn’t work. In the vertex shader gl_Color was a vertex attribute. In the fragment shader, gl_Color was a varying input (i.e. an interpolator) which was populated by the vertex shader’s setting of gl_FrontColor or gl_BackColor (vertex shader varying outputs). You didn’t set gl_FrontColor in the vertex shader so gl_Color’s value in the frag shader was undefined.

Thanks a lot. But if i use ‘color’ in fragment shader , there won’t have Lighting effects. And when i just use only fragment shader , it works fine.
[ATTACH=CONFIG]222[/ATTACH]
So, what is the error?

There’s no error. In the fixed function pipeline, lighting happens in the vertex shader. If you plug in your own, you lose that built-in lighting and have to do it yourself if you want it. Its not hard. And lots of code for this on the net or in the orange book.

I got it and thanks for the help, i am now reading OpenGL 4.0 Shading Language Cookbook, do i need to read the orange book first?

Not necessarily, the Shading Language Cookbook is a good list of examples, if you already have a rough overview of how shaders work and are willing to look up some specifics and available commands in the specs, you don’t need the orange book.

The Cookbook gets to what you’re interested in pretty quickly (assuming you want to use GLSL 4.0+ and not GLSL 1.0-1.2). Use the Orange book for reference as the Cookbook focuses on the GLSL syntax, not the GL API calls needed to drive the shaders.