Sign in to follow this  
Boude

OpenPDN

Recommended Posts

Hello again everybody,

This is my third plugin, I hope you'll all enjoy it. This uses OpenGL to increase speed and the OpenTK to simplify things for me. Thanks go to Madjik, I couldn't have done this (not that I'm finished) without using his GenTree source as general structure.

The plugin can be found under Advanced > OpenPDN.

As the description states this plugin brings GLSL to PDN. GLSL is a C-based language used to write shaders. In my plugin I supply the user with the width, height and source of the surface. These are accessible in code through WIDTH, HEIGHT and SRC. WIDTH and HEIGHT are both int and SRC is a sampler2D.

Some example code:

void main(void)
{
float x = float(gl_FragCoord.x) / float(WIDTH);
float y = float(gl_FragCoord.y) / float(HEIGHT);
vec4 src = texture2D(SRC, vec2(x, y));
float xx = gl_FragCoord.x;
float yy = gl_FragCoord.y;
gl_FragColor = vec4(xx / float(WIDTH * 3), yy / float(HEIGHT * 3), 0, 1) + src;
} 

Something more complicated (it's a blur effect):

const int radius = 10;

void main(void)
{
float xAb = float(gl_FragCoord.x);
float yAb = float(gl_FragCoord.y);

vec4 color = vec4(0, 0, 0, 0);
int amount = 0;
for (int x = int(xAb - radius); x <= int(xAb + radius); x++)
{
	if ((x > 0) && (x < WIDTH))
	{
		for (int y = int(yAb - radius); y <= int(yAb + radius); y++)
		{
			if ((y > 0) && (y < HEIGHT))
			{
				float xRel = float(x) / float(WIDTH);
				float yRel = float(y) / float(HEIGHT);
				float dis = pow(pow(x - xAb, 2) + pow(y - yAb, 2), 0.5);
				if (dis <= radius)
				{
					float disInv = radius - dis;						
					vec4 current = texture2D(SRC, vec2(xRel, yRel));
					for (int i = 0; i < int(disInv); i++){
						color += current;
						amount++;
					}
				}
			}
		}
	}
}
gl_FragColor = color / amount;
}

And here is a motion blur:

float angle = 0;
const int length = 10;
const float step = 1; //WARNING: do not make this 0, an infinite loop on your GPU is NOT a good thing (my PC showed a blue screen and resetted itself)

void main(void)
{
float xAb = gl_FragCoord.x;
float yAb = gl_FragCoord.y;
vec4 color;
int amount = 0;
for (int i = 0; i * step < length; i++)
{
	float x = sin(angle) * i * step;
	float y = cos(angle) * i * step;
	float disAdj = length - pow(pow(x, 2) + pow(y, 2), 0.5);
	x += xAb;
	y += yAb;
	if ((x >= 0) && (x < WIDTH) && (y >= 0) && (y < HEIGHT))
	{
		color += texture2D(SRC, vec2(x / WIDTH, y / HEIGHT)) * disAdj;
		amount += int(disAdj);
	}
}
gl_FragColor = color / amount;	
}

Note: for this to work, you have to have the OpenTK.dll and the OpenTK.GLControl.dll in the Effects folder. (Included in the .zip file)

Download

Please send me your errors.

Update: Fixed error where PDN crashes the second time one startes OpenPDN. (Or so I think)

Update: Source image is now available. See example code for usage. Note when using texture2D() the coordinates are from 0 to 1.

Update: Simple blur effect added. (Another update in which I coded the radius slightly softer.)

Update: Real-time rendering works and I changed from a GameWindow (in my project I used one named "DrawWindow") to a GLControl, which means the window opening and closing is gone for good. Let us now remember the DrawWindow, rest in peace.

Update: Fixed source flipping issue (which was detected by Cookie, thanks)

Up next: some standard functions to do stuff (motion blur, maybe a fractal, Gaussian blur) and some blending operations, maybe a way to save functions. And possibly syntax-highlighting (and other UI stuff), for now Visual Studio 2010 has a decent GLSL highlighter.

Edited by Boude

Share this post


Link to post
Share on other sites

Cool! I have, in a long time, wanted to make GLSL shaders that could be run in PDN. I might try this later but I'm a bit busy with other things right now. Hope you solve the crashing issue and make it more stable.

Share this post


Link to post
Share on other sites

Request for this thread to be moved to the other plugins, please. Thanks in advance.

Edited by Boude

Share this post


Link to post
Share on other sites

@EER: Yes, the request was only made under the assumption there were no major bugs.

@Cookie: Could you send me the error log from PDN (if any) from when it crashed?

Fixed the source flipping issue, I flipped the source, because OpenGL needs it to be flipped, the only problem is I never flipped it back. So the second render time it was flipped again and the third time another time etc. So basically all I had to do was flip the source twice per render.

Edited by Boude

Share this post


Link to post
Share on other sites

Request for this thread to be moved to the other plugins, please. Thanks in advance.

Let's wait until it's a little more stable first ...

Share this post


Link to post
Share on other sites

@Cookie: Could you send me the error log from PDN (if any) from when it crashed?

No crash log, it just crashed.

Just tried the new version and after some time of editing the display driver stopped responding (scared me for a second) and it crashed again, still no crash log :(

Share this post


Link to post
Share on other sites

@Rick: As I said to EER, the request was only made under the assumption there were no more errors. As Cookies pointed out that assumption was wrong. Hence the request is no longer valid.

@Cookies: The new version wasn't supposed to help with the crash. Did you use anything specific? Or just run it a couple of times with simple code? BTW, sorry I used "Cookie" instead of using "Cookies", I didn't notice.

Edit:

The fragment shader stuff works differently then PDN with what's up and what's down. In OpenGL the coordinates (0, 0) are located on the left bottom. In PDN (0, 0) is the left top. Do you think I should flip the image to make (0, 0) the left top (going for the PDN standard) or keep it this way and sticking to the familiarity GLSL programmers (might) enjoy?

Edited by Boude

Share this post


Link to post
Share on other sites

No worries ...

How does it deal with large images? Say, larger than 4096x4096? (or, specifically, larger than the maximum texture size of the video card)

Share this post


Link to post
Share on other sites

I tried a 10000x10000, PDN froze, but with 5000x5000 it worked. First it started finishing (took time), then it started initializing (also longer then normal), but the rendering process took only a split second. Done with the blur effect from above on some clouds. My guess is I was too impatient with the 10000x10000. I wonder what happens in the finishing and initiating parts of the effect rendering cycle and how does my effect come in? Maybe I should move some code around to do the rendering at the correct time, note: it is an Effect, not PropertyBasedEffect. By the way, I want to take in no way credit for the rendering of the image and the compiling of the code, that's all OpenGL. All I did was call a couple of methods.

Edited by Boude

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this