Sign in to follow this  
adam17

GLSL shaders acting weird

Recommended Posts

adam17    227
ok ive been researching GLSL shaders for a few days now and have progressed pretty well. i used to do Cg but now im switching. anyway ive been running into some weird issues with the shaders. basically what my shaders are doing is blending between two textures based on a timer. my vertex shader transforms the position of the vertex and sets the 1st and 2nd texture units up for the fragment shader. the fragment shader then takes the two textures, grabs a fragment from each, and then does the follwing equation as the final fragment color: (alpha*tex2)+((1.0-alpha)*tex1). alpha is the uniform variable based on time; the issue i am having is i can get my first and second texture to add and/or multiply with the correct output. whenever i output only the second texture unit, or multiply it with alpha, i always get the first texture unit. the same happens when i run them through the equation last paragraph. here is my vertex shader code
void main()
{
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;	

	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_TexCoord[0] = gl_MultiTexCoord1;		
}
here is my fragment shader code
uniform sampler2D texture0, texture1;
uniform float alpha;
void main()
{
	vec4 tex1 = texture2D(texture0, gl_TexCoord[0].st);
	vec4 tex2 = texture2D(texture1, gl_TexCoord[0].st);
		
	gl_FragColor = (alpha*tex2)+((1.0-alpha)*tex1);
}
here is the code for setting the uniform variables and the shader
GLint tex0, tex1;
GLint alpha;
void SetTestShader()
{
	vert_shader.filename = "vp0.vert";
	vert_shader.type = GL_VERTEX_SHADER_ARB;

	frag_shader.filename = "fp0.frag";
	frag_shader.type = GL_FRAGMENT_SHADER_ARB;

	LoadGLSLShader(vert_shader);
	LoadGLSLShader(frag_shader);

	glUseProgramObjectARB(frag_shader.shader_handle);
	tex0 = glGetUniformLocationARB(frag_shader.shader_handle, "texture0");
	tex1 = glGetUniformLocationARB(frag_shader.shader_handle, "texture1");
	//alpha = glGetUniformLocationARB(frag_shader.shader_handle, "alpha");
}
btw when i uncomment alpha all i get is a VERY dark texture. lastly here is the code for drawing
	static float a = 0;
	if(a > 1.0)
		a = 0.0;
	else
		a += 0.01f;

	glUseProgramObjectARB(glslContext);  //this is globally defined. could this pose a future problem?
	glUniform1iARB(tex0, 0);
	glUniform1iARB(tex1, 1);
	glUniform1fARB(a, xrot);
	sphere.DrawObj();
	glUseProgramObjectARB(0);
thanks ahead of time!

Share this post


Link to post
Share on other sites
Sneftel    1788
Quote:
Original post by adam17
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[0] = gl_MultiTexCoord1;

Without having read through the rest of your code..... is that really what you meant?

Share this post


Link to post
Share on other sites
adam17    227
as far as i know thats how i access the first and second texture units. i thought gl_TexCoord[1] (or higher) was for using different sets of texture coordinates on the same object.

if i use gl_TexCoord[1] in both the vertex program and fragment program all i get is a black texture.

Share this post


Link to post
Share on other sites
rick_appleton    864
Quote:

glUniform1iARB(tex0, 0);
glUniform1iARB(tex1, 1);


Is that correct? I would assume you mean textureID's 1 and 2, not 0 and 1. Also, I assume it's safe to say that the two shaders are correctly linked into the single programobject glslContext?

Share this post


Link to post
Share on other sites
_the_phantom_    11250
The uniforms look right, as they dont indicate texture handles but texture units, which are numbered from zero.

Sneftel brings up a good point however, you are assigning the built in varying variable gl_TexCoord[0] first the value of gl_MultiTexCoord0, then the value of gl_MultiTexCoord1.
Now, this is ineffect just assigning it the value held in gl_MultiTexCoord1 (and the compiler should be smart enuff to spot this and remove the extra line), so what values do you pass to as the texture coordinates to texture unit 1?

Infact, post your rendering where you pass the vertex data down...

Share this post


Link to post
Share on other sites
mikeman    2942
Quote:

glUniform1iARB(tex0, 0);
glUniform1iARB(tex1, 1);
glUniform1fARB(a, xrot);


What's that last line supposed to do? The first parameter should be the handle to the uniform, and the second a float value. According to the rest of your program, shouldn't it be glUniform1fARB(alpha,a)?

Share this post


Link to post
Share on other sites
adam17    227
Quote:
Original post by mikeman
Quote:

glUniform1iARB(tex0, 0);
glUniform1iARB(tex1, 1);
glUniform1fARB(a, xrot);


What's that last line supposed to do? The first parameter should be the handle to the uniform, and the second a float value. According to the rest of your program, shouldn't it be glUniform1fARB(alpha,a)?


yeah my mistake. i made some changes to the variable names so that it would make more sense to anyone reading it. it should be

glUniform1fARB(alpha, a);


->_the_phantom_
i got the code for assigning gl_MultiTexCoord0 and 1 to gl_TexCoord[0] from Lighthouse3D. ive noticed ALOT of the stuff there is wrong, confusing, or doesnt match the source code they provide.
as for the rendering code i only render models i read in. essentially it only uses glTexCoord2f(...); and glVertex3f(...);. yeah im going to optimize that later.

Share this post


Link to post
Share on other sites
_the_phantom_    11250
ah, the joys of dodgy tutorials [rolleyes]

Anyways, as you are using the default opengl commands then your vertex shader will want to look like this;


void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
// infact, I'd write it like this
void main()
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}




As for your alpha problem, i'm not sure about that, as it looks sane, i'll take a closer look at it in a bit when i've a little more time (dinner and all that)

Share this post


Link to post
Share on other sites
Sneftel    1788
For my money, there is exactly ONE text on GLSL worth reading, and that is the Orange Book. It's a little pricey, so see if there's a library somewhere you can borrow it from, but it's worth every penny.

EDIT: Actually, you're GDNet+... look here to get it from Addison-Wesley at a discount.

Share this post


Link to post
Share on other sites
adam17    227
->_the_phantom_
i made the changes you mentioned like changing to ftransform and taking out the extra gl_TexCoord[0] assignment.

->Sneftel
i wish i could afford the Orange Book right now. ive seen it and it looks bada$$ and could help me out ALOT. in the mean time im looking around for some local libraries that would carry it.

Share this post


Link to post
Share on other sites
zedzeek    529
i think u understand it now but ill say it again (ive seen a few ppl trip up on it, including myself)

glUniform1iARB(textureunit_12, 12);

uniform sampler2D textureunit_12;
A/vec4 tex1 = texture2D( textureunit_12, gl_TexCoord[0].st);

activetexture( GL_TEXTURE12 )
glBindTexture( GL_TEXTURE_2D, clouds_texture ); <- the clouds texture will be accessed in line A/

------------
also another IMO clearer way instead of writing gl_TexCoord[0] = is
varying vec2 texcoord;
texcoord = gl_MultiTexCoord0;

btw drop all the ARB's its not become part of opengl2.0

Share this post


Link to post
Share on other sites
OrangyTang    1298
Quote:
Original post by Sneftel
For my money, there is exactly ONE text on GLSL worth reading, and that is the Orange Book. It's a little pricey, so see if there's a library somewhere you can borrow it from, but it's worth every penny.

EDIT: Actually, you're GDNet+... look here to get it from Addison-Wesley at a discount.

Seconded. Direct and to the point - one of the best API-focused books I've read.

Share this post


Link to post
Share on other sites
zedzeek    529
Quote:
i understand everything except for the part about why i wouldnt want to use gl_TexCoord[]

just for clarity reasons thats all, nothing major
also since most cards only allow 32 varying floats
going
gl_TexCoord[0] = gl_MultiTexCoord0
will use up 4 of the 32 since even thoiugh usually u only need the .st coords
u can pack texture coords (and other things) together in a single varying

vec4 texccords = vec4(gl_MultiTexCoord0.st, gl_MultiTexCoord1.st ) // dont now if thats correct syntax

btw drop all the ARB's its not become part of opengl2.0 (i meant noW become)

Share this post


Link to post
Share on other sites
adam17    227
that makes alot of sense. ill keep that in mind when i start doing bigger things like normal mapping and parallax mapping.

as for the ARB stuff i would drop them but everything in my library has ARB attached and that would be way too much work to change. ill just wait until someone changes up the library again.

Share this post


Link to post
Share on other sites
zedzeek    529
im in the process now of changing my shader stuff from arb_shader to opengl2.0 shader, the gl2.0 version is way better designed (no objects handles etc)
thats the benifits of the ARB implementing something as an extension first before adding it to the core, it gives the extension a trail period so the final version is better.
normally extensions dont change to much when they get promoted to the core, unfortunatly with shader_objects there are a lot of changes
eg
Old ARB extensions commands New OpenGL 2.0 commands
glAttachObjectARB glAttachShader
glCreateProgramObjectARB glCreateProgram
glCreateShaderObjectARB glCreateShader
glDeleteObjectARB glDeleteShader for shader objects,
glDeleteProgram for program objects
glDetachObjectARB glDetachShader
glGetAttachedObjectsARB glGetAttachedShaders
glGetHandleARB glGetIntegerv(GL_CURRENT_PROGRAM, &retval)
glGetInfoLogARB glGetShaderInfoLog for shader objects,
glGetProgramInfoLog for program objects
glGetObjectParameterfvARB No equivalent
glGetObjectParameterivARB glGetShaderiv for shader objects,
glGetProgramiv for program objects
No equivalent glIsProgram
No equivalent glIsShader
glUseProgramObjectARB glUseProgram

Share this post


Link to post
Share on other sites
adam17    227
thats not going to solve my problem by changing this stuff right?

heh im lazy so if it doesnt help, i wont change it right now

Share this post


Link to post
Share on other sites
adam17    227
ok i have scoured what seems like every source that would be of any help like the ogl 2.0 spec, and glsl specs to name a few. has anybody come up with an idea of what could be going wrong?

i found this link [link="http://www.shadertech.com/forums/viewtopic.php?t=2745"]click[/link] but i didnt make a whole lot of sense out of it. it seems like exactly what im doing.

on a side note, is there any reason why my shader should be crashing when i use glGetUniformLocationARB for my alpha variable? when i use it, the model is black. if i comment it, the alpha variable changes as it should.

[Edited by - adam17 on July 1, 2005 1:55:58 AM]

Share this post


Link to post
Share on other sites
zedzeek    529
sorry didnt realise youre still having problems
what exactlys going wrong?
can u do a simple shader eg try this

VS
void main(void)
{
gl_Position = ftransform();
}
FS
void main(void)
{
gl_FragColor = vec4( 1.0,0.0,0.0,1.0 );
}

that should draw everything red

once u get that working try this
---- VS ----------
void main(void)
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;

}

----- FS ----

uniform vec4 col;

void main(void)
{

gl_FragColor = vec4( texture2D( tex0, gl_TexCoord[0].xy ) );
}

Share this post


Link to post
Share on other sites
adam17    227
yeah both of those work no problem. whats really weird is i can assign 2 different textures to TU0 and TU1. in the frag shader the second texture unit is always showing TU0.

im doing:

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[2]);

and this:

glUniform1iARB(tex0, 0);
glUniform1iARB(tex1, 1);

the textures are different ive done it using the fixed pipeline. what is REALLY bizarre is if i leave the location for the uniform for TU1 commented out i cannot sample TU1 by itself. although i can multiply and add it with no problems. basically TU1 can only be sampled if multiplied or added with TU0

Share this post


Link to post
Share on other sites
zedzeek    529
btw u dont need to enable textures (thats only for the fixed pipeline)

so this is your fragment shader

uniform sampler2d tex0;
uniform sampler2d tex1;

void main(void)
{
gl_FragColor = vec4( texture2D( tex0, gl_TexCoord[0].xy ) );
}

this should draw texture0 now change the tex0 to tex1 and it should draw texture1 if it does both of those then it should work (youre setting them up correctly)
so u should be able to go
gl_FragColor = vec4( texture2D( tex0, gl_TexCoord[0].xy ) * texture2D( tex1, gl_TexCoord[0].xy ) );
if not then i dont know whats up, try shaderdesigner do the examples there work?

Share this post


Link to post
Share on other sites
adam17    227
ok here are my two shaders

vertex

uniform sampler2D texture0, texture1;

void main()
{
gl_Position = ftransform();

gl_TexCoord[0] = gl_MultiTexCoord0;
}




fragment

uniform sampler2D texture0, texture1;
uniform float alpha;
void main()
{
vec4 tex1 = texture2D(texture0, gl_TexCoord[0].st);
vec4 tex2 = texture2D(texture1, gl_TexCoord[0].st);

gl_FragColor = tex2;
}

setting gl_FragColor to either tex1 or tex2, i get the same exact output. now when i multiply or add the two textures, i get the correct output with the two different textures. i tried the shaders in shader designer and my program and the exact same thing happens

Share this post


Link to post
Share on other sites
zedzeek    529
so youre saying theres visually no difference between

uniform sampler2D texture0, texture1;
void main()
{
vec4 tex1 = texture2D(texture0, gl_TexCoord[0].st);
vec4 tex2 = texture2D(texture1, gl_TexCoord[0].st);

gl_FragColor = tex2;
}

and

uniform sampler2D texture0, texture1;
void main()
{
vec4 tex1 = texture2D(texture0, gl_TexCoord[0].st);
vec4 tex2 = texture2D(texture1, gl_TexCoord[0].st);

gl_FragColor = tex1;
}

if thats the case youre buggered (if u want send me a testapp + ill run it and see whats wrong, billybolluxbouncingballs (at) yahoo.co.uk

Share this post


Link to post
Share on other sites
adam17    227
i have discovered a big chunk of my problem. whenever i render my model there were a bunch of calls to opengl inside of the draw function. i was enabling GL_TEXTURE_2D, setting certain colors and a bunch of other "idiot proofing" i had set in place. apparently it only made me look like more of an idiot. my model was only setup for using a single texture unit and not multiple units.

Share this post


Link to post
Share on other sites
gulgi    315
For all OpenGL-related problems, first thing you should do is use GLIntercept.
You can get it to break on invalid arguments, you can see the textures actually bound when the stuff get's rendered etc etc. Really a great tool. :)
With that tool you should be able to find any other bugs you have...

Good luck!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this