LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Noodles on August 10, 2013, 18:04:47

Title: Making a Graphics Engine
Post by: Noodles on August 10, 2013, 18:04:47
So Hi,

I am having some problems finding anything about this matter in the Internet.
I want to write a Graphics Engine, preety straight forward.
I want to make it possible to make moving Objects for example a human(actually there will only be chibi).
So, I got two problems:

-about moving Objects, I was thinking of making an abstract skeleton like stickfigure, which represents the basic movement of, in this example, the chibi.
Then building the mesh around each segment for example the upperleg, and pin the mesh to the abstract stick, so when i move the stick the mesh moves accordingly, but
if im thinking of using knees, how should i best animate these, should i use clipping, so just simply let two meshes clip each other, or should i make extra dynamic meshes for them?
Also how would i realize this structure in lwjgl, im quite new to moving objects in opengl.

-about savig these animation in NOT code segments, i thought about cutting the animation into (maybe 100) pieces and in each piece i can move the "sticks" as far as i like, for easier use maybe even just code 
something in a simmilar manner to : ";wait 10 segments;turn 90° in 30 segments; wait 3 segments; turn -90° in 30 segments;finallize segments"(finallize would be for reaching 100 segments).
Might this design be viable?

I would like to see sample code segments, since that will probably help me alot in understanding how to do this.

Thankyou very much in advance
Noodles
Title: Re: Making a Graphics Engine
Post by: quew8 on August 10, 2013, 21:57:57
For animating characters in 3d, I think skeletal animation is the way you want to go.  Essentially you transform the skeleton and then each vertex of the mesh has a weighting to each adjacent node on the skeleton and you work out the position based on these weightings. It is quick and if done well looks natural.

However, this is not a simple technique and would require at the very least a strong knowledge of shaders and matrix transformations. It is not for the lighthearted. I would advise looking at something simpler first.
Title: Re: Making a Graphics Engine
Post by: Noodles on August 11, 2013, 09:44:04
I have actually worked with opengl once before,
but in that case someone else had set everthing up and only transformations were left to do I actually wrote a shader for that programm so no worries i have donne that before,
my problem is not knowing how to do it, but how to do it best, its supposed to be a high performance game engine.
Im not sure how to use the weightings you suggested ?
Do you know some Web-Page, where I can read about it ? I am not able to find anything on this Topic.

Thanks for the reply though.
Title: Re: Making a Graphics Engine
Post by: quew8 on August 11, 2013, 10:30:22
If you've done complex transforms before then that's actually a very good place to start from. You will need to read up on vbos though as they are extremely important for performance. http://www.lwjgl.org/wiki/index.php?title=Main_Page (http://www.lwjgl.org/wiki/index.php?title=Main_Page) (Read either the OpenGL 3.2+ section or "Using FBOs" in the legacy OpenGL section)

http://en.wikipedia.org/wiki/Skeletal_animation (http://en.wikipedia.org/wiki/Skeletal_animation)

Essentially pass the skeleton, stored as a series of transformation matrices, in a uniform variable (if you are going for performance then you should do this in a texture). Your skin mesh should be stored in a vbo. The real magic happens in the shader (as per usual)

Can't really help you anymore - I've never implemented this myself. (I'll get round to it eventually)
Title: Re: Making a Graphics Engine
Post by: Noodles on August 11, 2013, 10:59:31
Ok,

I have another question, I am not sure if I read it correctly but is VBO used server-sided and sends the data to the client and is supposed to do so in real time ? Or was it an exmaple on how VBO is considered to work(with a server-client architecture?).
Well how ever, The Colours, that are used in the Examples on the Wiki, or they supposed to be for Shader purposes ? , since im not sure why I would want to change the location of colour(in form of .gif or .jpeg) that i wrap around the Object, or does this have to be done symmetrical to the conversions ?
Title: Re: Making a Graphics Engine
Post by: quew8 on August 11, 2013, 14:56:04
A VBO is a vertex buffer object. It is an area in the video card's memory where you can store vertex data so it is at the video card's "fingertips." (Ie. no lengthy copying ops between cpu and gpu). Once the VBO is created and the vertex data stored, you can draw the subject with just two or three OpenGL calls.

http://www.lwjgl.org/wiki/index.php?title=Using_Vertex_Buffer_Objects_(VBO) (http://www.lwjgl.org/wiki/index.php?title=Using_Vertex_Buffer_Objects_(VBO))

Definitely have a read.
Title: Re: Making a Graphics Engine
Post by: Noodles on August 27, 2013, 14:40:43
Hi again,

I am starting to try out all of the VBO stuff and i ran into a Problem.
When using VBOs scaling, rotating and translating has to be implemented different, in the example on the Wiki "The Quad with Projection, View and Model matrices"
he sets uniform variables, but these seem to be Global, so my question is:

If i got two Objects that move seperatly, do I have to save both object-Meshes in different VBO's ?
If I wouldnt I would allways move both of the Objects at the same time, the same amount!

Or is there another way to scale rotate and translate.

Ty for any answers.
Title: Re: Making a Graphics Engine
Post by: quew8 on August 27, 2013, 15:31:37
Problem with a capital 'P.'

You can draw different sections of the vbo with the offset parameter of glDrawElements(). So draw one object, then set the new transformation, then draw the next object.
Title: Re: Making a Graphics Engine
Post by: Noodles on August 27, 2013, 19:08:35
Sorry for the "Problem", am German,
So I still got a Problem with understanding this offset, if I say glDrawElements then all Elements get drawn from the offset forward am i right ?
If so then first i draw elements (0 to n) and with offset i draw objects (offset to n), if you ignore interleaving.
Or how do i set how many vertices get drawn for example vertice 0 to 5 then 5 to 10 then 10 to 15 etc ?
Title: Re: Making a Graphics Engine
Post by: quew8 on August 27, 2013, 20:40:05
That can be changed with the count parameter. So drawing n indices from the m th index can be achieved by:


glDrawElements(GL_WHATEVER, n, GL_UNSIGNED_INT, m * 4);


4 being the size of one integer (unsigned or otherwise)

A tip for later, whenever you are unsure about something like this, I find it helps greatly to take a look at the documentation for the function: http://www.opengl.org/sdk/docs/man2/ (http://www.opengl.org/sdk/docs/man2/). That's the docs for OpenGL 2.x
Title: Re: Making a Graphics Engine
Post by: Noodles on August 27, 2013, 21:19:25
Well Thank you i guess I was mixing up some functions,
I thought the second param was used for interleaving,
but ok that way of course its easy to do what I want to,

Well Thanks alot.
Title: Re: Making a Graphics Engine
Post by: quew8 on August 27, 2013, 21:43:23
No problem - that's what the docs are there for.
Title: Re: Making a Graphics Engine
Post by: Noodles on September 02, 2013, 13:32:52
Well,
Hi again,

I am at the point of creating Objects for animating of characters,
now then I am running into problems again,
I am thinking about using smooth skinning algorythms for rendering purposes,
So every Vertex will need specific 4 matrices that are deffind by joint transformations,
these joint transformations change almost each rendering cycle, so what is the fastest way to provide these matrices ?
I believe i will have to save them interleaved beside position color and texture data.
Are my assumptions correct? If so is the fastest way there buffersubdata() ?
Or am I missing something ?

Thanks for any help.
Title: Re: Making a Graphics Engine
Post by: quew8 on September 02, 2013, 15:59:59
Pretty much. Just make sure you create the VBO with the GL_DYNAMIC_DRAW flag (The usage parameter of glBufferData). That informs the video card that you are going to be doing lots of updating and drawing with this VBO. Also, make sure you reuse Buffers as much as possible.

You could also look into using glMapBuffer / glUnMapBuffer but, for what it's worth, my money is on glBufferSubData.
Title: Re: Making a Graphics Engine
Post by: Noodles on September 02, 2013, 16:17:07
In this Tutorial
http://graphics.ucsd.edu/courses/cse169_w05/3-Skin.htm (http://graphics.ucsd.edu/courses/cse169_w05/3-Skin.htm)

it is suggested to put all the joint matrices in some sort of dynamic accesible array and
only save the index of the matrices psoition interleaved with the position color and textures.
Is this realizable is there some sort of array that I can acces via Shader programm?
For Examble a Uniform Matrix4f array?
I would only have to load this in once since every Vertex uses the same matrix with different weight?

I havent worked too much with Shaders, so im not sure if this is possible or if this is actaully efficient.
Title: Re: Making a Graphics Engine
Post by: quew8 on September 03, 2013, 14:56:34
It is kind for possible - and certainly much more efficient than updating VBOs the whole time, now I think about it.

Firstly by dynamic, do you mean dynamic sized or just changeable? The second is simple, the first is more difficult.

Essentially you can think of GLSL as C without pointers or memory allocation (Probably a few other things less as well). If you don't know about C, you can only create arrays with a compile-time constant length. Thus, to make dynamic arrays you dynamically assign memory, but GLSL doesn't have this second bit, so only fixed length arrays. The solution to this is to create a texture (which you can obviously choose whatever size for on creation (within hardware limits) ). You fill this texture with the data and access it in the shader via a sampler. Another benefit to this is that you don't have to re-upload the matrices the whole time if they are the same. (you can update them with glTexSubImageXD() ) (The obvious drawback of this is that you are using more video memory as well). I never use this method since it seems hacky so I'm always worried that some video cards will mess with the data to "optimize" it but since it isn't texture data will mess it up. However I HAVE NEVER HEARD OF THIS HAPPENING and if you think about it, it's stupid anyway.

So my alternate solution is to create a fixed sized array large enough for the maximum requirement I will ever have for it, fill it up as required and also pass up how many elements I've used if that is relevant.

Anyway, some code. To change a uniform variable, you must first get its location with glGetUniformLocation() :


int shaderProgramId = ... //your shader program's id.
int location = glGetUniformLocation(shaderProgramId, "aUniformVariableName"); //And yes, you literally put the variable's name.
//Essentially you name the variable exactly as you would in code, so for the 5th element of an array:
int arrayLoc = glGetUniformLocation(shaderProgramId, "aUniformVariableArray[5]");
//And for the "foo" field in a uniform structure:
int structLoc = glGetUniformLocation(shaderProgramId, "aUniformVariableStruct.foo");


Easy as pie. Then to upload your matrix (I'm only going to show you the matrix stuff):


FloatBuffer matrixBuff = ... //The float buffer containing your matrix.
boolean shouldTranspose = ... //Whether OpenGL should transpose the matrix as it loads it. Put false if you're unsure.
glUniformMatrix4f(location, shouldTranspose, matrixBuff); //Location is the variable from the previous snippet.


And that's it. If you're going to go with the texture route, then it obviously depends how you want to store the matrix in a texture. I would recommend a 1D texture but that's completely down to ease of use. I have no idea in general but especially no idea if that is the quickest / most efficient.

I'm sorry - I know I have waffled more than a little. Congratulations if you managed to get this far in one go.
Title: Re: Making a Graphics Engine
Post by: Noodles on September 04, 2013, 15:23:21
Well by dynamic I actually ment both,
/*Solution 1*/but now that I think about it your solution of making an array with a fixed maximum length should suffice.

/*Solution 2*/Do you think the Texture way would be more efficient?
Since I hav to change the matrices every render-Cicle, which means, I could have all the Textures saved which would be enormous amounts of Memory.
Or I would have to save a Texture each rendercicle just to acces it from the graphics memory, which I imagine is extremely inefficient.
But tell me do you think this would be at all more efficient than solution number 1.

Well thanks for the answer anyway.
Title: Re: Making a Graphics Engine
Post by: quew8 on September 04, 2013, 15:57:54
I can't say for sure - especially since I have never used that approach, but what I do know is this. Uniform Variables are designed to be updated frequently. Textures aren't really. Presumably, you will be using all of the uniform array a lot / all of the time so that isn't even a question of wasting memory.

I think the question you need to ask is, do I need truly dynamic arrays? Ie. can I be sure of the maximum size I will need at the shader's compile time or can't I?
Title: Re: Making a Graphics Engine
Post by: Noodles on September 04, 2013, 16:22:08
Since this array will be storing just one matrix for every joint in a animated body, I would guess between 64 and 256 would be enough, depending on how accurate I want to animate.

Well thanks I appreciate the consultancy.