PDA

View Full Version : Good project and resources for a begginer to start in OpenGL



mikel_landa
03-26-2017, 10:03 AM
Hi guys, i have holidays in the next month and so i decided that will spend some of that time learning OpenGL.
I would like to make a game like Pacman or maybe a car racing game, in 3D.
I don't know if the above is too ambitious as i have no experience in OpenGL but i have a bit of programming experience.
I also wouldn't mind investing in a good book, if it's worth it. Are there OpenGL books with good examples in form of code? I find that really helps when i start learning something.

BBeck1
03-27-2017, 05:08 AM
Check out LearnOpenGL.com (https://learnopengl.com/) and the tutorial there. Having a solid understanding of programming is a good start, but it's just the prerequisite. There is so much to learn; a month is pretty ambitious. I was told that a guy who had quite a lot of experience making 3D games did 3D Pacman with the help of a musician in a month. He obviously wasn't learning, but quite experienced already and it took him a month. After studying 3D game programming for over a decade, I think I'm at the point where if I had an entire month with 8 hours a day for 30 days, I think I could probably crank out 3D Pacman by myself. That would be rather ambitious for me, especially if I have to use some of that time to compose the music, so maybe two such months. 3D Space Invaders or Pong would probably be a bit easier.

I worked on 3D Pong for awhile as part of a game programming competition. I had intended on fully completing it, but a major life event got in the way and by the time I got back to it the competition was over. I did a little video montage intro to my videos (https://www.youtube.com/watch?v=HYn9ast2gps) and at about 16 seconds in, there is some video of where I was at with my 3D Pong to give you some idea of how I envision 3D Pong. The yellow cross hairs basically show the depth of the ball because I found depth perception to be a lot more difficult than I expected, probably because both eyes are looking at the same image.

Unfortunately, I don't know of a single good place to go to learn this stuff. Game Institute (https://www.gameinstitute.com/) has a lot of game programming videos and for about $120 a year (they have a sale on till tomorrow) they give you access to all those videos on various subjects including a video series teaching modern OpenGL. I'm enrolled in their 2 year 3D Modeling program and I'm amazed at the progress I've made in just 6 months in that program, but that's far more expensive to enroll in one of their programs. And in that particular case, it's an art program and not a programming class. They do have a game programming program, but I haven't taken it and so could not say much about it.

In that video montage at the start of my video, there is also a toy car model driving around. Something like that is not overly ambitious; you just have to know how to put objects on the screen and rigid animation in order to do that. A model like that is fairly easy to whip up in Blender, although a 3D modeling program like Blender can be overwhelming (to say the least) to someone uninitiated. Basically, you just add some box meshes to the scene in object mode, I did an edge loop to create some vertices in the car body that I could move in Edit mode, and parent the wheel cubes to the body. Figuring out how to get the model into OpenGL might take the better part of a month. Assimp (http://www.assimp.org/) might be a good option. I wrote an exporter for Blender in Python. I was discussing it in another thread just a couple days ago. (EDIT: It turns out that was on another forum (https://www.gamedev.net/topic/687246-planning-on-using-blender/) where I discuss my Python Blender exporter in great detail. Hope no one minds the cross-forum post, but as you can see, I tend to write novels when I reply and that was a lot of info to be reposting.)

Often when I learn, I want a code example that I can study more than anything. I started out doing step by step tutorials, but I found it would take me forever to do very simple basic tutorials. I eventually decided I would just write code examples as tutorials and maybe some day do a YouTube video explaining the code line by line. And that is the tutorial format I am going for these days, but I haven't had any time to work on tutorials in over a year. I would recommend completing the LearnOpenGL.com stuff and then, assuming you have a fairly solid knowledge of C++, you might want to check out the work I've been doing on my OpenGL engine. On my website (http://virtuallyprogramming.com/OGL45/OGL45.html), I have the full OGL project in Visual Studio posted for download. There is a video on that page that you can click on (https://files.secureserver.net/0sBY3eAPXhNNga) and see what the "engine" does so far. It's not much, but if you can figure out how to get that far in a month, you've made a major accomplishment. Basically, it does what I call "hand coded 3D objects"; there is a class for that that allows you to specify a vertex buffer in order to code your models by hand. When you progress beyond cubes, this method of creating 3D models is far too cumbersome. Hand code a cube and you'll see what I mean when I say anything more complex than this just isn't going to happen; you have to start using a 3D modeling program like Blender to make your models and that requires figuring out how to get that data from Blender into your program. My OGL example engine doesn't do that, but my DirectX 11 engine (http://virtuallyprogramming.com/DirectX11/Tutorials/Tutorials.html) worked with a Python exporter from Blender to create the model files and import them into my engine. The Python code and everything else is included in that Project download. It probably would not be too difficult to convert all that model code over to OGL. I had planned on doing it, but have been side tracked for the past year or two (for one thing I'm in a 2 year program learning 3D modeling).

You might want to watch all my videos if you are new to 3D game programming, and especially if you don't know Linear Algebra pretty well. I would recommend starting with my Vector video (https://www.youtube.com/watch?v=56v9BgwSzsg) and then watching the Matrix video (https://www.youtube.com/watch?v=T7sb4yKKzFg). You'll need to know that stuff before learning shader programming. Short of copying and pasting code, you can't make a modern OGL program without learning GLSL shader programming. My HLSL series is more of a DirectX approach, but so much of it is math that it's probably still something you will want to watch in your quest to learn GLSL. And the series starts out with the most simple shader and builds a Blinn-Phong shader by the end, which is the foundation of most 3D shaders you will use. My OGL engine has a GLSL shader with source code that is nearly identical except I added fog to the GLSL shader. I think I tried to use the same variable names to make the DX and OGL shaders as similar as possible. The biggest difference is that DX apparently calls Uniforms constant buffers and calls fragment shaders pixel shaders. It won't hurt you to learn some HLSL as well since many book examples you see will be written in HLSL, although most I've seen are actually in GLSL. The underlying concepts are identical for HLSL and GLSL it's just some of the syntax that changes mostly.

I wish I knew of a book that I would recommend for learning 3D game programming OGL. I had to use several books and piece together the knowledge and still ended up using an online tutorial to get started in OGL. Wish I had of known about LearnOpenGL.com back then. There's probably some stuff on YouTube as well. Most of the OGL books are probably going to be focused on drawing things on the screen rather than making 3D video games. You kind of have to figure out how to put things on the screen before you can even begin to think about making a 3D game. And it takes quite a bit of knowledge to put things on the screen.

I also found it rather challenging just to get OGL compiled with all the libraries required. I use GLFW, GLEW, GLM, and FreeImage for my engine. You have to decide whether you are going to do dynamic linking or static linking. I tried to do static linking, but now I'm thinking maybe dynamic linking is a better option. On a lot of these you can download the binaries. But at some point, you really need to learn to make the files and build your own binaries on all these libraries. I think people from the Linux world or those who have done a whole lot of C/C++ programming may consider this par for the course, but for me it was the steepest part of the learning curve in learning OGL.

And all that gets you to about where my engine code is. It allows you to hand code objects, put them in the scene, move them around and rotate them, as well as gives you a camera that you can move through the scene and displays it all with a GLSL Blinn-Phong shader. It also supports keyboard and game controller input. It's not a bad start. I wanted to create the "engine" as boiler plate code that I could then use in every example I do of 3D game programming. Because when you get this far, you haven't even really begun to learn the subject of 3D game programming, although you will have come amazingly far, especially if you got the Blender exporter working and converted the RigidModel and ModelCompiler classes from my DX11 code to OGL so that you can put Blender models in the scene.

I think if you can understand every line of my OGL engine code in a month, you will have made an amazing accomplishment in learning 3D programming. But I would start with LearnOpenGL.com and then maybe try some of my stuff. And I would probably watch all of my videos on my YouTube channel at VirtuallyProgramming.com before going through my OGL engine code. It should shine some light on my GLSL shader.

Best of luck to you in your pursuit of OGL! Oh. And when you get stuck or don't understand something, forums such as this are a great place to get some help.

BBeck1
03-27-2017, 05:44 AM
If you want to go through my HLSL video series (https://www.youtube.com/watch?v=2MTMGmkb8k0), you probably would want my GLSL code to compare. I'll post it here so that you don't have to download the whole project file just to get the GLSL code. You can probably skip the first video and jump straight to the Triangles video (https://www.youtube.com/watch?v=2MTMGmkb8k0). The first video just discusses the calling code, written in XNA and the differences between HLSL for XNA and HLSL for DirectX 11. None of that probably matters to you. So, I would just skip that video. And you probably want to skip the Gimbal Lock video after watching the Matrix video until you have done everything else. You don't need to worry about Gimbal Lock until you start moving things through the scene. Plus, that's all in XNA code and so it might be confusing anyway if you don't know XNA and C#.

After watching the triangles video, just continue the videos in numeric order as the whole series builds on each video. You probably want to watch the vector (https://www.youtube.com/watch?v=56v9BgwSzsg) and matrix videos first, if you don't have solid understanding of those two subjects.


BlinnPhong.vrt


#version 450 core
layout (location = 0) in vec3 Pos;
layout (location = 1) in vec2 UV;
layout (location = 2) in vec3 Normal;
layout (location = 3) in vec4 Color;

uniform mat4 WorldMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;



smooth out vec2 TextureCoordinates;
smooth out vec3 VertexNormal;
smooth out vec4 RGBAColor;
smooth out vec4 PositionRelativeToCamera;
out vec3 WorldSpacePosition;


void main()
{
gl_Position = WorldMatrix * vec4(Pos, 1.0f); //Apply object's world matrix.
WorldSpacePosition = gl_Position.xyz; //Save the position of the vertex in the 3D world just calculated. Convert to vec3 because it will be used with other vec3's.
gl_Position = ViewMatrix * gl_Position; //Apply the view matrix for the camera.
PositionRelativeToCamera = gl_Position;
gl_Position = ProjectionMatrix * gl_Position; //Apply the Projection Matrix to project it on to a 2D plane.
TextureCoordinates = UV; //Pass through the texture coordinates to the fragment shader.
VertexNormal = mat3(WorldMatrix) * Normal; //Rotate the normal according to how the model is oriented in the 3D world.
RGBAColor = Color; //Pass through the color to the fragment shader.
};



BlingPhong.frg


#version 450 core

in vec2 TextureCoordinates;
in vec3 VertexNormal;
in vec4 RGBAColor;
in float FogFactor;
in vec4 PositionRelativeToCamera;
in vec3 WorldSpacePosition;

layout (location = 0) out vec4 OutputColor;


uniform vec4 AmbientLightColor;
uniform vec3 DiffuseLightDirection;
uniform vec4 DiffuseLightColor;
uniform vec3 CameraPosition;
uniform float SpecularPower;
uniform vec4 FogColor;
uniform float FogStartDistance;
uniform float FogMaxDistance;
uniform bool UseTexture;
uniform sampler2D Texture0;



vec4 BlinnSpecular(in vec3 LightDirection, in vec4 LightColor, in vec3 PixelNormal, in vec3 CameraDirection, in float SpecularPower)
{
vec3 HalfwayNormal;
vec4 SpecularLight;
float SpecularHighlightAmount;


HalfwayNormal = normalize(LightDirection + CameraDirection);
SpecularHighlightAmount = pow(clamp(dot(PixelNormal, HalfwayNormal), 0.0, 1.0), SpecularPower);
SpecularLight = SpecularHighlightAmount * LightColor;

return SpecularLight;
}


vec4 PhongSpecular(in vec3 LightDirection, in vec4 LightColor, in vec3 PixelNormal, in vec3 CameraDirection, in float SpecularPower)
{
vec3 ReflectedLightDirection;
vec4 SpecularLight;
float SpecularHighlightAmount;


ReflectedLightDirection = 2.0 * PixelNormal * clamp(dot(PixelNormal, LightDirection), 0.0, 1.0) - LightDirection;
SpecularHighlightAmount = pow(clamp(dot(ReflectedLightDirection, CameraDirection), 0.0, 1.0), SpecularPower);
SpecularLight = SpecularHighlightAmount * LightColor;


return SpecularLight;
}


void main()
{
vec3 LightDirection;
float DiffuseLightPercentage;
vec4 SpecularColor;
vec3 CameraDirection; //Float3 because the w component really doesn't belong in a 3D vector normal.
vec4 AmbientLight;
vec4 DiffuseLight;
vec4 InputColor;


if (UseTexture)
{
InputColor = texture(Texture0, TextureCoordinates);
}
else
{
InputColor = RGBAColor; // vec4(0.0, 0.0, 0.0, 1.0);
}


LightDirection = -normalize(DiffuseLightDirection); //Normal must face into the light, rather than WITH the light to be lit up.
DiffuseLightPercentage = max(dot(VertexNormal, LightDirection), 0.0); //Percentage is based on angle between the direction of light and the vertex's normal.
DiffuseLight = clamp((DiffuseLightColor * InputColor) * DiffuseLightPercentage, 0.0, 1.0); //Apply only the percentage of the diffuse color. Saturate clamps output between 0.0 and 1.0.

CameraDirection = normalize(CameraPosition - WorldSpacePosition); //Create a normal that points in the direction from the pixel to the camera.

if (DiffuseLightPercentage == 0.0f)
{
SpecularColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
else
{
//SpecularColor = BlinnSpecular(LightDirection, DiffuseLightColor, normalize(VertexNormal), CameraDirection, SpecularPower);
SpecularColor = PhongSpecular(LightDirection, DiffuseLightColor, normalize(VertexNormal), CameraDirection, SpecularPower);
}

float FogDensity = 0.01f;
float LOG2 = 1.442695f;
float FogFactor = exp2(-FogDensity * FogDensity * PositionRelativeToCamera.z * PositionRelativeToCamera.z * LOG2);
FogFactor = 1 - FogFactor;
//float FogFactor = clamp((FogMaxDistance - PositionRelativeToCamera.z)/(FogMaxDistance - FogStartDistance), 0.0, 1.0);

OutputColor = RGBAColor * (AmbientLightColor * InputColor) + DiffuseLight + SpecularColor;
OutputColor = mix (OutputColor, FogColor, FogFactor);
//OutputColor = vec4(0.0f, 0.5f, 0.0f, 1.0f);
};

mikel_landa
03-27-2017, 07:18 PM
So what are realistic games in 3D i can for in about a month, writing it in C++ and using GLUT and GLEW and doing tutorials in LearnOpenGL.com?
I'll guess i'll just use this time to build solid foundation but i would to do some cool 3D game, even if very simple.
Then later i could aim for more ambitious projects, maybe pacman? Or still not ready? :p

john_connor
03-28-2017, 12:52 AM
So what are realistic games in 3D i can for in about a month, writing it in C++ and using GLUT and GLEW and doing tutorials in LearnOpenGL.com?

making a game isnt the same as drawing with openGL, a game is much more than that, has most likely 3D sound, AI, physics, user interface, commands, maybe scripting and so on

drawing (the "wrong" way) is very simple: figure out how to draw some shapes, wrap that piece of code is a class and you're done. thats the usual c++ way of doing things, but the perfomance will suffer A LOT. by doing tutorials, reading some books AND reading the wiki page on this site, you get the "correct way" of how to use openGL efficiently

OpenAL (https://www.openal.org/) (3D audio library) would be the next thing to learn, its similar to OpenGL, but there is much less to understand

once you have a ball bouncing from the ground that you can hear, see (any maybe control), the actual "game programming" starts