4 Replies - 2975 Views - Last Post: 29 July 2009 - 02:20 PM Rate Topic: -----

#1 Telestia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 12-January 09

Normal mapping using shaders in Open GL

Post icon  Posted 27 July 2009 - 09:45 PM

Hey everyone, I'm having some problems with trying to figure out how to take an RGB texture and turn it into a normal vector using a shader program in Open GL and multi-texturing.

Here are my Vertex and Fragment programs. (Vertex first)

uniform float lightRadius;

varying vec3 lightDir;
varying vec3 viewDir;

void main()
{
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
	gl_TexCoord[0] = gl_MultiTexCoord0;
	
	gl_TexCoord[1] = gl_MultiTexCoord1;

	vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);
	
	vec3 n = normalize(gl_NormalMatrix * gl_Normal);
	vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
	vec3 b = cross(n, t) * gl_MultiTexCoord1.w;
	
	mat3 tbnMatrix = mat3(t.x, b.x, n.x,
						  t.y, b.y, n.y,
						  t.z, b.z, n.z);

	lightDir = (gl_LightSource[0].position.xyz - vertexPos) / lightRadius;
	lightDir = tbnMatrix * lightDir;

	viewDir = -vertexPos;
	viewDir = tbnMatrix * viewDir;
}



uniform sampler2D colorMap;
uniform sampler2D normalMap;

varying vec3 lightDir;
varying vec3 viewDir;

void main()
{
   vec3 l = lightDir;
	float atten = max(0.0, 1.0 - dot(l, l));
	
	l = normalize(l);
	
	vec3 n = normalize(texture2D(normalMap, gl_TexCoord[1].st).xyz * 2.0 - 1.0);
	vec3 v = normalize(viewDir);
	vec3 h = normalize(l + v);

	float nDotL = max(0.0, dot(n, l));
	float nDotH = max(0.0, dot(n, h));
	float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);
	
	vec4 ambient = gl_FrontLightProduct[0].ambient * atten;
	vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL * atten;
	vec4 specular = gl_FrontLightProduct[0].specular * power * atten;
	vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;
	
	gl_FragColor = color * texture2D(colorMap, gl_TexCoord[0].st);
}



Also, here is the code that I have for my rendering, init, and such.

#include "GLView.h"

////////////////////////////////////////////////////////////////////////////
// Do not put any OpenGL code here. General guidence on constructors in 
// general is to not put anything that can fail here either (opening files,
// allocating memory, etc.)
GLView::GLView(void) : _screenWidth(800), _screenHeight(600), _bFullScreen(false), _bAnimated(true)
{



}
void GLView::DrawFloor()
{
	GLfloat floorsize = 20.0f;
	GLfloat floorlevel = -0.4f;
	GLfloat gridsize = 0.5f;

	glBegin(GL_LINES);
	for (GLfloat i = -floorsize; i <= floorsize; i += gridsize)
	{
		glVertex3f(i, floorlevel, floorsize);
		glVertex3f(i, floorlevel, -floorsize);

		glVertex3f(floorsize, floorlevel, i);
		glVertex3f(-floorsize, floorlevel, i);
	}
	glEnd();

}
void GLView::PollKeyboard()
{
	static CStopWatch timer;
	float fTimePassed = timer.GetElapsedSeconds();
	timer.Reset();
	if (GetAsyncKeyState(VK_UP))
	{
		Camera.MoveForward(3.0f * fTimePassed);
	}
	if (GetAsyncKeyState(VK_DOWN))
	{
		Camera.MoveForward(-3.0f * fTimePassed);
	}
	if (GetAsyncKeyState(VK_LEFT))
	{
		Camera.RotateWorld( m3dDegToRad(60.0f) * fTimePassed, 0.0f, 1.0f, 0.0f);
	}
	if (GetAsyncKeyState(VK_RIGHT))
	{
		Camera.RotateWorld( m3dDegToRad(-60.0f) * fTimePassed, 0.0f, 1.0f, 0.0f);
	}

}

///////////////////////////////////////////////////////////////////////////////
// OpenGL related startup code is safe to put here. Load textures, etc.
void GLView::Initialize(void)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glEnable(GL_DEPTH_TEST);

	glEnable(GL_LIGHTING);

	GLfloat noLight[4] = {0.0f, 0.0f, 0.0f, 0.0f};

	GLfloat BrightLight[] = {1.0f, 1.0f, 1.0f, 1.0f};

	GLfloat dimLight[] = {0.2, 0.2f, 0.2f, 1.0f};

	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, dimLight);
	glLightfv(GL_LIGHT0, GL_AMBIENT, dimLight);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, BrightLight);
	glLightfv(GL_LIGHT0, GL_SPECULAR, BrightLight);
	glEnable(GL_LIGHT0);

	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glGenTextures(2, textures);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, textures[0]);
	LoadBMP("Wall Texture.bmp");
	
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, textures[1]);
	LoadBMP("Wall Something.bmp");



	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(GL_TEXTURE_2D);

	BoxList = glGenLists(1);

	glNewList(BoxList, GL_COMPILE);
	glBegin(GL_QUADS);

	//back
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-10.0f, -10.0f, -10.0f);
	glTexCoord2f(5.0f, 0.0f);
	glVertex3f(10.0f, -10.0f, -10.0f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(10.0f, 10.0f, -10.0f);
	glTexCoord2f(0.0f, 5.0f);
	glVertex3f(-10.0f, 10.0f, -10.0f);

	//right
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(10.0f, -10.0f, -10.0f);
	glTexCoord2f(5.0f, 0.0f);
	glVertex3f(10.0f, -10.0f, 10.0f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(10.0f, 10.0f, 10.0f);
	glTexCoord2f(0.0f, 5.0f);
	glVertex3f(10.0f, 10.0f, -10.0f);

	//front
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(10.0f, -10.0f, 10.0f);
	glTexCoord2f(5.0f, 0.0f);
	glVertex3f(-10.0f, -10.0f, 10.0f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(-10.0f, 10.0f, 10.0f);
	glTexCoord2f(0.0f, 5.0f);
	glVertex3f(10.0f, 10.0f, 10.0f);

	//left
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-10.0f, -10.0f, 10.0f);
	glTexCoord2f(5.0f, 0.0f);
	glVertex3f(-10.0f, -10.0f, -10.0f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(-10.0f, 10.0f, -10.0f);
	glTexCoord2f(0.0f, 5.0f);
	glVertex3f(-10.0f, 10.0f, 10.0f);

	//top
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-10.0f, 10.0f, -10.0f);
	glTexCoord2f(5.0f, 0.0f);
	glVertex3f(10.0f, 10.0f, -10.0f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(10.0f, 10.0f, 10.0f);
	glTexCoord2f(0.0f, 5.0f);
	glVertex3f(-10.0f, 10.0f, 10.0f);

	//bottom
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-10.0f, -10.0f, 10.0f);
	glTexCoord2f(5.0f, 0.0f);
	glVertex3f(10.0f, -10.0f, 10.0f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(10.0f, -10.0f, -10.0f);
	glTexCoord2f(0.0f, 5.0f);
	glVertex3f(-10.0f, -10.0f, -10.0f);


	glEnd();

	glEndList();
	glEnable(GL_TEXTURE_2D);


	NormalShader = gltLoadShaderPair("Normalmapper.vp", "Normalmapper.fp");

	iIndex = glGetUniformLocation(NormalShader, "lightRadius");


	glActiveTexture(GL_TEXTURE0);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(GL_TEXTURE_2D);
	glActiveTexture(GL_TEXTURE1);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(GL_TEXTURE_2D);

}
void GLView::LoadBMP(const char* szFileName)
{

	BYTE* pBits;
	int nWidth, nHeight;
	pBits = gltReadBMPBits(szFileName, &nWidth, &nHeight);
	if (pBits == NULL)
	{
		MessageBox(NULL, "Can't find texture file", szFileName, MB_OK);
	}

	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nWidth, nHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, pBits);
	free (pBits);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
void GLView::LoadTGA(const char* szFileName)
{

	GLbyte* pBits;
	int nWidth, nHeight;
	GLint component;
	GLenum enumm;
	pBits = gltLoadTGA(szFileName, &nWidth, &nHeight, &component, &enumm);
	if (pBits == NULL)
	{
		MessageBox(NULL, "Can't find texture file", szFileName, MB_OK);
	}

	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
	glTexImage2D(GL_TEXTURE_2D, 0, component, nWidth, nHeight, 0, enumm, GL_UNSIGNED_BYTE, pBits);
	free (pBits);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}


///////////////////////////////////////////////////////////////////////////////
// Do your cleanup here. Free textures, display lists, buffer objects, etc.
void GLView::Shutdown(void)
{


}


///////////////////////////////////////////////////////////////////////////////
// This is called at least once and before any rendering occurs. If the screen
// is a resizeable window, then this will also get called whenever the window
// is resized.
void GLView::Resize(GLsizei nWidth, GLsizei nHeight)
{
	glViewport(0, 0, nWidth, nHeight);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(35.0f, float(nWidth)/ float(nHeight), 1.0f, 1000.0f);

	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();

}


///////////////////////////////////////////////////////////////////////////////
// Render a frame. The owning framework is responsible for buffer swaps,
// flushes, etc.
void GLView::Render(void)
{
	static CStopWatch Timer;
	float yrot = Timer.GetElapsedSeconds() * 60;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	PollKeyboard();

	glPushMatrix();
	Camera.ApplyCameraTransform();

	GLfloat whereLight[] = {0.0f, 1.0f, 0.0f, 1.0f};
	glLightfv(GL_LIGHT0, GL_POSITION, whereLight);


	glDisable(GL_LIGHTING);


	glPushMatrix();
	glTranslatef(whereLight[0], whereLight[1], whereLight[2]);
	glColor3f(1.0f, 1.0f, 1.0f);
	gltDrawSphere(0.1f, 26, 13);
	glPopMatrix();

	glColor3f(0.0f, 1.0f, 0.0f);
	DrawFloor();

	glTranslatef(0.0f, 1.5f, 0.0f);
	glScalef(0.2f, 0.2f, 0.2f);
	glColor3f(1.0f, 1.0f, 1.0f);
	glActiveTexture(GL_TEXTURE0);
	glActiveTexture(GL_TEXTURE1);
	glUseProgramObjectARB(NormalShader);
	glUniform1f(iIndex, 10.0f);
	glCallList(BoxList);
	glUseProgramObjectARB(NULL);

	glPopMatrix();

}



I have my color map on texture 0 and my normal map on texture 1. When I run the programs the texture just get really dark and I can't figure out what might be wrong with it. Any help would be much appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Normal mapping using shaders in Open GL

#2 wildgoose  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 67
  • View blog
  • Posts: 468
  • Joined: 29-June 09

Re: Normal mapping using shaders in Open GL

Posted 29 July 2009 - 11:06 AM

You're building floor and walls! Don't need to calculate your normal to the face. You can hard code it. The normal is perpendicular to the face!

You're using OpenGL so -Z is into scene! X is left, and assumiing Y is up!
Floor {0,1,0} Y is up!
Back wall { 0, 0, 1 }
Right wall { -1, 0, 0 }
Left wall {1, 0, 0 }

By the way. Textures don't turn into normals. The vertex mesh does! However the normal is used in conjunction with a light source and the pixel color to illuminate those pixels! But that's typically done in a shader.

This post has been edited by wildgoose: 29 July 2009 - 11:10 AM

Was This Post Helpful? 0
  • +
  • -

#3 Tom9729  Icon User is offline

  • Segmentation fault
  • member icon

Reputation: 180
  • View blog
  • Posts: 2,641
  • Joined: 30-December 07

Re: Normal mapping using shaders in Open GL

Posted 29 July 2009 - 12:59 PM

GLSL example here...
http://codesampler.c...ng_bump_mapping
Was This Post Helpful? 1
  • +
  • -

#4 Telestia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 12-January 09

Re: Normal mapping using shaders in Open GL

Posted 29 July 2009 - 02:17 PM

View Postwildgoose, on 29 Jul, 2009 - 10:06 AM, said:

You're building floor and walls! Don't need to calculate your normal to the face. You can hard code it. The normal is perpendicular to the face!


I'm sorry, I don't think I explained what I'm doing well enough. I have 2 textures, one for the color map, and the other is the normal map. The second one is the same as the first only all the colors are either red, green, or blue. I'm trying to use a color lookup on the second texture, or texture unit one, and make that color into the normal for that particular vertex.

I'll have to take a look at the code Tom9792, I think that pretty much what I'm looking for.
Was This Post Helpful? 0
  • +
  • -

#5 wildgoose  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 67
  • View blog
  • Posts: 468
  • Joined: 29-June 09

Re: Normal mapping using shaders in Open GL

Posted 29 July 2009 - 02:20 PM

Ah, you're texture bump mapping!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1