using shader variables

Started by
6 comments, last by zacaj 12 years, 2 months ago
I want to apply a shader, just for learning purposes. But i'm not sure how to pass data from my code to my shader.

I have the following shader, used for spherical environment mapping:

Vertex_Shader

void main()
{
gl_Position = ftransform();

gl_TexCoord[0] = gl_MultiTexCoord0;

vec3 u = normalize( vec3(gl_ModelViewMatrix * gl_Vertex) );
vec3 n = normalize( gl_NormalMatrix * gl_Normal );
vec3 r = reflect( u, n );
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
gl_TexCoord[1].s = r.x/m + 0.5;
gl_TexCoord[1].t = r.y/m + 0.5;
}



Pixel_Shader

uniform sampler2D colorMap;
uniform sampler2D envMap;

void main (void)
{
vec4 color = texture2D( colorMap, gl_TexCoord[0].st);
vec4 env = texture2D( envMap, gl_TexCoord[1].st);

gl_FragColor = color + env*0.4;
}


How exactly do i pass a sampled2D variable to this shader..?? And i'm also not sure wether the Vertext Shader needs to receive data from my code aswell... Anyone willing to help me out on this one?
Advertisement
glUniform1i(uniformID,textureID);
uniform ID can be found by using glGetUniformLocation
textureID is number 0-MAX MULTITEXTURES (the same number you used with glActiveTexture when you bound the texture
Everything youre using in the vertex shader is just provided by opengl. As long as youre calling glVertexPointer etc correctly, the vertex shader looks fine. You might want to start with a fragment shader that just says gl_FragColor=vec4(1) first, so you can be sure its not a texturing problem (if youre having problems). Also, when you reply, please quote me so I get an email, or I may not respond for a while

glUniform1i(uniformID,textureID);
uniform ID can be found by using glGetUniformLocation
textureID is number 0-MAX MULTITEXTURES (the same number you used with glActiveTexture when you bound the texture


No, it is not the same number.
http://www.opengl.org/wiki/GLSL_Sampler#Binding_textures_to_samplers
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Sorry, that was a bit ambiguous. I meant that it was the number of the GL_TEXTURE#.

Everything youre using in the vertex shader is just provided by opengl. As long as youre calling glVertexPointer etc correctly, the vertex shader looks fine. You might want to start with a fragment shader that just says gl_FragColor=vec4(1) first, so you can be sure its not a texturing problem (if youre having problems). Also, when you reply, please quote me so I get an email, or I may not respond for a while


Thanks i've managed to get the shader i posted to work. But i made things a bit more difficult for me with an improved shader smile.png

I now need to pass a vec3 CameraPos and a mat4 ModelWorld4x4 to my shader. I think did the CameraPos part right, but i don't know how to obtain the ModelWorld part.

This is what i have so far:


GLuint front, back, campos, modelworld;

glGenTextures(1, &front);
glBindTexture(GL_TEXTURE_2D, front);
int success = glfwLoadTexture2D("C:\\models\\reflect1.tga", GLFW_BUILD_MIPMAPS_BIT);

glGenTextures(1, &back);
glBindTexture(GL_TEXTURE_2D, back);
success = glfwLoadTexture2D("C:\\models\\reflect2.tga", GLFW_BUILD_MIPMAPS_BIT);

campos = glGetUniformLocation(shader.id(), "CameraPos");
glUniform3fv(campos, 0.0f, 0.0f, 3.0f);


I got the campos variables from my gluLookAt method.

gluLookAt(0.0f, 0.0f, 3.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0f, 0.f);


Any idea on how to get the ModelWorld4x4?


For the record, this is the vertex shader:

uniform vec3 CameraPos;
uniform mat4 ModelWorld4x4;
varying vec3 R;
mat3 GetLinearPart( mat4 m )
{
mat3 result;

result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];

result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];

return result;
}

void main()
{
gl_Position = ftransform();

mat3 ModelWorld3x3 = GetLinearPart( ModelWorld4x4 );

// find world space position.
vec4 WorldPos = ModelWorld4x4 * gl_Vertex;

// find world space normal.
vec3 N = normalize( ModelWorld3x3 * gl_Normal );

// find world space eye vector.
vec3 E = normalize( WorldPos.xyz - CameraPos.xyz );

// calculate the reflection vector in world space.
R = reflect( E, N );
}

You calculate that yourself or use a math library like GLM or whatever
http://www.opengl.org/wiki/Related_toolkits_and_APIs#Math_Libraries
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Your worldmatrix is just the transform of whatever object youre rendering. Youll have to post your per-object code (if you have multiple objects) If you just draw one mesh at the origin, your worldmatrix is just the identity matrix(no translation or rotation is happening). Off the top of my head your cameraPos is correct I think. Also, I think you can replace your matrix3x3 function with a call to mat3(mat4x4)

This topic is closed to new replies.

Advertisement