Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Extending Gosu / Post processing effects for Ruby
- By jsb Date 2009-09-20 17:50
Here's my effort at porting mathias_' PostProcessing library from C++ to Ruby. Here is some example code:

require 'gosu'
require 'shader'

class GameWindow < Gosu::Window
  def initialize
    ...
   
    @blur = Shader.new(self, 'shader/radialblur.fs')
   
    @blur['BlurFactor'] = 0.15
    @blur['BrightFactor'] = 1.0
    @blur['origin_x'] = 0.5
    @blur['origin_y'] = 0.5
    @blur['passes'] = 16
  end
 
  def draw
    ...
   
    @blur.apply
  end
end


Unfortunately, there seem to be some bugs, possibly related to OS X. That's why I'd like you to try out some of the example scripts I've attached and post any errors along with your OS and Ruby version. I hope to be fixing those issues soon but atm I feel kinda clueless.
Attachment: gosu-shader.zip (9k)
- By deps Date 2009-09-20 19:55
This sounds awesome, but sadly I can't try it out. My ruby setup is a bit broken after upgrading to osx 10.6, and I have some problems reinstalling the ruby-opengl gem. I don't get any errors during the reinstall, but when I try to run one of the examples, it complains that it can't find a compatible gl.bundle, or something along those lines...
(Also, I had to add require 'rubygems' to the top of the example to run it. It looks like you don't have to. What's the secret? ;))
- By jlnr (dev) Date 2009-09-21 01:47
As a quick workaround, you can maybe try to run the examples with that arch thingie:

http://www.libgosu.org/cgi-bin/mwf/topic_show.pl?pid=1425#pid1425

Also, I guess Ruby 1.9 doesn't need the rubygems require anymore, but I also have to retype it every time, still being on 1.8.6 by default ;)
- By jsb Date 2009-09-21 07:03
I'm on Ruby 1.8.6 on Windows and I've never needed the require 'rubygems' for Gosu/OpenGL to work. As apparently everyone else does, I've added it to the examples now.
- By ? Date 2009-09-21 08:30
-AmIMeYet here-

It all depends on where you place your files..

I have my shared .rb's and .so as '<ruby lib dir>/site_ruby/1.9.1/file.ext'. If you use rubygems, they get placed as '<ruby lib dir>/gems/file.ext' or something.
You can also place them in the apps working directory ofcourse.

Everything I compile from source is automatically placed in site_ruby, and that's where I put those that aren't automagically placed (like Gosu, if I recall correctly) too.

Is this not the same as 1.8.6?.. I thought it was.. anyone willing to try? :D
- By deps Date 2009-09-21 11:13
Using arch I got test_pixelate to work, but the other two didn't. They got this error:

deps$ arch -i386 ruby test_multiple.rb
./shader.rb:60:in glUseProgram': invalid operation (Gl::Error)
  from ./shader.rb:60:in
[]='
  from ./shader.rb:59:in gl'
  from ./shader.rb:59:in
[]='
  from test_multiple.rb:34:in initialize'
  from test_multiple.rb:91:in
new'
  from test_multiple.rb:91

I'm on a macbook with intel graphics, so I'm not really surprised if something isn't supported. :P
Ruby 1.8.7
- By banister Date 2009-09-21 12:48
im on linux using ruby 1.9.1 and i get this error, for all examples:

$ ruby19 test_pixelate.rb
/home/john/ruby/tests/gosu-shader/shader.rb:87:in glTexImage2D': wrong argument type String (expected Struct) (TypeError)
  from /home/john/ruby/tests/gosu-shader/shader.rb:87:in
create_canvas'
  from /home/john/ruby/tests/gosu-shader/shader.rb:23:in initialize'
  from test_pixelate.rb:36:in
new'
  from test_pixelate.rb:36:in initialize'
  from test_pixelate.rb:79:in
new'
  from test_pixelate.rb:79:in `<main>'
- By adamsanderson Date 2009-09-22 23:20
Hey thanks for making this, I've really been wanting something along these lines.
- By adamsanderson Date 2009-09-23 15:17
@deps:  I'm on a macbook pro, on the stock ruby 1.8.7 with a GeForce 8600M GT and I get a similar results.  For what it's worth I needed to install the ruby-opengl gem to get it up and running.
- By jsb Date 2009-09-23 16:45
Thank you for your error reports so far. As my Macbook Pro will arrive in two days (yay :D), I'll hopefully be able to reproduce the bug and look into it then.

Interestingly, a friend of mine running Win XP with Ruby 1.8.6 installed through the one-click installer (like me) had no problems running all three examples. So, maybe it's the one-click installer's fault. On the other hand, I installed Ruby 1.9.1 on Win Vista along with fresh gosu and ruby-opengl Gems, and also had no problems.
- By erisdiscord Date 2009-09-23 17:06
Hey, this is theoretically totally awesome. OK, in practice it's awesome too, but I've got the same problem as deps above when running test_multiple.rb and  test_contrast.rb. test_pixelate.rb runs with no complaints.

My setup is Ruby 1.9.1 revision 24175 from MacPorts, ruby-opengl 0.60.1 (freshly updated just five minutes ago) and Mac OS X 10.6.1. Everything is compiled for x86_64.

I have no problems with Gosu and doing raw OpenGL calls has worked for me as well. I'm on a MacBook Pro with one of those fancy GPUs with, like, its memory and stuff, so I don't think the hardware should be a problem. Actually, OS X emulates unsupported calls on the less capable GPUs with dynamically loaded LLVM routines, so even there it shouldn't be a problem (except maybe poor performance).

Edited for formatting. My brain was in Markdown mode.
- By jsb Date 2009-09-26 16:31
Apparently, the shader files get compiled differently depending on the platform and bindings (C++ or Ruby). For example, on my Macbook Pro, I got the contrast shader to work after changing
vec4 color = texture2D(tex, gl_TexCoord[0]);
to
vec4 color = texture2D(tex, gl_TexCoord[0].xy);

For the radialblur shader, I needed to add some typecasts, that apparently worked implicitly before, i.e.:
float scale = 1.0 - BlurFactor * (float(i) / (passes - 1));
because passes is an int, needed to be changed to
float scale = 1.0 - BlurFactor * (float(i) / float(passes - 1));

I successfully tested the fixed shaders so far with Ruby 1.8.7 on my MPB with Snow Leopard, as well with Ruby 1.8.6 on Windows Vista. If you'd like to give it a try, you can download the updated attachment from my original post. I'm still very confused as why the shaders are compiled differently between platforms.
- By Wurstinator Date 2010-03-12 18:24
Hi,
is it possible to create something like Adobe Pixel Bender on the base of this?
For those who don't know: Pixel Bender is a tool for creating image effects in Adobe Flash.
You write a small script with certain parameters and your image will be rendered. For example "Invert RGB":

/*****************************************************************************
*
* Copyright (C) 2008 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE:  All information contained  herein is,  and remains the property of
* Adobe Systems Incorporated and its suppliers, if any.  The intellectual and
* technical  concepts  contained  herein  are  proprietary  to  Adobe Systems
* Incorporated  and  its suppliers  and may  be covered  by U.S.  and Foreign
* Patents, patents in process, and are protected by trade secret or copyright
* law.  Dissemination of this information or reproduction of this material is
* strictly forbidden  unless prior  written permission is obtained from Adobe
* Systems Incorporated.
*
*****************************************************************************/

<languageVersion: 1.0;>

// invertRGB: A simple example to demonstrate how to invert the RGB color
//            space.
kernel invertRGB
<   namespace : "AIF";
    vendor : "Adobe Systems, Inc.";
    version : 2;
    description : "Invert the Red, Green and Blue channels of an image"; >
{
    input image4 src;
    output float4 dst;
   
    // evaluatePixel(): The function of the filter that actually does the
    //                  processing of the image.  This function is called once
    //                  for each pixel of the output image.
    void
    evaluatePixel()
    {
        // Obtain the input pixel color
        float4 inputColor = sampleNearest(src, outCoord());

        // Calculate (1 - channel) for each of the RGB channels
        dst.rgb = float3(1.0, 1.0, 1.0) - inputColor.rgb;
       
        // set the alpha value equal to the alpha of the input
        dst.a = inputColor.a;
    }
}

I'd try to do this on my own but I don't know anything about OpenGL and I don't know a tutorial about it (in Ruby).
- By jlnr (dev) Date 2010-03-12 20:44
Yeah, I would saw from a quick glance that Adobe Pixel Bender is a thin layer on shader hardware.
- By Wurstinator Date 2010-03-12 21:35
So this means "yes"? :)
Is there a tutorial for opengl in gosu or do I have to wait for someone satisfying my wish? :)
- By jlnr (dev) Date 2010-03-13 03:23
Well, you could use the very library posted in this thread, the language for shaders is well-documented outside of Gosu (GLSL etc.). Gosu has an example for OpenGL integration in examples/OpenGLIntegration.rb though.
- By Wurstinator Date 2010-03-13 10:30
I know the OpenGL example but it is not a tutorial. There is not a single comment explaining OpenGL's functions and the online doc doesn't really help me.
- By jsb Date 2010-03-13 11:31
Hi,

actually, this is what the Post Processing effects are already using! If you take a look at the .fs files that come with the library, you'll see that all effects are described using a scripting language (apparently very similar to Adobe Pixel Bender) called GLSL. This enables you to create your own Post Processing effects. GLSL's syntax is C-like and fairly simple; I'm sure you'll find some good tutorials online or find out by toying around with the existing .fs scripts.
- By Wurstinator Date 2010-03-13 15:01
Okay... I tried a blur filter now but all I get is a screen full in black :/
uniform sampler2D tex;
uniform int radius;

void main(void)
{
  if (radius == 0) {
    gl_FragColor = texture2D(tex, gl_TexCoord[0]);
    return;
  }
  float x = gl_TexCoord[0].x;
  float y = gl_TexCoord[0].y;
  vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
  int i = 0;
  for (int n = int(x)-radius; n < (int(x)+radius); n++) {
    for (int m = int(y)-radius; m < (int(y)+radius); m++) {
      color += texture2D(tex, vec2(n, m));
      i++;
    }
  }
  gl_FragColor = color / i;
}

Where is my mistake?
- By jsb Date 2010-03-14 13:50
The Gosu pixel-related coordinates are not used in the shader programs. Rather, they are given as floats where (0.0, 0.0) is the bottom left and (1.0, 1.0) is the top right corner of the screen. If you want pixel-accurate operations, you'll need to convert between screen and shader coords. So, maybe you'll want to pass your screen dimensions to the shader program through unities, or just hard-code them in for better performance.
- By Wurstinator Date 2010-03-14 15:46
uniform sampler2D tex;
uniform float radius;
uniform float width;
uniform float height;

void main(void)
{
  if (radius == 0.0) {
    gl_FragColor = texture2D(tex, gl_TexCoord[0]);
    return;
  }
  float x = gl_TexCoord[0].x;
  float y = gl_TexCoord[0].y;
  vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
  float wradius = radius/width;
  float hradius = radius/height;
  int i = 0;
  for (float n = x-wradius; n < x+wradius; n++) {
    for (float m = y-hradius; m < y+hradius; m++) {
      color += texture2D(tex, vec2(n, m));
      i++;
    }
  }
  gl_FragColor = color / i;
}

I still have an error somewhere :(
- By jsb Date 2010-03-14 22:39
I think your error is that n and m are still incremented by whole number values. This code works for me:

uniform sampler2D tex;
uniform int radius;
uniform int width;
uniform int height;

void main(void) {
  vec4 color = 0.0;
  int i = 0;
  for(int x = -radius; x <= radius; x++) {
    for(int y = -radius; y <= radius; y++) {
      vec2 offset = vec2(float(x)/width, float(y)/height);
      color += texture2D(tex, gl_TexCoord[0] + offset);
      i++;
    }
  }
  gl_FragColor = color / i;
}
- By Wurstinator Date 2010-03-16 17:38
Thanks, it works :)
I think I can do some other filters on my own now... if I can't I'll ask you :p
One last question, is it possible to "shader" just a certain image and not the full screen?
- By jsb Date 2010-03-16 18:30

>is it possible to "shader" just a certain image and not the full screen?


Currently, no; it's on my ToDo. It is possible to layer shaders and Image.draw's, though, for example
- draw game scene
- apply post processing
- draw HUD (remains unaltered by the shader)
- - By youpi Date 2010-07-16 08:30
Hi! I've been trying out Gosu for a few days, and I'll proceed to bother you fine gentlemen with all the issues I'll encounter, starting with this one.
So, I've tried this script. Nifty! Pretty! Crashy :(

[WORKS] Mac OS X 10.6.4 Intel - Stock ruby 1.8 install
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]

[WORKS] Linux Jolicloud (Ubuntu-based) eeepc 1101HA - Ruby 1.9.0 from ubuntu repos
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]: Appears to work. (At 3 FPS, but the current state of GMA500 linux drivers is an unfunny joke, so it's normal).

[ERROR] Mac OS X 10.5.8 PPC - ruby built from source
ruby 1.9.1p378 (2010-01-10 revision 26273) [powerpc-darwin9.8.0]

$ ruby ./shader-testcase.rb
/Users/Arnaud/Dropbox/gosu-shader/shader.rb:85:in glTexImage2D': invalid value (Gl::Error)
  from /Users/Arnaud/Dropbox/gosu-shader/shader.rb:85:in
create_canvas'
  from /Users/Arnaud/Dropbox/gosu-shader/shader.rb:23:in initialize'
  from ./shader-testcase.rb:14:in
new'
  from ./shader-testcase.rb:14:in initialize'
  from ./shader-testcase.rb:30:in
new'
  from ./shader-testcase.rb:30:in <main>

[ERROR] Windows XP - Installer from official website
ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-mingw32]
same error:

C:\Documents and Settings\Owner\My Documents\My Dropbox\gosu-shader>ruby ./shade
r-testcase.rb
C:/Documents and Settings/Owner/My Documents/My Dropbox/gosu-shader/shader.rb:85
:in
glTexImage2D': invalid value (Gl::Error)
        from C:/Documents and Settings/Owner/My Documents/My Dropbox/gosu-shader
/shader.rb:85:in create_canvas'
        from C:/Documents and Settings/Owner/My Documents/My Dropbox/gosu-shader
/shader.rb:23:in
initialize'
        from ./shader-testcase.rb:14:in new'
        from ./shader-testcase.rb:14:in
initialize'
        from ./shader-testcase.rb:30:in new'
        from ./shader-testcase.rb:30:in
<main>'


Here is the minimal testcase I've used, hoping to isolate the bug:

# encoding: utf-8

begin
  require 'rubygems'
rescue
end
require 'gosu'
require 'shader'

class TestWindow < Gosu::Window
 
  def initialize
    super(400, 400, false)
    @blur = Shader.new(self, 'shader/radialblur.fs')
    @blur['BlurFactor'] = 0.15
    @blur['BrightFactor'] = 1.0
    @blur['origin_x'] = 0.5
    @blur['origin_y'] = 0.5
    @blur['passes'] = 16
  end
 
  def update
  end
 
  def draw
  end
 
end

TestWindow.new.show


I wanted to poke around to find a fix, but unfortunately I can't even begin to guess in which general direction to poke.
I hope someone will have a clue what's going wrong.

Another question about this script: what's the license?

Thanks!
Parent - - By jsb Date 2010-07-16 09:40
Hey, first of all, thanks for the extended test reports! To me, this sounds like some of your GPUs don't support non-power-of-two texture sizes. As the shader lib just generates a canvas texture the same size as the window, this could be the cause of Gl complaining.

Could you just add these lines somewhere to your test case:
puts Gl.extension_supported?("GL_ARB_texture_non_power_of_two")
puts Gl.version_supported?(2.0)

and check the output on those systems where it doesn't work?
Parent - - By youpi Date 2010-07-16 10:01
Running those statements in all the environments I described (including those that work, running them from the testcase or from irb) generally resulted in segfaults or in hangs...
But anyway, you were right: changing the window size to 256*256 make them throw a much more useful error: OpenGL version 2.0 is not available on this system (NotImplementedError).
Problem solved, then, thanks!

(BTW, about the usage terms for the script?)
Parent - By jsb Date 2010-07-16 10:07
The script is free to use without any need for attribution (didn't bother putting it under a license yet, I'll do that for the next version(TM), which then hopefully also checks for shader availability ;) )
Up Topic Gosu / Extending Gosu / Post processing effects for Ruby

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill