You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: chapter19/chapter19.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -314,7 +314,7 @@ Then we need to calculate the vertices position based on the information contain
314
314
}
315
315
```
316
316
317
-
Let’s examine what we are doing here. We iterate over the vertices information and store the texture coordinates in a list, no need to apply any transformation here. The we get the starting and total number of weights to consider to calculate the vertex position.
317
+
Let’s examine what we are doing here. We iterate over the vertices information and store the texture coordinates in a list, no need to apply any transformation here. Then we get the starting and total number of weights to consider to calculate the vertex position.
318
318
319
319
The vertex position is calculated by using all the weights that is related to. Each weights has a position and a bias. The sum of all bias of the weights associated to each vertex must be equal to 1.0. Each weight also has a position which is defined in joint’s local space, so we need to transform it to model space coordinates using the joint’s orientation and position (like if it were a transformation matrix) to which it refers to.
Copy file name to clipboardExpand all lines: chapter2/chapter2.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -95,7 +95,7 @@ With that line we are specifying that we must wait, at least, one screen update
95
95
glfwSwapBuffers(windowHandle);
96
96
```
97
97
98
-
So, if we enable v-sync we achieve a constant frame rate without performing the micro-sleeps to check the available time. Besides that, , the frame rate will match the refresh rate of our graphics card, that is, if it’s set to 60Hz (60 times per second), we will have 60 Frames Per Second. We can scale down that rate by setting a number higher than one in the ```glfwSwapInterval``` method (if we set it to 2, we would get 30 FPS).
98
+
So, if we enable v-sync we achieve a constant frame rate without performing the micro-sleeps to check the available time. Besides that, the frame rate will match the refresh rate of our graphics card, that is, if it’s set to 60Hz (60 times per second), we will have 60 Frames Per Second. We can scale down that rate by setting a number higher than one in the ```glfwSwapInterval``` method (if we set it to 2, we would get 30 FPS).
99
99
100
100
Let’s get back to reorganize the source code. First of all we will encapsulate all the GLFW Window initialization code in a class named ```Window``` allowing some basic parameterization of its characteristics (such as title and size). That ```Window``` class will also provide a method to detect key presses which will be used in our game loop:
101
101
@@ -286,7 +286,7 @@ If you try to run the source code provided above in OSX you will get an error li
286
286
Exception in thread "GAME_LOOP_THREAD" java.lang.ExceptionInInitializerError
287
287
```
288
288
289
-
What does this mean? The answer is that some functions of the GLFW library cannot be called in a ```Thread``` which is not the main ```Thread```. We are doing the initializing stuff, including window creation in the ```init``` method if the ```GameEngine class```. That method gets called in the ```run``` method of the same class, which is invoked by a new ```Thread``` instead the one that's used to launch the program.
289
+
What does this mean? The answer is that some functions of the GLFW library cannot be called in a ```Thread``` which is not the main ```Thread```. We are doing the initializing stuff, including window creation in the ```init``` method of the ```GameEngine class```. That method gets called in the ```run``` method of the same class, which is invoked by a new ```Thread``` instead the one that's used to launch the program.
290
290
291
291
This is a constraint of the GLFW library and basically it implies that we should avoid the creation of new Threads for the game loop. We could try to create all the Windows related stuff in the main thread but we will not be able to render anything. The problem is that, OpenGL calls need to be performed in the same ```Thread``` that its context was created.
Copy file name to clipboardExpand all lines: chapter5/chapter5.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -167,7 +167,7 @@ memFree(indicesBuffer);
167
167
168
168
Since we are dealing with integers we need to create an `IntBuffer` instead of a `FloatBuffer`.
169
169
170
-
And that’s, the VAO will contain now two VBOs, one for positions and another one that will hold the indices and that will be used for rendering. Our cleanup method in our `Mesh` classmust take into consideration that there is another VBO to free.
170
+
And that’s it; the VAO will contain now two VBOs, one for positions and another one that will hold the indices and that will be used for rendering. Our cleanup method in our `Mesh` classmust take into consideration that there is another VBO to free.
Copy file name to clipboardExpand all lines: chapter6/chapter6.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ But, the problem is more serious than that. Modify the z cords of our quad from
16
16
17
17
But, wait. Should not be this handled by the z-coord? The answer is yes an no, The z coordinate tells OpenGL that an object is closer or far away, but OpenGL does not know nothing about the size of your object you could have two objects of different sizes, one closer and smaller and one bigger and further that could be projected, correctly into the screen with the same size \(those would have same x and y coordinates and different z\). OpenGL just uses the coordinates we are passing, so we must take care of this, we need to correctly project our coordinates.
18
18
19
-
Now that we have diagnosed the problem, how do we do this ? The answer is by using a projection matrix or frustrum. The projection matrix will take care of the aspect ratio \(the relation between size and height\) of our drawing area so objects won’t be distorted. It also will handle the distance so objects far away from us will be drawn smaller. The projection matrix will also consider our field of view and how far is the maximum distance that should be displayed.
19
+
Now that we have diagnosed the problem, how do we do this ? The answer is by using a projection matrix or frustum. The projection matrix will take care of the aspect ratio \(the relation between size and height\) of our drawing area so objects won’t be distorted. It also will handle the distance so objects far away from us will be drawn smaller. The projection matrix will also consider our field of view and how far is the maximum distance that should be displayed.
20
20
21
21
For those not familiar with matrices, a matrix is a bi-dimensional array of numbers arranged in columns and rows, each number inside a matrix is called an element. A matrix order is the number of rows and columns. For instance, here you can see a 2x2 matrix \(2 rows and 2 columns\).
22
22
@@ -194,7 +194,7 @@ If we continue pushing backwards the quad we will see it smaller. Notice also th
194
194
195
195
## Applying Transformations
196
196
197
-
Let’s recall what we’ve done so far. We have learned how to pass data in an efficient format to our graphic card. How to project that data and assign them colours using vertex and fragments shaders. Now we should start drawing more complex models in our 3D space. But in order to do that we must be able to load an arbitrary model an represent it in our 3D space in a specific position, with the appropriate size and the required rotation.
197
+
Let’s recall what we’ve done so far. We have learned how to pass data in an efficient format to our graphic card. How to project that data and assign them colours using vertex and fragments shaders. Now we should start drawing more complex models in our 3D space. But in order to do that we must be able to load an arbitrary model and represent it in our 3D space in a specific position, with the appropriate size and the required rotation.
198
198
199
199
So right now, in order to that representation we need to provide some basic operations to act upon any model:
200
200
@@ -462,7 +462,7 @@ As you can see the code is exactly the same, we are using the uniform to correct
462
462
463
463
Another important thing to think about is, why don’t we pass the translation, rotation and scale matrices instead of combining them into a world matrix ? The reason is that we should try to limit the matrices we use in our shaders. Also keep in mind that the matrix multiplication that we do in our shader is done once per each vertex. The projection matrix does not change between render calls and the world matrix does not change per `GameItem` instance. If we passed the translation, rotation and scale matrices independently we will be doing many more matrices multiplication. Think about a model with tons of vertices and that’s a lot of extra operations.
464
464
465
-
But you may now think, that if the world matrix does not change per `GameItem` instance, why we don’t do the matrix multiplication in our Java class. We would be by multiplying the projection matrix and the world matrix just once per GameItem and we would send it as single uniform. In this case we would be saving many more operations. The answer is that this a valid point right now but when we add more features to our game engine we will need to operate with world coordinates in the shaders so it’s better to handlen in and independet way those two matrices.
465
+
But you may now think, that if the world matrix does not change per `GameItem` instance, why we don’t do the matrix multiplication in our Java class. We would be by multiplying the projection matrix and the world matrix just once per GameItem and we would send it as single uniform. In this case we would be saving many more operations. The answer is that this is a valid point right now but when we add more features to our game engine we will need to operate with world coordinates in the shaders anyway, so it’s better to handlen in and independet way those two matrices.
466
466
467
467
Finally we only need to change the `DummyGame` class to create a instance of `GameItem` with its associated `Mesh` and add some logic to translate, rotate and scale our quad. Since it’s only a test example and does not add too much you can find it in the source code that accompanies this book.
Copy file name to clipboardExpand all lines: chapter8/chapter8.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -273,7 +273,7 @@ One important thing related to callbacks and GLFW is that we need to keep a refe
273
273
Exception in thread "GAME_LOOP_THREAD" org.lwjgl.system.libffi.ClosureError: Callback failed because the closure instance has been garbage collected
274
274
```
275
275
276
-
The ```MouseInput``` class provides an input method which should be when game input is processed. This method calculates the mouse displacement from the previous position and stores it into ```Vector2f``````displVec``` variable so it can be used by our game.
276
+
The ```MouseInput``` class provides an input method which should be called when game input is processed. This method calculates the mouse displacement from the previous position and stores it into ```Vector2f``````displVec``` variable so it can be used by our game.
277
277
278
278
The ```MouseInput``` class will be instantiated in our ```GameEngine``` class and will be passed as a parameter in the ```init``` and ```update``` methods of the game implementation (so we need to change the interface accordingly).
0 commit comments