Author Topic: Projector Class Isn't Working  (Read 4807 times)

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Projector Class Isn't Working
« on: February 28, 2010, 12:38:13 am »
And the mirrorCamera is looking the right way! The following doesn't do anything other than paint the mirror's plane yellow:

Code: [Select]
Projector mirrorCamera = new Projector();
TextureManager.getInstance().addTexture("Mirror", new Texture(256, 256, Color.yellow));
TextureManager.getInstance().getTexture("Mirror").setProjector(mirrorCamera, true);

I'm just going to use the projector as a camera, render into an Image's graphics, then replace the texture on my mirror, or is that WAY too stupid (expensive) a method? But either way, as I understand it I would need this for the software renderer anyway.

Offline paulscode

  • double
  • *****
  • Posts: 863
    • View Profile
    • PaulsCode.Com
Re: Projector Class Isn't Working
« Reply #1 on: February 28, 2010, 01:29:08 am »
I'm just going to use the projector as a camera, render into an Image's graphics, then replace the texture on my mirror

I've found that adding/replacing textures in the TextureManager is very slow.  Another way might be to render onto an image as you mentioned, but use only one single Texture that you update each frame with an ITextureEffect (using java.awt.image.PixelGrabber).

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Projector Class Isn't Working
« Reply #2 on: February 28, 2010, 01:47:31 am »
Ooh, better, thanks a lot.

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Projector Class Isn't Working
« Reply #3 on: February 28, 2010, 04:32:11 am »
By the way, do you have any idea how much faster this might be (doesn't seem very fast)? Egon?

Also, is there any reason why PixelGrabber should be faster than BufferedImage's getRGB(int, int)?
« Last Edit: February 28, 2010, 05:38:27 am by AGP »

Offline paulscode

  • double
  • *****
  • Posts: 863
    • View Profile
    • PaulsCode.Com
Re: Projector Class Isn't Working
« Reply #4 on: February 28, 2010, 06:21:06 am »
Also, is there any reason why PixelGrabber should be faster than BufferedImage's getRGB(int, int)?
I guess you could try both to see which one is faster.  I don't think I ever used getRGB, so I'm not sure.  I've never used ITextureEffects like this for very large textures, so I don't know how well suited it is, anyway, since Java is so darn slow at drawing 2D graphics.  There is probably a better way to do this.

This highlights one of the most annoying things about Java IMO, which is its super-slow drawing speed of 2D graphics.  It's something that I've always taken for granted when programming games in c++, and has become a major headache for me since I started using Java.  Drawing 2D has been the main bottleneck of virtually every pure-java program I've written.  Perhaps I just haven't found the "right" way to do it.
« Last Edit: February 28, 2010, 06:48:24 am by paulscode »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Projector Class Isn't Working
« Reply #5 on: February 28, 2010, 08:10:58 pm »
I'm not sure, if the Projector really is what you want. If works only with hardware rendering anyway. Maybe FrameBuffer.setRenderTarget() is more like it?

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Projector Class Isn't Working
« Reply #6 on: February 28, 2010, 09:06:40 pm »
Ohh, I didn't see that one. So, two questions: is that a lot faster than what I did with BufferedImage and ITextureEffect (a nested loop that replaced, inside apply(int[], int[]), every pixel of the BufferedImage)? And how exactly is the Projector supposed to be used?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Projector Class Isn't Working
« Reply #7 on: February 28, 2010, 09:16:23 pm »
It should be faster, yes. Just give it a try. The Projector projects a texture onto polygons, i.e. it replaces the u/v-coordinates with dynamically generated ones that make the texture act like as if it was projected by a...well, by a projector. But as said, it's limited to the hardware renderers.

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Projector Class Isn't Working
« Reply #8 on: February 28, 2010, 09:19:32 pm »
What do I call, if not displayGLOnly() (which, by the way, just failed for me on the texture), to display in software?

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Projector Class Isn't Working
« Reply #9 on: February 28, 2010, 10:19:25 pm »
OK, to answer the question that Egon refused :-) you set, on a single buffer (I was using two before with my original solution), the render target draw on the texture, then remove it and draw on the screen.

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Projector Class Isn't Working
« Reply #10 on: February 28, 2010, 10:26:34 pm »
By the way, since I can't resize the FrameBuffer, it would be helpful to get a Primitives.getPlane(float width, float height), lest I get a distorted texture. Otherwise I see two options: using the blit method, which seems very slow, or writing a VertexController just to scale the plane. Honestly, the only thing that makes sense to me is to have the aforementioned getPlane(width, height in world units).
« Last Edit: February 28, 2010, 10:37:42 pm by AGP »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Projector Class Isn't Working
« Reply #11 on: March 01, 2010, 08:41:28 pm »
...it would be helpful to get a Primitives.getPlane(float width, float height), lest I get a distorted texture.
I see...until then, maybe the source of getPlane() helps. It shouldn't be too hard to add this feature.

Code: [Select]
public static Object3D getPlane(int quads, float scale) {
float startx = -scale * (float) quads / 2f;
float starty = startx;
float tx = 0f;
float ty = 0f;
float dtex = (1f / (float) quads);
Object3D obj = new Object3D(quads * quads * 2 + 8);
for (int i = 0; i < quads; i++) {
for (int p = 0; p < quads; p++) {
float dtx = tx + dtex;
float dty = ty + dtex;
if (dtx > 1f) {
dtx = 1f;
}
if (dty > 1f) {
dty = 1f;
}
obj.addTriangle(startx, starty, 0, tx, ty, startx, starty + scale, 0, tx, dty, startx + scale, starty, 0, dtx, ty);
obj.addTriangle(startx, starty + scale, 0, tx, dty, startx + scale, starty + scale, 0, dtx, dty, startx + scale, starty, 0, dtx, ty);
startx += scale;
tx += dtex;
}
starty += scale;
startx = -scale * quads / 2;
tx = 0;
ty += dtex;
}
return obj;
}