Projector Class Isn't Working

Started by AGP, February 28, 2010, 12:38:13 AM

Previous topic - Next topic

AGP

And the mirrorCamera is looking the right way! The following doesn't do anything other than paint the mirror's plane yellow:

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.

paulscode

Quote from: AGP on February 28, 2010, 12:38:13 AMI'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).

AGP


AGP

#3
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)?

paulscode

#4
Quote from: AGP on February 28, 2010, 04:32:11 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.

EgonOlsen

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?

AGP

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?

EgonOlsen

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.

AGP

What do I call, if not displayGLOnly() (which, by the way, just failed for me on the texture), to display in software?

AGP

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.

AGP

#10
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).

EgonOlsen

Quote from: AGP on February 28, 2010, 10:26:34 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.


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;
}