Welcome, Guest |
You have to register before you can post on our site.
|
Forum Statistics |
» Members: 103
» Latest member: yelruh
» Forum threads: 233
» Forum posts: 989
Full Statistics
|
Online Users |
There are currently 2 online users. » 0 Member(s) | 1 Guest(s) Bing
|
Latest Threads |
Is Vulkan the future?
Forum: General Chat
Last Post: web2gamedevconvert
07-07-2024, 12:29 PM
» Replies: 8
» Views: 18,679
|
hello
Forum: Scratchpad Games
Last Post: web2gamedevconvert
05-20-2024, 04:20 PM
» Replies: 10
» Views: 31,258
|
So, you're bypassing Unit...
Forum: General Chat
Last Post: web2gamedevconvert
05-18-2024, 10:34 AM
» Replies: 3
» Views: 15,216
|
Arise dead book?
Forum: Scratchpad Games
Last Post: Brian Beuken
02-29-2024, 08:07 AM
» Replies: 0
» Views: 1,141
|
Im working on a Game..
Forum: Scratchpad Games
Last Post: Brian Beuken
08-04-2023, 10:58 AM
» Replies: 8
» Views: 18,732
|
OpenGL Error handling
Forum: Assets, Tools, Libraries and other useful things
Last Post: Brian Beuken
12-07-2022, 11:48 AM
» Replies: 0
» Views: 5,792
|
Rock Pi5B
Forum: Other SBC's
Last Post: Brian Beuken
11-12-2022, 10:14 PM
» Replies: 5
» Views: 11,911
|
Setting Up Bullet
Forum: Assets, Tools, Libraries and other useful things
Last Post: Brian Beuken
10-12-2022, 11:36 AM
» Replies: 3
» Views: 14,642
|
Building with a toolchain
Forum: General Chat
Last Post: junglie85
09-11-2022, 07:45 AM
» Replies: 3
» Views: 11,703
|
Window doesn't open on Pi
Forum: Help my code won't work??
Last Post: junglie85
09-05-2022, 01:28 PM
» Replies: 5
» Views: 10,220
|
|
|
Disable OpenGL, for failed to add service error |
Posted by: Brian Beuken - 04-15-2018, 11:26 AM - Forum: Help my code won't work??
- Replies (7)
|
|
A new thing I wasn't aware of, since my Raspberry Pi's don't have the experimental version of OpenGL activated.
If your pi is currently running with "full" OpenGL enabled, then the OpenGLES2.0 demos in the book and on the site will most likely fail to run, giving a failed to add service error.
The fix is simple, you need to have a totally fresh install of Raspbian before you start working on the book. (this is by far the best option)
or
You have to disable the OpenGL drivers. You can do this by opening a terminal and entering
sudo raspi-config
use your keyboard to select Advanced options,
select GL Driver
and then use Legacy Original non-GL drivers
(if you have OpenGL drivers installed it will say disable GL drivers instead)
Once done you are back in OpenGLES2.0 mode, and all OpenGLES2.0 projects should now work fine.
There are work rounds to get OpenGL to work, but really I would avoid that, the projects are all designed on OpenGLES2.0 so best to use it.
Reading the Pi forums, there may be other causes for this error, but for Stretch, this seems the most likely.
|
|
|
C++ Coding MagPi #69 |
Posted by: Brian Beuken - 04-13-2018, 08:29 AM - Forum: General Chat
- No Replies
|
|
A bit of a leap this month as we finally get a game (of sorts) up and running. Most of the explanations for what is happening are in the source code as the article needs to describe what we're doing rather than spell out the code.
Using what we learned previously about creating objects and giving them graphics we can arrange for a playfield to be displayed and populate it with items which we set up at the beginning and also create as the game is in progress.
This is our first proper use of inheritance and creating objects in the free space memory using the new keyword. It also means we need to take responsibility for removing items we make when we are done with them which brings us to the delete keyword. These 2 keywords should always balance up.
We will also see that even though we are making a game, it clearly suffers from some issues, especially speed. Next month we need to look into why a project that is working fine, isn't working fast and what we can do about that.
|
|
|
[Chapter 04] Unclear where to put the FileHandler code |
Posted by: sephris - 04-10-2018, 01:06 PM - Forum: Fundamentals Errata/Questions
- Replies (2)
|
|
Hi,
So I just finished the part about displaying the single picture ("lenna.png") in chapter 04. There's one part that seemed unclear to me and that's where to put this FileHandler code:
Code: int Width, Height;
char* OurRawData = FileHandler.Load((char*)"../assets/lenna.png", &Width, &Height);
if (OurRawData == NULL) printf("Picture failed to load.\n");
p_state->user_data->textureID = CreateTexture2D(Width, Height, OurRawData);
You mention a while (TRUE) loop on page 63 as if it's already existing, but if you look back at the first code listing for the triangle on page 49, there is no while loop in the main function.
My first reaction was to put the new code into the esMainLoop function (I mean, it's already called main loop, it has a while loop that terminates and it worked previously) which resulted in a program that was executing but displayed no picture, no compiler errors and none of the debug messages. So, without any errors I started looking for mistakes elsewhere and checked the code that was changed in this chapter so far against the book ... twice. Only when looking at the project file you uploaded for chapter 04 did I notice that you had placed a new while loop in the main function.
So, to summarize, on page 61 you wrote "After the FileHandler add this code;" which in my opinion should have been something like "Above the esMainLoop function in the main function at the bottom, add the following code:" and then on page 63 it should have said to add the new line below and put a while (TRUE) loop around it while also mentioning that execution of the program can now only be stopped from within Visual Studio by pressing the "Stop Debugging"-button.
Another thing, maybe for the next edition: Could you please highlight the changes you made to existing code?
|
|
|
Shadow Mapping Shaders |
Posted by: Brian Beuken - 04-08-2018, 02:30 AM - Forum: OpenGLES2.0 Shaders
- No Replies
|
|
Shadow Mapping requires 2 sets of shaders, one to gather the shadows and one to render them
The principles are explained in the Fundamentals book, so I won't go into them here, and the shaders are also available on downloadable demo's but I thought I'd put them here in isolation for you as well. These are optimized to run reasonably well on OpenGLES2.0 giving the client side (CPU) the responsibility to create the MVP for light and Models. Normally on a PC you'd let the Shader caclulate them, but here its better to let the CPU pass these as a uniform. (because even though PC is far slower to do the calculations, its a one time thing, but on a limited core GPU you don't gain the performance boost you would on a 512core unit)
1st thing to remember is that you need to do a gathering pass, where you render your height map into an FBO so you need to have an FBO 1st. This is easy to set up like so.
Code: // only used when creating dynamic shadows.
// Create and return a frame buffer object
GLuint Graphics::CreateShadowBuffer(int width, int height)
{
GLuint FBO, RenderBuffer;
glActiveTexture(GL_TEXTURE1); // use an unused texture
// make a texture the size of the screen
glGenTextures(1, &ShadowTexture);
glBindTexture(GL_TEXTURE_2D, ShadowTexture); // its bound to texture 1
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// once the texture is set up, we can turn to the Framebuffer
glGenFramebuffers(1, &FBO); // allocate a FrameBuffer
glGenRenderbuffers(1, &RenderBuffer); // allocate a render buffer
glBindRenderbuffer(GL_RENDERBUFFER, RenderBuffer); // bind it
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,height); //give some parameters for it
glBindTexture(GL_TEXTURE_2D, ShadowTexture); // bind the texture
glBindFramebuffer(GL_FRAMEBUFFER, FBO); // and the frame buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RenderBuffer); // they are now attached
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ShadowTexture, 0); // and so is the texture that will be created
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
printf("oh bugger framebuffer not properly set up");
glActiveTexture(GL_TEXTURE0); // careful to not damage this
return FBO;
}
Height and width should be the same (512x512 or 1024*1024 work well), but you can have any size you want up to the max size of textures, but the bigger the better, though there is a speed penalty the bigger the buffer is. If you have a very large scene, it might be better to use a number of different lights and switch between them with different view areas to cover the space.
Now that you have your framebuffer, you only need to switch it on and clear it before running a gathering pass
Code: // if we are going to have shadows, we need to do a pass through all the objects and do the draw shadow routines for anything that casts
glBindFramebuffer(GL_FRAMEBUFFER, MyGraphics->ShadowFB);
glViewport(0, 0, ShadowBufferSize, ShadowBufferSize);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (int i = 0; i < MyObjects.size(); i++)
{
MyObjects[i]->DrawShadow(); // most objects will do a dummy call
} // for
The DrawShadow method is a much more simplified drawing system, which has no need of textures or light effects, it only needs to do a simple draw with these shaders, 1st the vertex.
Code: #version 100
precision mediump float;
// simple shader to gather the depth, its a 1st pass shader designed to render into a bound FBO
attribute vec4 a_position;
uniform mat4 u_lightMVP; // light MVP is the casters Model, the lights view and Projection
varying vec4 v_texCoords; // we have to pass coords to the frag shader
void main()
{
gl_Position = u_lightMVP * a_position;
v_texCoords = gl_Position; // pass this to the fragment which can't access gl_Position
}
And now the fragment
Code: #version 100
precision mediump float;
varying vec4 v_texCoords;
/*
Generate shadow map
We need to gather the depth values, bring them into range
and then encode them into the x and y values of the
colour value we create
This shader should be linked with ShadowMap.vsh and used with a bound FBO
*/
void main()
{
float value = 10.0 - v_texCoords.z; // 10 is the most usual range
float num = floor(value);
float f = value - num; // get the floating point value
float vn = num * 0.1;
gl_FragColor = vec4(vn, f, 0.0, 1.0);
}
any model which casts a shadow needs to set up these shaders, and then simply run a simplified DrawShadow Method.
Once thats done, you will have a nice FBO filled with shadow info, actually height map info, and you can switch off your FBO and render back to screen with a simple
Code: // release the shadow framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
// Setup the viewport
glViewport(0, 0, MyGraphics->p_state->width, MyGraphics->p_state->height);
Now we're ready to render normally, Your Vertex Shader looks like this
Code: #version 100
precision mediump float;
attribute vec4 a_position;
attribute vec3 a_normal;
attribute vec2 a_texCoord;
uniform mat4 MVP; // our models MVP
uniform mat4 u_LightsMVP; // our lights MVP (using the objects model)
varying vec4 v_ShadowTexCoord; // the texture coords for the shadow
varying vec2 v_texCoord; // the usual texture coords for the texture
// we need to bring our values into range so this matrix will do that
const mat4 biasMatrix = mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0);
void main()
{
// Calculate vertex position, seen from the light view point and Normalize texture coords from -1<>1
v_ShadowTexCoord = biasMatrix * (u_LightsMVP * a_position); // this result gets passed to the frag shader as its a varying
// do our normal position calculations
gl_Position = MVP * a_position; // use the models normal camera based MVP
// pass the texture coord to the frag and our lit flag
v_texCoord = a_texCoord;
}
and your fragment
Code: #version 100
precision mediump float;
/*
This is a base level system for adding shadows to your scene, it uses a simple
FBO as a texture to gain access to a shadow map.
The result is an effective but potentially low resolution hard shadow (depending on scene size and light spread)
Softer shadows can be done using PCF or other methods but there is a very significant
drop in performance on limited core GPU's and you need a better resolution to get good results, on phones/SBC's this may be too much.
*/
uniform sampler2D s_texture; // texture0 our normal diffuse texture
uniform sampler2D u_s2dShadowMap; // texture1 our FBO shadows
uniform vec4 Ambient; // not used yet
varying vec4 v_ShadowTexCoord; // the coordinates passed from the vertex shader
varying vec2 v_texCoord; // passed by our normal textures
void main()
{
float fLight = 1.0; // supply a transparent value as defaut
/* we need to get the packed light distance data from the shadow texture, texture1. */
vec2 Depth = texture2DProj(u_s2dShadowMap, v_ShadowTexCoord).xy;
// its in 2 values scaled down so resize them
float fDepth = (Depth.x * 10.0 + Depth.y);
// reconstitute the depth
float ActualDepth = (10.0-v_ShadowTexCoord.z) + 0.1 - fDepth ;
if (fDepth> 0.0 && ActualDepth <0.0)
{
fLight = 0.6; // set lower values for a darker shadow
}
gl_FragColor = texture2D( s_texture, v_texCoord )*fLight; // we can also use ambient and other light factors here
gl_FragColor.w = 1.0;
}
And thats it... Assuming you set up the light to an overhead location that is not too far away from the casters, and your draw routine provides the appropriate uniforms and attribute pointers you will get a nice set of shadows like this
Shadow mapping is an effective and relatively fast way to do shadows, but softer edge shadows are preferred, trouble is the Pi GPU and most other SBC GPU's will struggle to do too much of the sampling needed to do them, so for now this is probably the best option. But....there are ways to make it better, I'll let you explore them.
You will note that the shadow has rather chunky pixels, this can be improved with a decent sample system to give anti aliasing, but as noted you will find there is a massive speed hit for that.
Also a factor, is the resolution of our FBO, whatever size it is it will stretch over the view of our lights coverage of the terrain so a smaller FBO stretches further and has chunkier pixels.
Separate lights swapped as needed and focusing on areas that are close to the size of the texture will provide better results. Larger resolution FBO's are also good, but do come at a cost of speed.
Of course these shaders don't do any lighting or Lerping, which you will need to add if you want them, but remember, the more you make your shaders do, the slower they get.
This very simple shadow technique has its flaws, but it will work on pretty much any system. Culling systems to prevent rendering when not needed will also make a massive difference.
|
|
|
Other Model Formats |
Posted by: Brian Beuken - 03-24-2018, 09:09 PM - Forum: Assets, Tools, Libraries and other useful things
- No Replies
|
|
I am investigating some other model formats, mainly MD5 to experiment with skeletal systems where there are a lot of public domain assets around.
I won't be posting my efforts for a while though as I'm caught up in some other things non SBC related. But my colleague Ahbishek Biswas at NHTV did manage to get a nice little demo of MD5 up and running on Pi, so it just needs a bit more time to optimise
I'm also investigating the use of glFT since Soyo has a tinyglft loader that is in production, it might give us access to more interesting model formats, as soon as I can work out how to extract the data and a render system to draw it.
If anyone has had any success in that field, please tell us all about it.
|
|
|
taking monochrome too far, its a red dot! |
Posted by: Brian Beuken - 03-21-2018, 01:08 AM - Forum: Fundamentals Errata/Questions
- No Replies
|
|
I only just noticed this one, on page 8,11 and 12, there is mention of a grey dot when using the debugger.... which is funny because what I wrote was, there is a red dot!
Clearly the type setters looked at the monochrome version of the image, and decided to "correct" my text since it certainly is grey in the image.....but of course on your screen its red.
|
|
|
|