PDA

View Full Version : Why aren't there GLSL tuts with full source code?



Bluebomber357
05-15-2009, 12:40 PM
I have been messing around with GLSL and while it has been a struggle (and still is) to work with textures, I have managed to get single-texturing, per-pixel fog, specular lighting, procedural brick texturing, and recently, spherical environment mapping to work via GLSL.

There are many other effects I want to get running, like multi-texturing, bump-maping, and cube environment mapping for starters. I see a lot of GLSL tutorials on google, but so many of them just talk about theory, provide the .vert and .frag code, and then leave me dangling. I recently spent a couple hour trying to get multi-texturing to work... I am probably just messing up some trivial openGL, it would be so much easier if someone posted full source code :(

Anyways, if anybody knows of GLSL tutorials with full source (particularly if they are with GLUT or freeGlut, and Visual Studio), please let me know. Otherwise, is it frowned upon if I link my project and ask for specific help in the future? What about asking for examples from the board members?

ZbuffeR
05-15-2009, 02:23 PM
Each sample here has documentation + full source code + exe + data :
http://developer.download.nvidia.com/SDK/10/opengl/samples.html

GLSL multitexture is in fact very easy :
http://www.opengl.org/wiki/Multitexture_with_GLSL

The code examples from the Orange Book, it is a great read by the way, try to get or borrow it :
http://3dshaders.com/home/index.php?option=com_weblinks&catid=14&Itemid=34

Once you have a working glsl example, it is easy to add effects, just provide more textures and data to your vert and frag shaders.


many of them just talk about theory, provide the .vert and .frag code, and then leave me dangling
Please define "dandling" ? What is your cause of pain ?

Bluebomber357
05-15-2009, 02:31 PM
I have the orange book, it is awesome, and does talk about "application setup" which is nice. The ogl2brick example is fantastic for figuring out how to get a shader applied to something :)

I agree that GLSL multitexture is very easy, but I cannot figure out what in my application is wrong. It is just one of those things that seems impossible to me to figure out, and then sometime soon I hope, I'll figure it out and it'll be trivial for the rest of my life :)

Aren't the openGL SDK examples all advanced? I am sure they'll come in handy down the road for me, but should I try to use them even as a beginner?

By "dangling", I mean that I'll have a project all setup, and then for example, the multi-texture examples. The frag and vertex shader code is easy, but I am new to openGL, so I am making some minuscule error with my application code. If I had full source for one of these things I would be set.

ZbuffeR
05-15-2009, 03:07 PM
1) check glGetError() after each gl command. In fact I use this very hand printOpenGLError() below, not sure where this snippet comes from, maybe orange book, or 3dlabs ?



#define printOpenGLError() printOglError(__FILE__, __LINE__)

int printOglError(char *file, int line)
{
//
// Returns 1 if an OpenGL error occurred, 0 otherwise.
//
GLenum glErr;
int retCode = 0;

glErr = glGetError();
while (glErr != GL_NO_ERROR)
{
printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
retCode = 1;
glErr = glGetError();
}
return retCode;
}


2) check each texture is complete (mipmaps ok ? otherwise use GL_LINEAR min filter)

3) simple multitexture stuff, for a frag shader with 3 textures :


// frag shader
uniform sampler2D EarthDay;
uniform sampler2D EarthNight;
uniform sampler2D EarthCloudGloss;
// ... //
vec2 clouds = texture2D(EarthCloudGloss, TexCoord).rg;


app setup code (uses getUniLoc() from Orange Book) :


glUniform1i(getUniLoc(earthProg, "EarthDay"), 0);
glUniform1i(getUniLoc(earthProg, "EarthNight"),1);
glUniform1i(getUniLoc(earthProg, "EarthCloudGloss"),2);

for (i = 0 i<3i++) {
// using multitexture
glActiveTexture(i);
glBindTexture(GL_TEXTURE_2D,name[i]);

// here load texture, linear filtering, etc
}


By the way you still did not say what is wrong ? Screen is white ? Texture 1 works but not texture 2 ? Something else ?

Bluebomber357
05-15-2009, 03:27 PM
It only shows my first texture, layered twice. I cannot get a second texture to appear.

ZbuffeR
05-15-2009, 03:39 PM
And you did glActiveTexture(i) before binding each texture ?
Can you show your texture-related GL code ?

Bluebomber357
05-15-2009, 04:44 PM
I believe this is all my application texture code, let me know if it all looks okay.

//Loads a texture into memory from disk, assigns it to an index, and creates mipmaps (which we'll cover later in class.)
void LoadTexture(char *filename, int num) {

"I deleted a bunch of texture loading code here"

glGenTextures(1, &texture[num]); //generates unique texture names
if (num == 0)
glActiveTexture(GL_TEXTURE0);
else
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture[num]); //assigns the texture name to a 2D texture (1D and 3D textures are also possible.)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR); //use linear interpolation between texture values for when you get too close
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR); //use linear averaging for when you are far away
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //define parameters of the 2D texture
}


//initializes the OpenGL scene. These things have to happen once, before the scene is drawn.
void init()
{
LoadTexture("quilt2.bmp", 0); //calls the above function.
LoadTexture("parrots.bmp", 1); //calls the above function.
glEnable(GL_TEXTURE_2D); //we will be using 2D textures

texLoc = getUniLoc2(getProgObj(), "colorMap"); //glGetUniformLocation(ProgramObject, "color_map");
glUniform1i(texLoc, 0);

texLoc = getUniLoc2(getProgObj(), "colorMap2");//glGetUniformLocation(ProgramObject, "color_map2");
glUniform1i(texLoc, 1);
}

Bluebomber357
05-15-2009, 08:16 PM
UPDATE, I still cannot get it to work, but I discovered some error output in a window when I run the program. I get a: No such uniform named "colorMap" error> Here is my shader code, sorry about how long it is. I got some lighting and procedural brick texturing in there too. BTW, I will be out of town for the weekend, so I won't be able to respond till Sunday night, please help anyways :D

Also, my whole project is available here: http://www.mediafire.com/file/zzde2myezzy/myShaders.zip, in the brick3_multiTex folder, just in case someone has some free time :) Ah man I can't wait to snuff out this problem.

VERT:

uniform vec3 LightPosition;

const float SpecularContribution = 0.3;
const float DiffuseContribution = 1.0 - SpecularContribution;

varying float LightIntensity;
varying vec2 MCposition;

void main(void)
{
vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVec = normalize(LightPosition - ecPosition);
vec3 reflectVec = reflect(-lightVec, tnorm);
vec3 viewVec = normalize(-ecPosition);
float diffuse = max(dot(lightVec, tnorm), 0.0);
float spec = 0.0;

if (diffuse > 0.0)
{
spec = max(dot(reflectVec, viewVec), 0.0);
spec = pow(spec, 16.0);
}

LightIntensity = DiffuseContribution * diffuse +
SpecularContribution * spec;

MCposition = gl_Vertex.xy;

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}



FRAG code:

uniform vec3 BrickColor, MortarColor;
uniform vec2 BrickSize;
uniform vec2 BrickPct;
uniform sampler2D colorMap;
uniform sampler2D colorMap2;


varying vec2 MCposition;
varying float LightIntensity;

void main(void)
{
vec3 color;
vec2 position, useBrick;

position = MCposition / BrickSize;

if (fract(position.y * 0.5) > 0.5)
position.x += 0.5;

position = fract(position);

useBrick = step(position, BrickPct);

vec4 color_map = texture2D( colorMap, gl_TexCoord[0].st);
vec4 color_map2 = texture2D( colorMap2, gl_TexCoord[0].st);


color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);
color *= LightIntensity;
gl_FragColor = vec4(color, 0.5) + color_map2;
//gl_FragColor = texture2D( colorMap, gl_TexCoord[0].st);
//vec4 (color, 1.0);
}

Bluebomber357
05-17-2009, 06:42 PM
bump

Xmas
05-18-2009, 05:19 AM
The GLSL compiler will remove uniforms that aren't actually used in the shader. Your shader doesn't use the color sampled from colorMap, so colorMap gets removed from the list of active uniforms.

glEnable(GL_TEXTURE_2D) is texture stage state, i.e. it needs to be enabled for each texture stage you're using.

dletozeun
05-18-2009, 07:20 AM
If I followed correctly this thread, Bluebomber357 is using glsl for texture mapping. So glEnable(GL_TEXTURE_2D) calls are useless.

Bluebomber357
05-18-2009, 07:54 AM
yeah, I am using glsl for texture mapping. My problems appears to be that I am not setting up my two uniform variables correctly in the application code, so the frag shader doesn't use them for the two textures. Does anyone know why? I linked my project earlier. Even better would be some code showing the whole process of GLSL texturing. I haven't been able to find any that shows off the app code, only the frag and vert shaders...

dletozeun
05-18-2009, 08:08 AM
Your code is a bit messy, try to simplify it and write a very simple fragment shader that blend two textures for instance.

To get samplers location, your program have to be compiled and linked successfully. On some hardwares like ATI ones with some driver versions, it could happen that you need to put the program in use to set uniforms values which is IIRC not required in the spec.

Bluebomber357
05-18-2009, 08:14 AM
My program is messy, but the application code is very short. I am pretty sure my frag and vert code is not the problem.

Are you saying that I need to get my sampler location after I install the shader?

dletozeun
05-18-2009, 02:32 PM
You can get a uniform variable location only if the program has been successfully compiled and linked. It does not have to be in use necessarily if it is what you mean by "install the shader".

Xmas
05-19-2009, 02:36 AM
My problems appears to be that I am not setting up my two uniform variables correctly in the application code, so the frag shader doesn't use them for the two textures. Does anyone know why?
No, your problem (at least if you're using the fragment shader posted) is that the fragment shader never actually uses the first texture.

Bluebomber357
05-20-2009, 08:37 PM
That is true, if I enter in either one, or both, it just uses the same texture though... :(

jmsmistral
08-28-2010, 05:25 PM
Hi all,

I am having exactly the same problem described. And like Bluebomber375 am unable to find places where both shader and app code are offered.

The problem is as follows: I want to load 3 textures, a depth map, color texture and a normal map. So fine, I load them as follows...

/* setup textures */
glGenTextures(1, &amp;depthmap);
glBindTexture(GL_TEXTURE_2D, depthmap);
<loading of depth texture - done correctly as I can see it>

/* load snow textures */
Image* image;
image = loadBMP("./textures/snowtexcolor.bmp");

glGenTextures(1, &amp;colormap);
glBindTexture(GL_TEXTURE_2D, colormap);

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

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height, 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);


Then I render as follows:

glUseProgram(progobj[0]);

// bind the textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthmap);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, bumpmap);

uniformLoc = glGetUniformLocation(progobj[0], "depthMap");
if(uniformLoc != -1)
{
glUniform1i(uniformLoc, 0);
}

uniformLoc = glGetUniformLocation(progobj[0], "bumpMap");
if(uniformLoc != -1)
{
glUniform1i(uniformLoc, 1);
}

drawmodels();


I still can only refer to the texture in GL_TEXTURE0.

How was this resolved?

Many thanks in advance,
Jonathan

jmsmistral
08-28-2010, 05:29 PM
In the example code I've just put the color texture and not the normal map.

Also... there was a little mistake: instead of

glBindTexture(GL_TEXTURE_2D, bumpmap);

and

uniformLoc = glGetUniformLocation(progobj[0], "bumpMap");

read "colormap"