Release Cannonball - The Enhanced C++ Outrun Engine


First I load the FBO extension with this function:

bool loadFBOExtension() {
bool fboExtensionAvailable = false;
bool fboFunctionsAvailable = false;

glBindFramebufferOES = null;
glDeleteFramebuffersOES = null;
glGenFramebuffersOES = null;
//glCheckFramebufferStatusOES = null;
glFramebufferTexture2DOES = null;

string extensions = to!string(cast(char *)glGetString(GL_EXTENSIONS));
string extleft = extensions;

while (extleft.length != 0) {
ptrdiff_t delim = indexOf(extleft, ' ');
string extension;
if (delim != -1) {
extension = extleft[0..delim];
extleft = extleft[delim+1..extleft.length];
} else {
extension = extleft;
extleft = extleft[0..0];
}

if (extension == "GL_OES_framebuffer_object") {
fboExtensionAvailable = true;
break;
}
}

if (fboExtensionAvailable) {
glBindFramebufferOES = cast(PFNGLBINDFRAMEBUFFEROESPROC) eglGetProcAddress(toStringz("glBindFramebufferOES"));
glDeleteFramebuffersOES = cast(PFNGLDELETEFRAMEBUFFERSOESPROC) eglGetProcAddress(toStringz("glDeleteFramebuffersOES"));
glGenFramebuffersOES = cast(PFNGLGENFRAMEBUFFERSOESPROC) eglGetProcAddress(toStringz("glGenFramebuffersOES"));
//glCheckFramebufferStatusOES = cast(PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) eglGetProcAddress(toStringz("glCheckFramebufferStatusOES"));
glFramebufferTexture2DOES = cast(PFNGLFRAMEBUFFERTEXTURE2DOESPROC) eglGetProcAddress(toStringz("glFramebufferTexture2DOES"));

fboFunctionsAvailable = (glBindFramebufferOES != null)
&& (glDeleteFramebuffersOES != null)
&& (glGenFramebuffersOES != null)
//&& (glCheckFramebufferStatusOES != null)
&& (glFramebufferTexture2DOES != null);
}

return fboExtensionAvailable && fboFunctionsAvailable;
}

Then I use it like this:

glGenFramebuffersOES(1, &luminousFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, luminousFramebuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, luminousTexture, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

The code is in D, but it should be understandable.
 
Installed this for the first time yesterday, great port thank you for doing it! One of my favourite games of all time, looks even better in widescreen and at 60hz.
 
First I load the FBO extension with this function:

bool loadFBOExtension() {
bool fboExtensionAvailable = false;
bool fboFunctionsAvailable = false;

glBindFramebufferOES = null;
glDeleteFramebuffersOES = null;
glGenFramebuffersOES = null;
//glCheckFramebufferStatusOES = null;
glFramebufferTexture2DOES = null;

string extensions = to!string(cast(char *)glGetString(GL_EXTENSIONS));
string extleft = extensions;

while (extleft.length != 0) {
ptrdiff_t delim = indexOf(extleft, ' ');
string extension;
if (delim != -1) {
extension = extleft[0..delim];
extleft = extleft[delim+1..extleft.length];
} else {
extension = extleft;
extleft = extleft[0..0];
}

if (extension == "GL_OES_framebuffer_object") {
fboExtensionAvailable = true;
break;
}
}

if (fboExtensionAvailable) {
glBindFramebufferOES = cast(PFNGLBINDFRAMEBUFFEROESPROC) eglGetProcAddress(toStringz("glBindFramebufferOES"));
glDeleteFramebuffersOES = cast(PFNGLDELETEFRAMEBUFFERSOESPROC) eglGetProcAddress(toStringz("glDeleteFramebuffersOES"));
glGenFramebuffersOES = cast(PFNGLGENFRAMEBUFFERSOESPROC) eglGetProcAddress(toStringz("glGenFramebuffersOES"));
//glCheckFramebufferStatusOES = cast(PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) eglGetProcAddress(toStringz("glCheckFramebufferStatusOES"));
glFramebufferTexture2DOES = cast(PFNGLFRAMEBUFFERTEXTURE2DOESPROC) eglGetProcAddress(toStringz("glFramebufferTexture2DOES"));

fboFunctionsAvailable = (glBindFramebufferOES != null)
&& (glDeleteFramebuffersOES != null)
&& (glGenFramebuffersOES != null)
//&& (glCheckFramebufferStatusOES != null)
&& (glFramebufferTexture2DOES != null);
}

return fboExtensionAvailable && fboFunctionsAvailable;
}
Then I use it like this:



glGenFramebuffersOES(1, &luminousFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, luminousFramebuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, luminousTexture, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);


The code is in D, but it should be understandable.


Ok, and how is luminousTexture created?
 
In this case like this:

Code:
    memset(data, 0, luminousTextureWidth * luminousTextureHeight * 4 * uint.sizeof);
    glGenTextures(1, &luminousTexture);
    glBindTexture(GL_TEXTURE_2D, luminousTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, luminousTextureWidth, luminousTextureHeight, 0,
		 GL_RGBA, GL_UNSIGNED_BYTE, data);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Data is a static buffer (can be dynamic).
 
In this case like this:

memset(data, 0, luminousTextureWidth * luminousTextureHeight * 4 * uint.sizeof);
glGenTextures(1, &luminousTexture);
glBindTexture(GL_TEXTURE_2D, luminousTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, luminousTextureWidth, luminousTextureHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Data is a static buffer (can be dynamic).
And when you create the FrameBuffer, the luminousTexture is attached or not (I think it's the last question)?
 
The texture is attached to the framebuffer using glFramebufferTexture2DOES - see the first example (the second part).

BTW this is all from my A7Xpg port, you can look at the whole code there.
 
Last edited by a moderator:
The texture is attached to the framebuffer using glFramebufferTexture2DOES - see the first example (the second part).


BTW this is all from my A7Xpg port, you can look at the whole code there.
I meant, do you glBindTexture(GL_TEXTURE_2D, 0); before creating FrameBuffer.

But I'll simply look in your code and try to have a working FBO. Thanks :)
 
I think the rotation-effect is way too strong. If at all it should be much more subtle!

Is it normal that the car is always braking when you release the throttle? For me that's how it is, but I would have expected the car to just roll and that you actively have to engage the brakes if you want to brake?
 
I think the rotation-effect is way too strong. If at all it should be much more subtle!

Is it normal that the car is always braking when you release the throttle? For me that's how it is, but I would have expected the car to just roll and that you actively have to engage the brakes if you want to brake?
I will try to render rotation effect parametrable in a future release.

About controls, with one are you using: A assume nub for throttle/brake?
 
Yes, I'm using the right nub for throttle/brake.

Thinking about the rotation: if it rotates real slow and maybe not as much this would already help. Slow rotation would have the neat side-effect that the longer you steer to one side, the further it would rotate. This should give a better illusion of "leaning into the curve". Probably rotating back would still have to be fast though, otherwise you're still tilted when going straight.
 
About the general bc_cat reinit issue, the API is rather broken that it doesn't allow you to free the buffers.. bc_cat from TI wiki frees old buffers automatically when new ones are created, but the one included with main pvr driver doesn't, for whatever reason. I guess the wiki behavior should be ported to the one included with main, otherwise it's not very usable.
Kernel update published, that part should be fixed now.
 
About the general bc_cat reinit issue, the API is rather broken that it doesn't allow you to free the buffers.. bc_cat from TI wiki frees old buffers automatically when new ones are created, but the one included with main pvr driver doesn't, for whatever reason. I guess the wiki behavior should be ported to the one included with main, otherwise it's not very usable.
Kernel update published, that part should be fixed now.
Yup. Tested and it worked! Thanks
 
So new release.

The tilt is less stong, and is disabled by default. Go to Video Option menu to activate it.

0.2.1.23

  • Improved a bit Streaming Texture init for GLES mode.
  • Tilt is now parametrable in the Video option menu (GLES mode only)

(there is hidden fps counter for the curious ones. open the appdata/cannonball/home/config.xml file and add <fps_counter>1</fps_counter> in the <video> section).
 
Last edited by a moderator:
The new tilt is great! It's no longer distracting when just changing lanes. In long turns you barely notice it's happening, but it really adds to the experience. Love it! :)
 
The new tilt is great! It's no longer distracting when just changing lanes. In long turns you barely notice it's happening, but it really adds to the experience. Love it! :)
Thanks!

Some Youtube of it could do some nice advertisement, if someone can do that.
 
Updated the C4A support to use the --cache parameter, so result are saved if offline (and uploaded at next upload of any score using Fusilli client)

0.2.1.24

  • Using Fusilli client from Ziz, with cached upload
 
Updated the fuzilli client to fix large cache issue

0.2.1.25

  • Updated Fusilli client from Ziz, with fixed cached upload for large cache
 
Back
Top