Well its been a few weeks but I can proudly say I've gotten a whole bunch of shaders done lately. With that said, I'm much more confident texturing with shaders now, so I'm going to give a simple tutorial on how to slap on some textures for your models.
Lets start with the basics, you're going to need a variable to hold the texture itself. (Make sure the texture is in your project file!) Preferably this variable should be off in your global header somewhere to keep your main from getting cluttered.
static GLuint textureName;
This variable holds the information for whichever texture you choose. Loading the texture is just as simple. **Make sure you have all your DevIL libs included, and initialized** DevIL pretty much takes care of this step for you with:
textureName = ilutGLLoadImage("nameOfTextureFile.extension");
You can throw this function in main or maybe somewhere in your code where it can be dynamically changed on the fly. Its up to you, but for this tutorial the texture is loaded in main as that is all which is necessary.
Next you'll want to make sure all your CG stuff is initialized properly. I'll assume you know the basics of setting up a context/program/profile etc so I'll just show you how to get the parameter. Note that it can be a vertex or fragment parameter, it doesn't make a big difference for a simple program like this.
cgVertexParam_textureMap = cgGetNamedParameter(vertexProgram, "textureMap");
Now that you have the texture initialized, your shader will need to know where to get the texture coordinates. These come from the actual drawing of your shape/obj. Somewhere in your code you must have
glTexCoord2f(0.0,0.0);
for each texture coordinate your shape/obj has. This is crucial because your shader program will use these valuables when it has the correct semantic.
There's one more important thing to add in your main code, but I'm going to jump ahead to the shader itself for now. In the vertex or fragment shader, you will need a variable called
float2 texCoord : TEXCOORD0
This variable is varying, so it will automatically take in the values you specified with glTexCoord2f().
If you put this variable in your vertex shader, you should just pass it along to the fragment shader by specifying an out variable like so
out float2 oTexCoord : TEXCOORD0
Now in your fragment shader, you will need both the texCoord variable and a new one to specify the textureMap which the shader will use. Remember that textureMap parameter we set? Now it finally gets to be part of the action. The variable goes as such:
uniform sampler2D textureMap : TEXUNIT0
The uniform states it is a constant variable set by the program, the sampler2D is what grabs the actual texture, and TEXUNIT0 tell the shader which texture is going to be applied.
Lets go back to the program itself for a moment, and set the texture that will be applied in the shader. This code should be in the display function after you bind your programs and enable the shader profiles.
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,textureMap);
These two lines of code tell the shader which texture is being used, and then binds it to the textureMap variable. Note the TEXTURE0 will match up with TEXUNIT0 in your fragment shader. **I do not think glEnable(TEXTURE_2D) is necessary because the shader itself handles all the texturing instead of OpenGL**
Now back to the fragment shader to put it all together. As long as there is some form of lighting in your program (ambient is fine) then the following code should make your shape/obj nice and pretty:
float3 mappedObj = tex2D(textureMap, texCoord);
This applies the texture you loaded and matches it up with the texture coordinates you have specified. Now you can multiply this with your ambient colour (make sure its white) and output your final colour. Voila, you have a beautifully textured object; not that difficult eh?
**As a side note, if you want to blend multiple textures its as easy as setting more texture parameters, then lerping them in the fragment shader.**
:D
Continuing in the Game Dev course at UOIT, this year's blog will feature tidbits of Game Engine wisdom and AI techniques.
Monday, March 26
Sunday, March 25
Fun Fun for Everyone
This week I'm going to take a look at two very different games that I consider a lot of fun, and see if I can match them to some of the fun categories from the lecture. I really liked the BrainHex model because of how it relates to the parts of the brain used for different feelings. I will use that model and see how these games fit in.
The BrainHex model takes into account how different parts of the brain control different states of mind which video games can create in a player. The seven states listed below are not mutually exclusive, as often a player can be of multiple types. There are also several exceptions which take into account things a player really dislikes in a game.
A visual representation of the 7-pointed BrainHex model. |
My scores were:
Conqueror: 19
Daredevil: 16
Achiever: 14
Mastermind: 8
Socialiser: 7
Seeker: 6
Survivor: -6
Now for the games; first up is Diablo 2. This RPG features fast-paced dungeon crawling action, pitting your character up against the minions of hell. You begin by choosing one of 5 unique classes and then progress through the game's five-act storyline.
While the basic enemies in the game can be mowed down in waves, taking down a boss is extremely different. They have up to 1000x more health than a regular enemy and some of them can kill you in 1-shot at higher difficulty levels. Leading up to each boss is usually a multi-level dungeon which must be traversed. It contains hordes of regular enemies which you must carve a swath through to reach the end boss.
In order to facilitate the defeat of these powerful demons, your character gains experience and levels up by defeating enemies. This gives you stronger spells and abilities. Combine that with the thousands of different items enemies can drop, and it becomes all about getting the best loot. With the right equipment and spells, any previously impossible boss can be taken down with some effort.
The two core elements found in Diablo 2 match up with my main BrainHex types. Conquerer is found in Diablo 2 with the arduous boss fights; I died many times to Duriel and Diablo in particular. The feeling of fiero when finally defeating one of these challenging bosses is a thrill and really made the game fun for me. It also encourages players to go back to previous bosses, enhancing its replay value for the fun-inducing boss fights.
Taking into account my Daredevil type, smashing through a dungeon at high speeds is quite the thrill in Diablo 2. With the proper spells you can take out a dozen+ enemies at once and just keep on moving. Blizzard designed the dungeons to have low-downtime to keep the epinephrine pumping and keep the player engrossed in the game world. Its a lot of fun to go through dungeons at high speeds and obliterate everything in your path.
In contrast, Super Smash Bros. Melee has a whole different set of game mechanics. There is no levelling up, no stats, no equipment sets, no real bosses, and no largely different levels. The game play is comprised of picking a character and using combinations of controls to perform various attacks. Every character has unique attacks and properties (ie., agility and power) which affect how they are played. A skilled player can use these properties to their advantage and defeat their enemies.
SSBM focuses on the multi-player aspect because at its core it is a fighting game. When playing against my friends I noticed I enjoy the game most when I am fighting others that are also skilled and prove to be a challenge to defeat (this also ties to the flow theory!). My Conquerer type comes out when I am fighting a skilled opponent, as I enjoy the level of difficulty and it feels great to defeat them when I am trying my hardest.
You'll note I also had 7 points in the Socialiser type, showing that most people are a mix of 6 or 7 of all the personalities. This is prominent in a multi-player situation where you are physically with all the other players. Fighting against NPC's in Smash Bros is boring because they are both too easy, and not as interesting as fighting real people where social dynamics can come into play.
The fact that tournaments are still held for SSBM 11 years later shows that the developers really hit the mark for creating a fighting game which keeps players interested. The video shown is in real time, and as you can see both players are moving with extreme speed and precise control. The Daredevil personality in me really enjoys the fast paced nature of Melee and the role skill plays into being good at the it.
Being able to concisely control your characters movements is absolutely crucial to winning in Melee, and that embodies the personality of a Daredevil. To prove my point, just look at the differences between Melee and Brawl. My friends and I have boycotted Brawl because its just too sluggish in comparison, and the matches seem much slower. Even the gravity is reduced and overall its not nearly as fun. Maybe I'm saying this from a more experienced perspective, but the below video is so much less interesting than the previous one.
To summarize, the BrainHex model is based on 7 different gamer (not necessarily) personalities which tie into various types of games. Different genres of games can be fun for the same types of personalities despite much different game play mechanics. My type was Conquerer-Daredevil and the two games I presented prominently displayed these personalities. Despite them totally different genres, they are both very fun to me because they suit me in a way that satisfies my psychological needs as a gamer.
Subscribe to:
Posts (Atom)