Categories
3d code graphics opengl programming Solutions

A GLSL shader showing the normal map [w/ code]


A very simple thing, although I couldn’t find on Google some place to copy-paste off, so here it is:

Vertex shader

varying vec3 normal;
void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    normal = gl_NormalMatrix * gl_Normal;
}

Fragment shader

varying vec3 normal;
void main()
{
    vec3 normal_normal = normalize(normal);
	gl_FragColor = vec4(normal_normal, 1.0);
}

A technique to load the shaders that will save you a lot of headaches

GLvoid* my_program;
//Error-checking function
void checkARBError(GLvoid* obj) {
	char infolog[1024] = {0}; int _written = 0;
	glGetInfoLogARB(obj, 1024, &_written, infolog);
	if(_written>0) {
		cerr << infolog << endl;
	}
}
bool notIsAscii(int i) { return !isascii(i); }
void init_shaders() {
	const GLubyte* lang_ver = glGetString(GL_SHADING_LANGUAGE_VERSION);
	cout <<"shading language version: "<<(uchar*)lang_ver<<endl;
	const char * my_fragment_shader_source;
	const char * my_vertex_shader_source;
        //Reading shaders from files
	ifstream ifs("vshader.txt");
	ostringstream ss; ss << ifs.rdbuf();
	ifstream ifs1("fshader.txt");
	ostringstream ss1; ss1 << ifs1.rdbuf();
	ifs.close(); ifs1.close();
        //Cleaning up the strings...
	string _vertex = ss.str(); _vertex.erase(remove_if(_vertex.begin(), _vertex.end(), notIsAscii), _vertex.end());
	string _frag = ss1.str(); _frag.erase(remove_if(_frag.begin(), _frag.end(), notIsAscii), _frag.end());
	// Get Vertex And Fragment Shader Sources
	my_fragment_shader_source = _frag.c_str();
	my_vertex_shader_source = _vertex.c_str();
        //DEBUG - can remove
	cout << "vertex shader:"<<endl<<my_vertex_shader_source<<endl;
	cout << "fragment shader:"<<endl<<my_fragment_shader_source<<endl;
	GLvoid* my_vertex_shader;
	GLvoid* my_fragment_shader;
	// Create Shader And Program Objects
	my_program = glCreateProgramObjectARB();
	my_vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
	my_fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
	// Load Shader Sources
	glShaderSourceARB(my_vertex_shader, 1, &my_vertex_shader_source, NULL);
	checkARBError(my_vertex_shader);
	glShaderSourceARB(my_fragment_shader, 1, &my_fragment_shader_source, NULL);
	checkARBError(my_fragment_shader);
	// Compile The Shaders
	glCompileShaderARB(my_vertex_shader);
	checkARBError(my_vertex_shader);
	glCompileShaderARB(my_fragment_shader);
	checkARBError(my_fragment_shader);
	// Attach The Shader Objects To The Program Object
	glAttachObjectARB(my_program, my_vertex_shader);
	glAttachObjectARB(my_program, my_fragment_shader);
	checkARBError(my_program);
	// Link The Program Object
	glLinkProgramARB(my_program);
	checkARBError(my_program);
}

I based it on this example from NeHe.
It does periodical error checking so you can see if something is wrong, plus it will make sure the vertex shader and fragmetn shader are stripped of all non-ASCII characters.
This way the compilation will not give you cryptic errors such as “ERROR: 0:1: ‘<' : syntax error syntax error"...

2 replies on “A GLSL shader showing the normal map [w/ code]”

So you’re using JNI to run the GL on the Samsung Galaxy S2? What version OS do you have – been having real problems with Gingerbread 2.3.3 – it just won’t do normal mapping. Do you have a pre-built APK I could test out at all and see if it causes the same problems?

Leave a Reply

Your email address will not be published. Required fields are marked *