📄 lwjglpbuffertexturerenderer.java
字号:
initPbuffer();
}
// Override parent's last frustum test to avoid accidental incorrect
// cull
if (spat.getParent() != null)
spat.getParent().setLastFrustumIntersection(
Camera.FrustumIntersect.Intersects);
if (useDirectRender
&& tex.getRTTSource() != Texture.RenderToTextureType.Depth) {
// setup and render directly to a 2d texture.
pbuffer.releaseTexImage(Pbuffer.FRONT_LEFT_BUFFER);
activate();
switchCameraIn(doClear);
doDraw(spat);
deactivate();
switchCameraOut();
LWJGLTextureState.doTextureBind(tex.getTextureId(), 0, Texture.Type.TwoDimensional);
pbuffer.bindTexImage(Pbuffer.FRONT_LEFT_BUFFER);
} else {
// render and copy to a texture
activate();
switchCameraIn(doClear);
doDraw(spat);
switchCameraOut();
copyToTexture(tex, pBufferWidth, pBufferHeight);
deactivate();
}
} catch (Exception e) {
logger.logp(Level.SEVERE, this.getClass().toString(),
"render(Spatial, Texture)", "Exception", e);
}
}
// inherited docs
public void render(ArrayList<? extends Spatial> spats, ArrayList<Texture> texs) {
render(spats, texs, true);
}
public void render(ArrayList<? extends Spatial> spats, ArrayList<Texture> texs, boolean doClear) {
if (!isSupported) {
return;
}
// clear the current states since we are renderering into a new location
// and can not rely on states still being set.
try {
if (pbuffer.isBufferLost()) {
logger
.warning("PBuffer contents lost - will recreate the buffer");
deactivate();
pbuffer.destroy();
initPbuffer();
}
if (texs.size() == 1 && useDirectRender
&& texs.get(0).getRTTSource() != Texture.RenderToTextureType.Depth) {
// setup and render directly to a 2d texture.
LWJGLTextureState.doTextureBind(texs.get(0).getTextureId(), 0, Texture.Type.TwoDimensional);
activate();
switchCameraIn(doClear);
pbuffer.releaseTexImage(Pbuffer.FRONT_LEFT_BUFFER);
for (int x = 0, max = spats.size(); x < max; x++) {
Spatial spat = spats.get(x);
// Override parent's last frustum test to avoid accidental incorrect
// cull
if (spat.getParent() != null)
spat.getParent().setLastFrustumIntersection(
Camera.FrustumIntersect.Intersects);
doDraw(spat);
}
switchCameraOut();
deactivate();
pbuffer.bindTexImage(Pbuffer.FRONT_LEFT_BUFFER);
} else {
// render and copy to a texture
activate();
switchCameraIn(doClear);
for (int x = 0, max = spats.size(); x < max; x++) {
Spatial spat = spats.get(x);
// Override parent's last frustum test to avoid accidental incorrect
// cull
if (spat.getParent() != null)
spat.getParent().setLastFrustumIntersection(
Camera.FrustumIntersect.Intersects);
doDraw(spat);
}
switchCameraOut();
for (int i = 0; i < texs.size(); i++) {
copyToTexture(texs.get(i), pBufferWidth, pBufferHeight);
}
deactivate();
}
} catch (Exception e) {
logger.logp(Level.SEVERE, this.getClass().toString(),
"render(Spatial, Texture)", "Exception", e);
}
}
/**
* <code>copyToTexture</code> copies the pbuffer contents to
* the given Texture. What is copied is up to the Texture object's rttSource
* field.
*
* @param tex
* The Texture to copy into.
* @param width
* the width of the texture image
* @param height
* the height of the texture image
*/
public void copyToTexture(Texture tex, int width, int height) {
LWJGLTextureState.doTextureBind(tex.getTextureId(), 0, Texture.Type.TwoDimensional);
int source = GL11.GL_RGBA;
switch (tex.getRTTSource()) {
case RGBA:
case RGBA8:
break;
case RGB:
case RGB8:
source = GL11.GL_RGB;
break;
case Alpha:
case Alpha8:
source = GL11.GL_ALPHA;
break;
case Depth:
source = GL11.GL_DEPTH_COMPONENT;
break;
case Intensity:
case Intensity8:
source = GL11.GL_INTENSITY;
break;
case Luminance:
case Luminance8:
source = GL11.GL_LUMINANCE;
break;
case LuminanceAlpha:
case Luminance8Alpha8:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case Alpha4:
source = GL11.GL_ALPHA;
break;
case Alpha12:
source = GL11.GL_ALPHA;
break;
case Alpha16:
source = GL11.GL_ALPHA;
break;
case Luminance4:
source = GL11.GL_LUMINANCE;
break;
case Luminance12:
source = GL11.GL_LUMINANCE;
break;
case Luminance16:
source = GL11.GL_LUMINANCE;
break;
case Luminance4Alpha4:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case Luminance6Alpha2:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case Luminance12Alpha4:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case Luminance12Alpha12:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case Luminance16Alpha16:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case Intensity4:
source = GL11.GL_INTENSITY;
break;
case Intensity12:
source = GL11.GL_INTENSITY;
break;
case Intensity16:
source = GL11.GL_INTENSITY;
break;
case R3_G3_B2:
source = GL11.GL_RGB;
break;
case RGB4:
source = GL11.GL_RGB;
break;
case RGB5:
source = GL11.GL_RGB;
break;
case RGB10:
source = GL11.GL_RGB;
break;
case RGB12:
source = GL11.GL_RGB;
break;
case RGB16:
source = GL11.GL_RGB;
break;
case RGBA2:
source = GL11.GL_RGBA;
break;
case RGBA4:
source = GL11.GL_RGBA;
break;
case RGB5_A1:
source = GL11.GL_RGBA;
break;
case RGB10_A2:
source = GL11.GL_RGBA;
break;
case RGBA12:
source = GL11.GL_RGBA;
break;
case RGBA16:
source = GL11.GL_RGBA;
break;
case RGBA32F:
source = GL11.GL_RGBA;
break;
case RGB32F:
source = GL11.GL_RGB;
break;
case Alpha32F:
source = GL11.GL_ALPHA;
break;
case Intensity32F:
source = GL11.GL_INTENSITY;
break;
case Luminance32F:
source = GL11.GL_LUMINANCE;
break;
case LuminanceAlpha32F:
source = GL11.GL_LUMINANCE_ALPHA;
break;
case RGBA16F:
source = GL11.GL_RGBA;
break;
case RGB16F:
source = GL11.GL_RGB;
break;
case Alpha16F:
source = GL11.GL_ALPHA;
break;
case Intensity16F:
source = GL11.GL_INTENSITY;
break;
case Luminance16F:
source = GL11.GL_LUMINANCE;
break;
case LuminanceAlpha16F:
source = GL11.GL_LUMINANCE_ALPHA;
break;
}
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, source, 0, 0, width,
height, 0);
}
private Camera oldCamera;
private int oldWidth, oldHeight;
private RenderContext<?> oldContext;
private void switchCameraIn(boolean doClear) {
// grab non-rtt settings
oldCamera = parentRenderer.getCamera();
oldWidth = parentRenderer.getWidth();
oldHeight = parentRenderer.getHeight();
parentRenderer.setCamera(getCamera());
// swap to rtt settings
parentRenderer.getQueue().swapBuckets();
parentRenderer.reinit(pBufferWidth, pBufferHeight);
// clear the scene
if (doClear) {
GL11.glDisable(GL11.GL_SCISSOR_TEST);
parentRenderer.clearBuffers();
}
getCamera().update();
getCamera().apply();
}
private void switchCameraOut() {
parentRenderer.setCamera(oldCamera);
parentRenderer.reinit(oldWidth, oldHeight);
// back to the non rtt settings
parentRenderer.getQueue().swapBuckets();
oldCamera.update();
oldCamera.apply();
}
private void doDraw(Spatial spat) {
// do rtt scene render
spat.onDraw(parentRenderer);
parentRenderer.renderQueue();
}
private void initPbuffer() {
if (!isSupported) {
return;
}
try {
if (pbuffer != null) {
giveBackContext();
display.removeContext(pbuffer);
}
pbuffer = new Pbuffer(pBufferWidth, pBufferHeight, new PixelFormat(
bpp, alpha, depth, stencil, samples), texture, null);
} catch (Exception e) {
logger.logp(Level.SEVERE, this.getClass().toString(), "initPbuffer()", "Exception", e);
if (texture != null && useDirectRender) {
logger.warning("Your card claims to support Render to Texture but fails to enact it. Updating your driver might solve this problem.");
logger.warning("Attempting to fall back to Copy Texture.");
texture = null;
useDirectRender = false;
initPbuffer();
return;
}
logger.log(Level.WARNING, "Failed to create Pbuffer.", e);
isSupported = false;
return;
}
try {
activate();
pBufferWidth = pbuffer.getWidth();
pBufferHeight = pbuffer.getHeight();
GL11.glClearColor(backgroundColor.r, backgroundColor.g,
backgroundColor.b, backgroundColor.a);
if (camera == null)
initCamera();
camera.update();
deactivate();
} catch( Exception e ) {
logger.log(Level.WARNING, "Failed to initialize created Pbuffer.",
e);
isSupported = false;
return;
}
}
private void activate() {
if (!isSupported) {
return;
}
if (active == 0) {
try {
oldContext = display.getCurrentContext();
pbuffer.makeCurrent();
display.switchContext(pbuffer);
} catch (LWJGLException e) {
logger.logp(Level.SEVERE, this.getClass().toString(), "activate()", "Exception",
e);
throw new JmeException();
}
}
active++;
}
private void deactivate() {
if (!isSupported) {
return;
}
if (active == 1) {
try {
if (!useDirectRender)
display.getCurrentContext().invalidateStates();
giveBackContext();
display.getRenderer().reset();
} catch (LWJGLException e) {
logger.logp(Level.SEVERE, this.getClass().toString(),
"deactivate()", "Exception", e);
throw new JmeException();
}
}
active--;
}
private void giveBackContext() throws LWJGLException {
if (!headless && Display.isCreated()) {
Display.makeCurrent();
display.switchContext(display);
} else if (oldContext.getContextHolder() instanceof AWTGLCanvas) {
((AWTGLCanvas)oldContext.getContextHolder()).makeCurrent();
display.switchContext(oldContext.getContextHolder());
} else if (display.getHeadlessDisplay() != null) {
display.getHeadlessDisplay().makeCurrent();
display.switchContext(display.getHeadlessDisplay());
}
}
private void initCamera() {
if (!isSupported) {
return;
}
logger.info("Init RTT camera");
camera = new LWJGLCamera(pBufferWidth, pBufferHeight, false);
camera.setFrustum(1.0f, 1000.0f, -0.50f, 0.50f, 0.50f, -0.50f);
Vector3f loc = new Vector3f(0.0f, 0.0f, 0.0f);
Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
camera.setFrame(loc, left, up, dir);
}
public void cleanup() {
if (!isSupported) {
return;
}
display.removeContext(pbuffer);
pbuffer.destroy();
}
public int getWidth() {
return pBufferWidth;
}
public int getHeight() {
return pBufferHeight;
}
public void setMultipleTargets(boolean force) {
if (force) {
logger.info("Copy Texture Pbuffer used!");
useDirectRender = false;
texture = null;
initPbuffer();
} else {
if ((caps & Pbuffer.RENDER_TEXTURE_SUPPORTED) != 0) {
logger.info("Render to Texture Pbuffer supported!");
if (texture == null) {
logger.info("No RenderTexture used in init, falling back to Copy Texture PBuffer.");
useDirectRender = false;
} else {
useDirectRender = true;
}
} else {
logger.info("Copy Texture Pbuffer supported!");
texture = null;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -