How easy is it to transform the Openengine framework from OpenGL to DirectX?
It demands that all the OpenGL-specific pieces of code be replaced by the equivalent for DirectX, this means that all the variables starting with the GL_ prefix should be replaced. Also, the use of glsl-shaders would also not be possible when using DirectX, it should be replaced by cg or something.
Wednesday, September 26, 2007
Tuesday, September 25, 2007
Week 3 - Headheadaches
Things that gave headaches this week was Darcs and getting a computer that supported shaders.
We had 3 different Darcs repositories (one for every week), and we wanted to merge these repositories into one. Now this may sound easy, but it turned out to be really complicated since we had a lot of conflicts in our patches. We spent around 4 hours trying to get everything up and running. It was quite frustrating.
Our final solution was to take a clean openengine pull and manually copy in our code. This worked :) Darcs seems to be really bad at merging code together - it's almost lethal to edit in same files/functions.
We all use laptops for development and only one of the laptops has support for shaders. Stibitz was quite full of people, so we were forced to find some other Daimi computers that had support for shaders. At last we found them, but they were Windows machines... Getting OpenEngine up and running on Windows wasn't that smooth, we spent around 2 hours setting everything up.
Anyway, we have Darcs up and running and we have found some computers that are configured for game development... Now we can fully focus on game development :D
We had 3 different Darcs repositories (one for every week), and we wanted to merge these repositories into one. Now this may sound easy, but it turned out to be really complicated since we had a lot of conflicts in our patches. We spent around 4 hours trying to get everything up and running. It was quite frustrating.
Our final solution was to take a clean openengine pull and manually copy in our code. This worked :) Darcs seems to be really bad at merging code together - it's almost lethal to edit in same files/functions.
We all use laptops for development and only one of the laptops has support for shaders. Stibitz was quite full of people, so we were forced to find some other Daimi computers that had support for shaders. At last we found them, but they were Windows machines... Getting OpenEngine up and running on Windows wasn't that smooth, we spent around 2 hours setting everything up.
Anyway, we have Darcs up and running and we have found some computers that are configured for game development... Now we can fully focus on game development :D
Week 3 - oily shaders

We started looking at the oily shader, which we was to implement. The rough model without the shader, can be seen to the right.
It took some time to figure out, just how to do it, but eventually the implementation worked. The main idea behind it was, declare the colorRamp.tga as a texture in the glsl-file. From that on, it was possible to access it via a sampler2D in the frag-file. We first tried to use just a sampler1D, but for some reason it didn't work. Even though the f ile should just be a 1D picture(?). To get the right range of color we had a lookup variable, which was a vec2. It's y coordinate was set to 0.0 (again, doesn't this imply 1D?), and the x coordinate var derived from a constant, divided by the variable NdotL, which is the dot product between the normal and the normalized light direction.
The lookup was used in a texture2D, which was multiplied with the shininess of the material and the NdotHV raised to a power of 2.
This gave us this result:

There is a clear difference between the two, and there is no doubt, which one looks the best.
Week 3 Parallax
We had som troubles implementing the two shaders. Mainly because only one of our computers could use shaders and because the computers at daimi which did was taken most of the time, but also because we didn't have a guideline about the final result and about the shaders in general.
The parallax shaders was implemented with inspiration from the BumpMap shader and the information we got at the lecture.
The vert part of the parallax is almost identical with the one from BumpMap except we calculate a normal and sends it to the frag part.
In the frag, we used the height of the bumpmap, which is sent as a parameter in the alphachannel of the map, to shift the texture coordinates in the direction of the cam.
It works pretty much as the figure on the slides from the lecture. We multiply the height on the normalized eye vector and then use this as an indicator for the new coordinates along with an offset.
We used some time to tweak it so that we have a nice shader but we ended up with a result that looks pretty good (we think).
Week 3 - Transformations
The biggest problem we faced while implementing RenderingView::VisitTransformationNode was that we got a strange error which turned out to be nothing more a function that was standard in the OpenGL 2.0 was an extension in OpenGL 1.2 which we ran on the machine we worked on.
The code looks as follows:
The real trick was the magic ARB letters which is used to specify a function in the extension lib of OpenGL.
The code actually just fetches the transformation matrix from the scene graph structure and uses the boost .ToArray(*float) function to populate an array which in turn is given to the gl function. The gl function is the transposed version of the normal one as the boost matrix returned is in row major and OpenGL treats its pointer as a 4x4 column major matrix.
The code looks as follows:
void RenderingView::VisitTransformationNode(TransformationNode* node) {
Matrix<4,> transformationMatrix = node->GetTransformationMatrix();
float realTransformationMatrix[16];
transformationMatrix.ToArray(realTransformationMatrix);
glMultTransposeMatrixfARB(realTransformationMatrix);
node->VisitSubNodes(*this);
}
The real trick was the magic ARB letters which is used to specify a function in the extension lib of OpenGL.
The code actually just fetches the transformation matrix from the scene graph structure and uses the boost .ToArray(*float) function to populate an array which in turn is given to the gl function. The gl function is the transposed version of the normal one as the boost matrix returned is in row major and OpenGL treats its pointer as a 4x4 column major matrix.
Wednesday, September 19, 2007
Mouse add-on
We have added a bit to GameFactory.cpp so that it is now possible to rotate the camera around the object by using the movement of the mouse. The left mouse enables/disables the rotation-mode and j,k and l is used to select which axis to rotate around. To rotate the camera you simply have to move the mouse.
Parsing model data
This week we had to parse OBJ files (which is a geometry definition file). The main idea is to parse values from a text file and transfer them into OpenEngine's data structures.
We had to parse 5 kind of information:
vector<> > vertexes;
vector<> > normals;
vector<> > textures;
In a scripting language this would be rather trivial, but in C++ it's rather complex. For example, to split after " " you would do this in Python:
, so we had to make following hack:
Other than that we also had to dig a little into Open Engine, some of the things that we didn't understand at first was:
We had to parse 5 kind of information:
- vertex: e.g. v 15.424347 17.551886 -10.248134
- normals: e.g. vn -1.000000 0.000000 0.000000
- textures: e.g. vt 0.503197 0.007948
- faces: e.g. f 6/340/1 2/337/2 7/339/3
- f v/vt/vn v/vt/vn v/vt/vn
vector<> > vertexes;
vector<> > normals;
vector<> > textures;
In a scripting language this would be rather trivial, but in C++ it's rather complex. For example, to split after " " you would do this in Python:
- str.split(" ")
- vector<> split_vec;
split( split_vec, line, is_any_of(" ") );
- vector
OBJResource::parseLine(string line, int dims)
- parseLine("v 15.424347 17.551886 -10.248134", 3) -> [15.424347, 17.551886, -10.248134]
- vector
vec = parseLine(string(buf), 3);
vertexes.push_back( Vector<3,>( vec[0], vec[1], vec[2] ) );
- sscanf(split_inner[1].c_str(), "%d", &inner_in);
face->texc[i-1] = textures[inner_in-1];
- int a = Integer.parseInt("5");
Other than that we also had to dig a little into Open Engine, some of the things that we didn't understand at first was:
- Face class didn't have a "smart" constructor, so we had to modify public field variables directly
- We had to call face->CalcHardNorm() and face->CalcTangentSpace() explicitly
- We didn't really understand why FacePtr was smart, but that's probably because we don't have that much experience with C++ programming
Monday, September 17, 2007
Week 2
OBJ Resource loader
To get the materials extracted from the obj-file, we first ran through the obj-file to find if the keyword "mtllib" was included in the file. If so, the sscanf-method was used to extract the lib name, and this was saved to a variable. The name of the file was concatenated with the path from the obj-file to give the complete path of the mlt-file. This was necessary because the helper method "LoadMaterialFile", in contradiction to the comments, required the complete path of the material file. As this was done, the materials was saved in the Material map.
RenderingView
To render the GeometryNode's constructed from the OBJ file we simply call the correct OpenGL functions. A GeometryNode consists of 3 vertices which all have color and texture coordinates. We just run through these between glBegin(GL_TRIANGLES) and glEnd() calls, that is we choose to minimize the number of glBegin/glEnd to one per GeometryNode.
To get the materials extracted from the obj-file, we first ran through the obj-file to find if the keyword "mtllib" was included in the file. If so, the sscanf-method was used to extract the lib name, and this was saved to a variable. The name of the file was concatenated with the path from the obj-file to give the complete path of the mlt-file. This was necessary because the helper method "LoadMaterialFile", in contradiction to the comments, required the complete path of the material file. As this was done, the materials was saved in the Material map.
RenderingView
To render the GeometryNode's constructed from the OBJ file we simply call the correct OpenGL functions. A GeometryNode consists of 3 vertices which all have color and texture coordinates. We just run through these between glBegin(GL_TRIANGLES) and glEnd() calls, that is we choose to minimize the number of glBegin/glEnd to one per GeometryNode.
Friday, September 14, 2007
Introduction to computer graphics
Some of us have had Introduction to computer graphics. Our work in that course mostly involved implementing algorithms for physical movement and some gpu programming. It involved a tree, a flag, a lake and some rain and we will not repeat that in this course.
Wednesday, September 12, 2007
Week 1
What have we done in week 1
This week our primary goal was to setup development environment and to implement device input functionality for mouse and keyboard. We also made it possible to control the camera.
Setting up the development environment was easy, we mostly followed the guides on OE's website. There were a few issues with getting OE to work on Mac (mostly getting Darcs installed :))
We didn't really have any decisions to make since the code to implement was pretty straight forward. One problem we had was with GetState() implementation. A MouseState has buttons, and we didn't know how to indicate that multiple buttons were pressed (in the documentation it said we could or them together, we understood this, but didn't know how to translate this to C++ [so it actually could compile]).
We have also implemented a camera controller using our SDL implementation. This wasn't that complicated.
Our experience with OE
We had some trouble getting into the code since the documentation is rather lacking - there is a need for more example code :) So the way we have understood the framework was by inspecting the code and figuring out how it works. Our first impression is that the code is pretty clean and the design patterns are easy to understand (factory and observer this week).
For development we currently use Emacs or VIM. We are thinking of using Eclipse in the future.
OE's website is simple and nice, but the it lacks quite some documentation (this is also understandable since it's first time the course has run).
This week our primary goal was to setup development environment and to implement device input functionality for mouse and keyboard. We also made it possible to control the camera.
Setting up the development environment was easy, we mostly followed the guides on OE's website. There were a few issues with getting OE to work on Mac (mostly getting Darcs installed :))
We didn't really have any decisions to make since the code to implement was pretty straight forward. One problem we had was with GetState() implementation. A MouseState has buttons, and we didn't know how to indicate that multiple buttons were pressed (in the documentation it said we could or them together, we understood this, but didn't know how to translate this to C++ [so it actually could compile]).
We have also implemented a camera controller using our SDL implementation. This wasn't that complicated.
Our experience with OE
We had some trouble getting into the code since the documentation is rather lacking - there is a need for more example code :) So the way we have understood the framework was by inspecting the code and figuring out how it works. Our first impression is that the code is pretty clean and the design patterns are easy to understand (factory and observer this week).
For development we currently use Emacs or VIM. We are thinking of using Eclipse in the future.
OE's website is simple and nice, but the it lacks quite some documentation (this is also understandable since it's first time the course has run).
Subscribe to:
Posts (Atom)