http://geeks.ms/blogs/jcanton/archive/2011/02/06/occlusion-culling.aspx
Hacía tiempo que no escribía y me alegra que el regreso sea con un
tema tan interesante como el Occlusion Culling. Esta técnica podríamos
clasificarla dentro de las técnicas de visibilidad para mejorar el
rendimiento del render, y se suele usar junto a muchas otras técnicas de
visibilidad conocidas, como el frustum culling o el back-face culling.
Back-face Culling:
En esta técnica el objetivo es detectar cuales son las caras o
polígonos de un objeto que no serán vistos desde la posición actual de
la cámara (no se usará con objetos transparentes). De forma que dichas
caras no serán dibujadas y por lo tanto reduciremos el coste en tiempo
del render, sobre todo para objetos complejos donde podamos descartar
gran cantidad de polígonos.
¿Y cómo funciona?, se obtiene la
normal de una cara la cual puede tenerse ya almacenada tras la carga del
modelo o se puede calcular usando el producto vectorial de dos aristas
de la cara, después estudiaremos el signo del producto escalar entre
dicha normal ( N ) y el vector de vista del observador ( L ), si el
signo es “=” ó “> 0” significa que el ángulo formado por estos
vectores es mayor o igual a 90º, lo que indicará que no será visible al
observador y podremos descartar el polígono
Anuncio
miércoles, 3 de octubre de 2012
Java 2D: Hardware Accelerating - Part 1 - Volatile Images
http://www.javalobby.org/java/forums/m91823967.html
Java 1.4 introduced support for hardware acceleration in Java 2D functionality. Hardware acceleration is great to have, no question - but effectively using the
I'm going to assume that readers of this tip are familiar with at least the concept of double-buffering - if you aren't, please read here . In short, double buffering is a technique of deferring the rendering process to an 'offscreen' buffer, and then quickly copying that buffer to the onscreen device, which gives the illusion of higher performance (by making the onscreen rendering smoother). To simply produce a standard double buffer (not hardware accelerated), your code may look something like this:
This sort of 'double-buffer' situation is the perfect case for hardware acceleration. The question becomes, however, how do you utilize classes such as the
Whew - things are getting complicated. Long story short, however, volatile images are just as their name suggests - temperamental. Volatile images can be considered to represent an image in non-standard memory (e.g. video card memory). This makes them reliant on an underlying hardware feature (the video card) that may or may not be the active 'weapon of choice' at all times, and as such the image may or may not apply (it represents memory in a video card not being used). This is specifically why the
In addition to the foreign 'validate' check, we also have that nasty (and rare) use of a
Stay tuned, as tomorrow I will show how to hide some of this code craziness by using the
Java 1.4 introduced support for hardware acceleration in Java 2D functionality. Hardware acceleration is great to have, no question - but effectively using the
java.awt.image.VolatileImage
class is at least bit more complicated than using a
traditional 'buffered image' format. The details of working with this
low-level 'hardware acceleration' is only really important if you are
doing complex Java 2D rendering on your own. If you are only working
with pre-built widgets/components in Swing for instance, most of this
tip isn't really relevant. This tip is very helpful, however, for people
working with 2D game programming in Java, or perhaps someone working on
a graphics-intensive GUI such as charts and diagrams.
I'm going to assume that readers of this tip are familiar with at least the concept of double-buffering - if you aren't, please read here . In short, double buffering is a technique of deferring the rendering process to an 'offscreen' buffer, and then quickly copying that buffer to the onscreen device, which gives the illusion of higher performance (by making the onscreen rendering smoother). To simply produce a standard double buffer (not hardware accelerated), your code may look something like this:
// other classes may be extended - canvas is a common selection however. public class CustomGUI extends Canvas { private Image offscreenImage; private Graphics offscreenGraphics; private Dimension offscreenDimension; // ... public void paint(Graphics g) { Dimension currentSize = getSize(); if(offscreenImage == null || !currentSize.equals(offscreenDimension)) { // call the 'java.awt.Component.createImage(...)' method to get an // image offscreenImage = createImage(currentSize.width, currentSize.height); offscreenGraphics = offscreenImage.getGraphics(); offscreenDimension = currentSize; } // rendering code here (use offscreenGraphics 'Graphics' object) // this algorithm assumes the background will be re-filled because it // reuses the image object (otherwise artifacts will // remain from previous renderings) offscreenGraphics.setColor(Color.WHITE); offscreenGraphics.fillRect(0, 0, offscreenDimension.width, offscreenDimension.height); offscreenGraphics.setColor(Color.BLACK); offscreenGraphics.drawLine(0, 0, 10, 10); // arbitrary rendering logic // paint back buffer to main graphics g.drawImage(offscreenImage, 0, 0, this); } public void update(Graphics g) { paint(g); } }
This sort of 'double-buffer' situation is the perfect case for hardware acceleration. The question becomes, however, how do you utilize classes such as the
java.awt.image.VolatileImage
class to accelerate this code? Well, adapted from the Javadocs of
VolatileImage
and the contents of
this Java whitepaper on volatile images
(which I highly recommend you read for a more thorough
understanding) - here is a new version of the same class above that uses
volatile images for rendering - don't worry, I will take a stab at
explaining the 'wierdness' after:
// other classes may be extended - canvas is a common selection however. public class CustomGUI extends Canvas { private VolatileImage volatileImg; // ... public void paint(Graphics g) { // create the hardware accelerated image. createBackBuffer(); // Main rendering loop. Volatile images may lose their contents. // This loop will continually render to (and produce if neccessary) volatile images // until the rendering was completed successfully. do { // Validate the volatile image for the graphics configuration of this // component. If the volatile image doesn't apply for this graphics configuration // (in other words, the hardware acceleration doesn't apply for the new device) // then we need to re-create it. GraphicsConfiguration gc = this.getGraphicsConfiguration(); int valCode = volatileImg.validate(gc); // This means the device doesn't match up to this hardware accelerated image. if(valCode==VolatileImage.IMAGE_INCOMPATIBLE){ createBackBuffer(); // recreate the hardware accelerated image. } Graphics offscreenGraphics = volatileImg.getGraphics(); offscreenGraphics.setColor(Color.WHITE); offscreenGraphics.fillRect(0, 0, getWidth(), getHeight()); offscreenGraphics.setColor(Color.BLACK); offscreenGraphics.drawLine(0, 0, 10, 10); // arbitrary rendering logic // paint back buffer to main graphics g.drawImage(volatileImg, 0, 0, this); // Test if content is lost } while(volatileImg.contentsLost()); } // This method produces a new volatile image. private void createBackBuffer() { GraphicsConfiguration gc = getGraphicsConfiguration(); volatileImg = gc.createCompatibleVolatileImage(getWidth(), getHeight()); } public void update(Graphics g) { paint(g); } }
Whew - things are getting complicated. Long story short, however, volatile images are just as their name suggests - temperamental. Volatile images can be considered to represent an image in non-standard memory (e.g. video card memory). This makes them reliant on an underlying hardware feature (the video card) that may or may not be the active 'weapon of choice' at all times, and as such the image may or may not apply (it represents memory in a video card not being used). This is specifically why the
VolatileImage.IMAGE_INCOMPATIBLE
check is performed. We ask the volatile image to validate itself
against the graphics configuration for the current component (remember
the graphics configuration represents, at its core, the destination
'device' of our component), and if it doesn't match, we reproduce the
volatile image for the current graphics configuration (current video
card for instance).
In addition to the foreign 'validate' check, we also have that nasty (and rare) use of a
do-while
loop. There are two reasons that all of this logic is wrapped in the
do-while
loop. First, after we have begun rendering to the volatile
image, the image may once again become incompatible. In this case, the
contentsLost()
method will return true to let us know that something went
wrong. Second, certain platforms (I won't name names) allow for a case
where video memory may be 'lost' (*poof*! where'd it go?), and as such
requires that you re-write any data to that block of memory. In these
cases the 'valCode' returned from the
VolatileImage.validate(...)
method will actually be
VolatileImage.IMAGE_RESTORED
(there are three results - IMAGE_OK, IMAGE_RESTORED,
IMAGE_INCOMPATIBLE). The way the code is structured above, however, this
return-type doesn't need to be handled explicitly. In general,
VolatileImage.contentsLost()
returns true if the contents of the image have been lost for one of these reasons
since the last call to
VolatileImage.validate(...)
was performed. Because of that distinction I just
emphasized, our code works rather simply by performing two validates
each loop: the call to
VolatileImage.validate()
before
our rendering logic (to ensure our image is in good shape to use), and then a call to
VolatileImage.contentsLost()
after
our rendering logic to determine if the image stayed happy since we
last called validate (which implies all of our rendering logic since we
called validate worked as expected).
Stay tuned, as tomorrow I will show how to hide some of this code craziness by using the
java.awt.image.BufferStrategy
class.
VolatileImage
http://www.java-gaming.org/index.php/topic,7045.
http://stackoverflow.com/questions/2684123/java-volatileimage-slower-than-bufferedimage
http://www.javalobby.org/java/forums/m91823967.html
https://deim.urv.cat/~pfc/docs/pfc852/d1238664969.pdf
http://singletechgames.com/2008/11/20/3-a-full-screen-exclusive-mode-fsem-worm-part-1/
http://singletechgames.com/category/java/killer-game-programming-in-java/
http://www.coderanch.com/t/346138/GUI/java/BufferedImage-versus-VolatileImage
http://content.gpwiki.org/index.php/Java:Tutorials:VolatileImage
http://www.oracle.com/technetwork/articles/javase/index-141909.html
http://www.java.net/pub/au/78?page=3
http://www.javahispano.org/antiguo_javahispano_org/2003/9/17/introduccion-al-api-volatileimage.html
http://www.exampledepot.com/egs/java.awt.image/VolImage.html
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/VolatileImage.html
http://webcache.googleusercontent.com/search?q=cache:r_ZKdfwidcYJ:docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/VolatileImage.html+&cd=1&hl=es&ct=clnk&gl=es
http://www.java.net/node/703840
http://www.java.net/node/662985
OTROS ENLACES DE JAVA
http://www.docjar.org/docs/api/java/awt/GraphicsConfiguration.html
http://www.docjar.org/docs/api/java/awt/Canvas.html
http://stackoverflow.com/questions/2684123/java-volatileimage-slower-than-bufferedimage
http://www.javalobby.org/java/forums/m91823967.html
https://deim.urv.cat/~pfc/docs/pfc852/d1238664969.pdf
http://singletechgames.com/2008/11/20/3-a-full-screen-exclusive-mode-fsem-worm-part-1/
http://singletechgames.com/category/java/killer-game-programming-in-java/
http://www.coderanch.com/t/346138/GUI/java/BufferedImage-versus-VolatileImage
http://content.gpwiki.org/index.php/Java:Tutorials:VolatileImage
http://www.oracle.com/technetwork/articles/javase/index-141909.html
http://www.java.net/pub/au/78?page=3
http://www.javahispano.org/antiguo_javahispano_org/2003/9/17/introduccion-al-api-volatileimage.html
http://www.exampledepot.com/egs/java.awt.image/VolImage.html
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/VolatileImage.html
http://webcache.googleusercontent.com/search?q=cache:r_ZKdfwidcYJ:docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/VolatileImage.html+&cd=1&hl=es&ct=clnk&gl=es
http://www.java.net/node/703840
http://www.java.net/node/662985
OTROS ENLACES DE JAVA
http://www.docjar.org/docs/api/java/awt/GraphicsConfiguration.html
http://www.docjar.org/docs/api/java/awt/Canvas.html
Gráficos con Java 2D
http://www.programacion.com/articulo/graficos_con_java_2d_111/1
***********************************************
HABLA DE MUCHAS COSAS MUY INTERESANTE
***********************************************
***********************************************
HABLA DE MUCHAS COSAS MUY INTERESANTE
***********************************************
OpenGL para Android para todos
http://www.muchoandroid.com.ar/2012/05/opengl-en-android-para-todos.html
En este primer post vamos a aprender a manejar los conceptos básicos de una de las librerías graficas más utilizadas, OpenGL.
Luego iremos haciendo cosas un poco más complejas, hasta llegar a
gráficos en 3D y sus respectivas operaciones, pero primero lo primero.
Lo primero que debes conocer antes de empezar a graficar con OpenGL, son las clases a utilizar, y son:
- GLSurfaceView, la clase que te permite escribir las aplicaciones con OpenGL
- GLSurfaceView.Renderer, es una interfaz de renderizado genérica donde escribirás el código de lo que quieras que se dibuje.
Suscribirse a:
Entradas (Atom)