Friday, March 25, 2011

Colors and Textures

Spent about 6-7 hours today trying to figure out why my glutWireSphere wouldn't draw in a color other than black. The ultimate goal behind changing the color of the sphere is to have the wire spheres (which represent the bounding spheres of the primitive objects inside them) be blue when they are moving around and not colliding, and turning green when they are colliding. In order to test the waters for how to change the color though, I first decided to manually set all of the spheres around cubes to be red. Initially, I expected it to be as simple as writing:


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


before calling glutWireSphere. However, when that didn't work, I began to try all sorts of things. I had started out by placing the sphere code in the cube's draw function, which is where I was first binding the vao of the cube model to the cube object. I moved these calls outside, into the form manager. This did not yield any progress. I then tried wrapping the calls in glPushMatrix() and glPopMatrix(), glBegin(GL_LINES) and glEnd(), and combinations of both.


At this point, I was quite frustrated and decided to see if it was a driver or machine problem that I was experiencing. I sent my project to my friend Jeff, and asked him to run it to see if he also saw black spheres. Surprisingly (because I didn't really expect to be right about this), he reported that the spheres were the same color (texture really) as the cubes that they encompassed. To test this theory further, he changed the call to glutWireSphere to be glutSolidSphere, and indeed, the screenshot he sent me displayed a swirly ball of sandy-stone color.


This was now doubly frustrating, because not only was the glColor* not having the desired effect, but I also couldn't test other ideas since I was still only seeing black. I have yet to figure out what about my machine makes it different, but I am very determined to do so.


I began to scour online forums, graphics sites, and all of my textbooks to see why my call to glColor* was being ignored. I even went so far as to change the glColor3f call to 4f, and then 3ub, thinking that maybe I was crazy and missing something very obvious. None of this helped. However, I did come across some interesting new information, which although it didn't solve my problem, taught me some useful facts.


First of all, it appears that when lighting is used, calls to glColor* will have no effect unless glEnable(GL_MATERIAL_COLOR) is called. Now, I am still unclear as to by lighting, they mean the specific call of glEnable(GL_LIGHTING) or just having lighting in general. I am still very new with lighting details, and never really learned about lighting beyond a very basic overview of types in a Graphics class, so forgive me if this is obvious. However, I checked my entire solution and did not find any calls to glEnable(GL_LIGHTING), so as a result, I still don't know if this applies in my case. Either way, I tried it to make sure, and, it did not help.


I then read that blending will happen if glColor* is called after a texture is bound. As one person explained it on a forum, OpenGL is a state machine of sorts, and once you put it in one state, it will not change until you tell it to do so. This is the case with all programming really. We programmers bitch all the time about the program not doing what we want, but we're the ones telling it to do the wrong thing, or not telling it to do the right thing. Any who, back on track. So, apparently, the blending is what was occurring as far as I could deduce from the screenshot that Jeff sent me. Calling glColor* would blend with the texture, or "tint" it to be the selected color in other words. In order to prevent this, I tried calling glDisable(GL_TEXTURE_2D) and glEnableTexture(GL_TEXTURE_2D, 0). The latter is being passed a null parameter for the texture id in order to clear the buffer, so to speak. Neither of these seemed to have any effect, not alone and not in combination.


At this point, I was once again at my wit's end-- a phrase I seem to be using commonly nowadays when I'm programming. I emailed Keenan and told him about my problem, and he suggested that it might be a shader issue-- something that I had not considered at all until then. For some reason, I had thought the shader and the  calls to the glColor* for glutWireSphere to be entirely separate from each other. After emailing Keenan though, he assured me that we would discuss the shader further next week to get it working, and that in the meantime, I could print to console when the objects were colliding. 


This brings me to another "discovery" that I made today, or rather, a realization. Looking at my sphereToSphere collision code, I realized that the velocity vectors v0 and v1 for each object that I was passing, were completely wrong. Rather than representing the object's actual velocities, I was passing in their translations. This is ridonkulous, and not what I had intended but after programming for a long time that night, I must have had a brain fart. I now know that I need to go back into my code and create actual velocity vectors for each object. Right now, the two objects that I have on screen do not even have any linear velocity, just rotational, because they are turning about their own axes. Overall, this means that even without colors and print statements, I already know that my sphereToSphere collision calculations are wrong because they are based on some ridiculousness that needs to be fixed to non-ridiculousness.


That is all that I have to update right. Hopefully, I will have some great progress to post about tomorrow!

No comments:

Post a Comment