This content originally appeared on DEV Community and was authored by gagecantrelle
Hello if you haven't read part 1 I recommend you read that First before you read this. To recap on what I talked about, it's about what the code of Minecraft looks like. some of you Might want to Build a similar game to it or just want to try and change yourself. Whatever the reason you are curious about it since this is a popular game we are talking about. So let's continue I left off in part 1 of MINECRAFT-how does it work, also here is the link for part 1 https://dev.to/gagecantrelle/minecraft-how-does-it-work-part-1-1i8l.
Before starting let's refresh our knowledge of Minecraft
- made by a Swedish game programmer Markus Notch
- made in 2009
- sold to Microsoft in 2014
- Became popular after being sold
Buffers, what are they and why would we need them? If you Remember part 1 talked about Vertx data and the process, you need something to pass it to OpenGL. A Buffer is basically like a storage unit on the GPU, it can hold any data type.
In OpenGL, there are different buffer types for Different tasks. Here are some common buffers that are used GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_TEXTURE_BUFFER, GL_DRAW_INDIRECT_BUFFER, GL_SHADER_STORAGE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, and GL_UNIFORM_BUFFER.
let's talk about GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER first. So how do we use the two buffers? First, we need to create an array buffer
with the glCreateBuffers function. Passing it a number and ID so we can target it later. Next, we need to tell it what type of buffer it is supposed to be with glNindBuffer(). The parameters that it will take are the buffer type and the buffer ID you created. Finally, we need to use the glBufferData function to pass in our data. It will take in four parameters the buffer type, the size of the data, the data itself, and usage. The last parameter is used for telling what we intend to do with the data.
Here is some links to the Doc that talk about all the usage types. https://registry.khronos.org/OpenGL-Refpages/gl4/html/glBindBuffer.xhtml
https://registry.khronos.org/OpenGL-Refpages/gl4/html/glBufferData.xhtml
After creating the buffer and giving it data to use, how can we use that data? By using a Vertex and Fragment shader, now let's say we want to send
the position and color data. First, we need to use the layout function to set the position where the Vertex data is at.
Now we need to use the glVertexAttribPointer function, to tell the GPU that the buffer holds vertex data.
It will take in six values GLuint, GLint, GLenum, GLboolean, GLsize, and offsetPointer
- GLuint - index/location data for where it at
- GLint - size / how many components this attribute has - Must be a size of 1, 2, 3, or 4 for basic data type - For a vertex 3 data type you use size 3
- GLenum - type / the type of data - If you use vertex 3 you use GL_FLOAT
- GLboolean - normalized / if you want data pass-in to be normalized - Integrate to float data type - Normalized: has many meanings depending on its use, but to put in a general term for code. It's the Process of organizing data in a database to eliminate redundancy and inconsistencies - Depending on how you look it up on Google you will get different types of Normalized. like the version to get Unicode in javascript - Good for converting color data to normalized range data
- GLsize - stride / determine how many bites each vertex is - if the data is tightly pact meaning there is no gap between vertices, then set the value to 0 to represent the tightly pact data
- const void* offsetPointer - ask for the offset of the data
After you call that with the correct values you need we need to run the function glEnableVertexAttribArry function. This takes in the number that represents the layout location in the shader. That makes sure that OpenGL enables this vertex attribute as part of the state for the vertex array
We know how to create a buffer and make data pass to the buffer, but how do we combine them with OpenGL? By using Vertex Array Objects Better known as VAOs but what is it VAOs? Well, it's similar to an OpenGL buffer with its unique IDs, with only one difference. Being that instead of storing data it stores how our data should work
nest we create bind and create a vertex array by using the glCreateVertexArrays and glBindVertexArray functions. The reason why we have to bind it after creating it is because OpenGL is like a big state machine.
Then let's say you don't want it to be bound anymore, rerun the same function again but pass in a 0. Now let's take a five-minute break to take a good look at an example to see how this would look.
Ok, now that we just need to run it through the shader. Unfortunately, we won't talk about shaders due to them being at a point where they should be in their own blog. I explain more about them in part 3 of Minecraft-how does it work? Move on from that when we get the shader working we need OpenGL to draw the data from VAO. To do this we need to use two functions glUseProgram with the shader as a parameter, and glDrawArrays. The parameters for that are the Primitive first, then the start index, and finally vertex count as the last. Let's say we have twenty vertices, the starting point is fourteen and the court at six. The data will be drawn from vertices fourteen through nineteen.
Now that We have all the functions and data set up we can draw something. But wait we have a problem that we need to fix first before moving on. The problem is the duplication of vertices when something is drawn since some vertices share the same data. Let's say we draw a star with ten vertices but we want to use 8 triangles, then we would need twenty-four Vertices.
How would we fix this, luckily OpenGl thought of a way to fix this with the Element array buffer/GL_ELEMENT_ARRAY_BUFFER. This buffer will tell OpenGL that we want to reuse some of the vertices.
The way to set up the element array buffer is pretty much the same as setting up the array buffer
Now how do we set the elements, The doc states that it can only be assigned one of three values unsigned bytes, unsigned shorts, and unsigned ints. The OpenGl doc doesn't explain where to declare the data type we're using. We can specify it when drawing the elements, then declare them as unsigned ints with unit32_t. When the data is uploaded with the functions in the last images with the buffer being created. While the VAO is bound, that buffer will be related to that VAO
While the VAO is bound to the buffer we can use a different OpenGL function to draw it. The VAO must also have an element buffer bound for this to work. The function we will use is called glDrawElements it takes in the Primitives, a number that will represent how many elements and how many to draw. Next, we need to assign them with a GL_UNSIGN_INT. finally, we pass in an offset, if we set the offset to three it will start at the third index in the array. In the doc, it refers to this as a pointer because you can pass the element buffer directly to OpenGL here. thought You shouldn't do that because you need to upload the data every time the function is called. so instead think of this as an offset in the element array where you start drawing from.
This is a lot to take in from buffers to elements, vertices, etc. But it is important for creating an engine for a game to run on even if it Minecraft copy or not. Though we did skip talking about shaders we will talk more about them in part 3. Also, all information used in the creation of this blog is in the part 1 blog. Like I said in Part 1 this will not teach you how To make Minecraft but show you the steps that you might need to do. If you're making a Minecraft copy or something similar.
This content originally appeared on DEV Community and was authored by gagecantrelle
gagecantrelle | Sciencx (2024-07-20T20:58:57+00:00) MINECRAFT-How does it work? (part 2). Retrieved from https://www.scien.cx/2024/07/20/minecraft-how-does-it-work-part-2/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.