📄 joglrenderer.java
字号:
if (!supportsVBO())
return;
RendererRecord rendRecord = (RendererRecord) DisplaySystem
.getDisplaySystem().getCurrentContext().getRendererRecord();
VBOInfo vbo = g.getVBOInfo();
if (vbo.isVBOVertexEnabled() && vbo.getVBOVertexID() <= 0) {
if (g.getVertexBuffer() != null) {
Object vboid;
if ((vboid = vboMap.get(g.getVertexBuffer())) != null) {
vbo.setVBOVertexID(((Integer) vboid).intValue());
} else {
g.getVertexBuffer().rewind();
int vboID = rendRecord.makeVBOId();
vbo.setVBOVertexID(vboID);
vboMap.put(g.getVertexBuffer(), vboID);
// ensure no VBO is bound
rendRecord.invalidateVBO(); // make sure we set it...
rendRecord.setBoundVBO(vbo.getVBOVertexID());
gl.glBindBufferARB(
GL.GL_ARRAY_BUFFER_ARB, vbo
.getVBOVertexID());
gl.glBufferDataARB(
GL.GL_ARRAY_BUFFER_ARB, g
.getVertexBuffer().limit() * 4, g
.getVertexBuffer(),
GL.GL_STATIC_DRAW_ARB); // TODO Check <sizeInBytes>
}
}
}
if (g instanceof TriMesh) {
if (vbo.isVBOIndexEnabled() && vbo.getVBOIndexID() <= 0) {
TriMesh tb = (TriMesh) g;
if (tb.getIndexBuffer() != null) {
Object vboid;
if ((vboid = vboMap.get(tb.getIndexBuffer())) != null) {
vbo.setVBOIndexID(((Integer) vboid).intValue());
} else {
tb.getIndexBuffer().rewind();
int vboID = rendRecord.makeVBOId();
vbo.setVBOIndexID(vboID);
vboMap.put(tb.getIndexBuffer(), vboID);
rendRecord.invalidateVBO(); // make sure we set it...
rendRecord.setBoundElementVBO(vbo.getVBOIndexID());
gl
.glBufferDataARB(
GL.GL_ELEMENT_ARRAY_BUFFER_ARB,
tb.getIndexBuffer().limit() * 4,
tb.getIndexBuffer(),
GL.GL_STATIC_DRAW_ARB); // TODO Check <sizeInBytes>
}
}
}
}
if (vbo.isVBONormalEnabled() && vbo.getVBONormalID() <= 0) {
if (g.getNormalBuffer() != null) {
Object vboid;
if ((vboid = vboMap.get(g.getNormalBuffer())) != null) {
vbo.setVBONormalID(((Integer) vboid).intValue());
} else {
g.getNormalBuffer().rewind();
int vboID = rendRecord.makeVBOId();
vbo.setVBONormalID(vboID);
vboMap.put(g.getNormalBuffer(), vboID);
rendRecord.invalidateVBO(); // make sure we set it...
rendRecord.setBoundVBO(vbo.getVBONormalID());
gl.glBufferDataARB(
GL.GL_ARRAY_BUFFER_ARB, g
.getNormalBuffer().limit() * 4, g
.getNormalBuffer(),
GL.GL_STATIC_DRAW_ARB); // TODO Check <sizeInBytes>
}
}
}
if (vbo.isVBOColorEnabled() && vbo.getVBOColorID() <= 0) {
if (g.getColorBuffer() != null) {
Object vboid;
if ((vboid = vboMap.get(g.getColorBuffer())) != null) {
vbo.setVBOColorID(((Integer) vboid).intValue());
} else {
g.getColorBuffer().rewind();
int vboID = rendRecord.makeVBOId();
vbo.setVBOColorID(vboID);
vboMap.put(g.getColorBuffer(), vboID);
rendRecord.invalidateVBO(); // make sure we set it...
rendRecord.setBoundVBO(vbo.getVBOColorID());
gl.glBufferDataARB(
GL.GL_ARRAY_BUFFER_ARB, g
.getColorBuffer().limit() * 4, g
.getColorBuffer(),
GL.GL_STATIC_DRAW_ARB); // TODO Check <sizeInBytes>
}
}
}
if (supportsFogCoords && vbo.isVBOFogCoordsEnabled() && vbo.getVBOFogCoordsID() <= 0) {
if (g.getFogBuffer() != null) {
Object vboid;
if ((vboid = vboMap.get(g.getFogBuffer())) != null) {
vbo.setVBOFogCoordsID(((Integer) vboid).intValue());
} else {
g.getFogBuffer().rewind();
int vboID = rendRecord.makeVBOId();
vbo.setVBOFogCoordsID(vboID);
vboMap.put(g.getFogBuffer(), vboID);
rendRecord.invalidateVBO(); // make sure we set it...
rendRecord.setBoundVBO(vbo.getVBOFogCoordsID());
gl.glBufferDataARB(
GL.GL_ARRAY_BUFFER_ARB, g
.getFogBuffer().limit() * 4, g
.getFogBuffer(),
GL.GL_STATIC_DRAW_ARB); // TODO Check <sizeInBytes>
}
}
}
if (vbo.isVBOTextureEnabled()) {
for (int i = 0; i < g.getNumberOfUnits(); i++) {
if (vbo.getVBOTextureID(i) <= 0
&& g.getTextureCoords(i) != null) {
Object vboid;
TexCoords texC = g.getTextureCoords(i);
if ((vboid = vboMap.get(texC.coords)) != null) {
vbo.setVBOTextureID(i, ((Integer) vboid).intValue());
} else {
texC.coords.rewind();
int vboID = rendRecord.makeVBOId();
vbo.setVBOTextureID(i, vboID);
vboMap.put(texC.coords, vboID);
rendRecord.invalidateVBO(); // make sure we set it...
rendRecord.setBoundVBO(vbo.getVBOTextureID(i));
gl.glBufferDataARB(
GL.GL_ARRAY_BUFFER_ARB, texC.coords.limit() * 4, texC.coords,
GL.GL_STATIC_DRAW_ARB); // TODO Check <sizeInBytes>
}
}
}
}
}
/**
* <code>draw</code> renders a scene by calling the nodes
* <code>onDraw</code> method.
*
* @see com.jme.renderer.Renderer#draw(com.jme.scene.Spatial)
*/
public void draw(final Spatial s) {
if (camera != null)
camera.apply();
if (s != null) {
s.onDraw(this);
}
}
/**
* <code>draw</code> renders a text object using a predefined font.
*
* @see com.jme.renderer.Renderer#draw(com.jme.scene.Text)
*/
public void draw(Text t) {
if (font == null) {
font = new JOGLFont();
}
font.setColor(t.getTextColor());
applyStates(t.states, null);
if (Debug.stats) {
StatCollector.startStat(StatType.STAT_RENDER_TIMER);
}
font.print(this, t.getWorldTranslation().x, t
.getWorldTranslation().y, t.getWorldScale(), t.getText(), 0);
if (Debug.stats) {
StatCollector.endStat(StatType.STAT_RENDER_TIMER);
}
}
/**
* checkAndAdd is used to process the Spatial for the render queue.
* It's queue mode is checked, and it is added to the proper queue. If the
* queue mode is QUEUE_SKIP, false is returned.
*
* @return true if the Spatial was added to a queue, false otherwise.
*/
public boolean checkAndAdd(Spatial s) {
int rqMode = s.getRenderQueueMode();
if (rqMode != Renderer.QUEUE_SKIP) {
getQueue().addToQueue(s, rqMode);
return true;
}
return false;
}
/**
* Return true if the system running this supports VBO
*
* @return boolean true if VBO supported
*/
public boolean supportsVBO() {
return supportsVBO;
}
/**
* re-initializes the GL context for rendering of another piece of geometry.
*/
protected void postdrawGeometry(Geometry g) {
// Nothing to do here
}
/**
* <code>flush</code> tells opengl to send through all currently waiting
* commands in the buffer.
*/
public void flush() {
final GL gl = GLU.getCurrentGL();
gl.glFlush();
}
/**
* <code>finish</code> is similar to flush, however it blocks until all
* waiting OpenGL commands have been finished.
*/
public void finish() {
final GL gl = GLU.getCurrentGL();
gl.glFinish();
}
/**
* Prepares the GL Context for rendering this geometry. This involves
* initializing the VBO and obtaining the buffer data.
*
* @param g
* the geometry to process.
* @return true if VBO is used for indicis, false if not
*/
protected boolean predrawGeometry(Geometry g) {
final GL gl = GLU.getCurrentGL();
RenderContext<GLContext> context = display
.getCurrentContext();
RendererRecord rendRecord = (RendererRecord) context
.getRendererRecord();
VBOInfo vbo = !generatingDisplayList ? g.getVBOInfo() : null;
if (vbo != null && supportsVBO()) {
prepVBO(g);
}
indicesVBO = false;
// set up data to be sent to card
// first to go is vertices
int oldLimit = -1;
FloatBuffer vertices = g.getVertexBuffer();
if (vertices != null) {
oldLimit = vertices.limit();
// make sure only the necessary verts are sent through on old cards.
vertices.limit(g.getVertexCount() * 3);
}
if ((supportsVBO && vbo != null && vbo.getVBOVertexID() > 0)) { // use
// VBO
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
rendRecord.setBoundVBO(vbo.getVBOVertexID());
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
} else if (vertices == null) {
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
} else if (prevVerts != vertices) {
// verts have changed
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
// ensure no VBO is bound
if (supportsVBO)
rendRecord.setBoundVBO(0);
vertices.rewind();
gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertices); // TODO Check assumed <type> GL_FLOAT
}
if (oldLimit != -1)
vertices.limit(oldLimit);
prevVerts = vertices;
// apply fogging coordinate if support and the buffer is set for this
// tri mesh
if (supportsFogCoords) {
oldLimit = -1;
FloatBuffer fogCoords = g.getFogBuffer();
if (fogCoords != null) {
oldLimit = fogCoords.limit();
// make sure only the necessary verts are sent through on old cards.
fogCoords.limit(g.getVertexCount());
}
if ((supportsVBO && vbo != null && vbo.getVBOVertexID() > 0)) { // use
// VBO
gl.glEnableClientState(GL.GL_FOG_COORDINATE_ARRAY_EXT);
rendRecord.setBoundVBO(vbo.getVBOVertexID());
gl.glFogCoordPointerEXT(GL.GL_FLOAT, 0, 0);
} else if (fogCoords == null) {
gl.glDisableClientState(GL.GL_FOG_COORDINATE_ARRAY_EXT);
} else if (prevFogCoords != fogCoords) {
// fog coords have changed
gl.glEnableClientState(GL.GL_FOG_COORDINATE_ARRAY_EXT);
// ensure no VBO is bound
if (supportsVBO)
rendRecord.setBoundVBO(0);
fogCoords.rewind();
gl.glFogCoordPointerEXT(0, 0, g.getFogBuffer());
}
if (oldLimit != -1)
fogCoords.limit(oldLimit);
prevFogCoords = fogCoords;
}
if (g instanceof TriMesh) {
if ((supportsVBO && vbo != null && vbo.getVBOIndexID() > 0)) { // use VBO
indicesVBO = true;
rendRecord.setBoundElementVBO(vbo.getVBOIndexID());
} else if (supportsVBO) {
rendRecord.setBoundElementVBO(0);
}
}
Spatial.NormalsMode normMode = g.getNormalsMode();
if (normMode != Spatial.NormalsMode.Off) {
applyNormalMode(normMode, g);
FloatBuffer normals = g.getNormalBuffer();
oldLimit = -1;
if (normals != null) {
// make sure only the necessary normals are sent through on old
// cards.
oldLimit = normals.limit();
normals.limit(g.getVertexCount() * 3);
}
if ((supportsVBO && vbo != null && vbo.getVBONormalID() > 0)) { // use
// VBO
gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
rendRecord.setBoundVBO(vbo.getVBONormalID());
gl.glNormalPointer(GL.GL_FLOAT, 0, 0);
} else if (normals == null) {
gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
} else if (prevNorms != normals) {
// textures have changed
gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
// ensure no VBO is bound
if (supportsVBO)
rendRecord.setBoundVBO(0);
normals.rewind();
gl.glNormalPointer(GL.GL_FLOAT, 0, normals); // TODO Check assumed <type> GL_FLOAT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -