/* * $RCSfile$ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision$ * $Date$ * $State$ */ #include "StdAfx.h" #include "D3dDisplayList.hpp" D3dDisplayList::D3dDisplayList() { } D3dDisplayList::~D3dDisplayList() { for (ITER_LPD3DVERTEXBUFFER p = vBufferVec.begin(); p != vBufferVec.end(); p++) { SafeDelete(*p); } vBufferVec.empty(); } VOID D3dDisplayList::render(D3dCtx *d3dCtx) { for (ITER_LPD3DVERTEXBUFFER p = vBufferVec.begin(); p != vBufferVec.end(); p++) { (*p)->render(d3dCtx); } } VOID D3dDisplayList::add(LPD3DVERTEXBUFFER vbuffer) { vBufferVec.push_back(vbuffer); } BOOL D3dDisplayList::isQuad(LPD3DVERTEXBUFFER p) { return (!p->isIndexPrimitive && (p->indexBuffer != NULL)); } VOID D3dDisplayList::optimize(D3dCtx *d3dCtx) { D3dVertexBufferVector vCloneBufferVec; D3dVertexBuffer **r = &(*vBufferVec.begin()); for (; r != &(*vBufferVec.end()); r++) { vCloneBufferVec.push_back(*r); } vBufferVec.erase(vBufferVec.begin(), vBufferVec.end()); D3dVertexBuffer **vbegin = &(*vCloneBufferVec.begin()); D3dVertexBuffer **vend = &(*vCloneBufferVec.end()); D3dVertexBuffer **q = vbegin; D3dVertexBuffer **p; int primitiveType, vcounts, climit; int indexCounts = 0; BOOL merge; LPD3DVERTEXBUFFER mergedVB; BOOL isPointFlagUsed; DWORD vertexFormat; BOOL isIndexPrimitive; BOOL quadFlag; while (q != vend) { primitiveType = (*q)->primitiveType; climit = (*q)->maxVertexLimit; vcounts = (*q)->vcount; isPointFlagUsed = (*q)->isPointFlagUsed; vertexFormat = (*q)->vertexFormat; isIndexPrimitive = (*q)->isIndexPrimitive; quadFlag = isQuad(*q); if ((*q)->indexBuffer != NULL) { indexCounts = (*q)->indexCount; } merge = false; p = q + 1; while (p != vend) { if (((*p)->primitiveType == primitiveType) && ((*p)->vertexFormat == vertexFormat) && ((*p)->isIndexPrimitive == isIndexPrimitive) && (isQuad(*p) == quadFlag) && ((*p)->isPointFlagUsed == isPointFlagUsed) && // This means Mutliple VBs already use ((*p)->totalVertexCount == (*p)->vcount)) { vcounts += (*p)->totalVertexCount; if ((*p)->indexBuffer != NULL) { indexCounts += (*p)->totalIndexCount; } if ((vcounts > climit) || (indexCounts > climit)) { break; } p++; merge = true; } else { break; } } if (merge) { mergedVB = createMergedVB(d3dCtx, q, p, vcounts, indexCounts); if (mergedVB != NULL) { for (r = q; r != p; r++) { SafeDelete(*r); } vBufferVec.push_back(mergedVB); } else { for (r = q; r != p; r++) { vBufferVec.push_back(*r); } } } else { vBufferVec.push_back(*q); } q = p; } vCloneBufferVec.erase(vCloneBufferVec.begin(), vCloneBufferVec.end()); } LPD3DVERTEXBUFFER D3dDisplayList::createMergedVB(D3dCtx *d3dCtx, D3dVertexBuffer **vstart, D3dVertexBuffer **vend, DWORD vcount, DWORD indexCount) { LPDIRECT3DDEVICE9 device = d3dCtx->pDevice; D3dVertexBuffer **r; UINT i; HRESULT hr; LPD3DVERTEXBUFFER vb = new D3dVertexBuffer(); vb->primitiveType = (*vstart)->primitiveType; vb->isIndexPrimitive = (*vstart)->isIndexPrimitive; vb->isPointFlagUsed = (*vstart)->isPointFlagUsed; vb->vertexFormat = (*vstart)->vertexFormat; vb->stride = (*vstart)->stride; vb->ctx = (*vstart)->ctx; vb->vcount = vb->totalVertexCount = vcount; vb->indexCount = vb->totalIndexCount = indexCount; vb->maxVertexLimit = (*vstart)->maxVertexLimit; if (!vb->isPointFlagUsed) { hr = device->CreateVertexBuffer(vb->stride*vcount, D3DUSAGE_WRITEONLY, vb->vertexFormat, D3DPOOL_DEFAULT, &vb->buffer, NULL); } else { hr = device->CreateVertexBuffer(vb->stride*vcount, D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS, vb->vertexFormat, D3DPOOL_DEFAULT, &vb->buffer, NULL); } if (FAILED(hr)) { return NULL; } BYTE *bdst = NULL; WORD *wdst = NULL; UINT *idst = NULL; hr = vb->buffer->Lock(0, 0,(VOID**) &bdst , 0); if (FAILED(hr)) { SafeRelease(vb->buffer); return NULL; } if (indexCount > 0) { if (indexCount < 0xffff) { hr = device->CreateIndexBuffer(indexCount*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &vb->indexBuffer, NULL); } else { hr = device->CreateIndexBuffer(indexCount*sizeof(UINT), D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &vb->indexBuffer, NULL); } if (FAILED(hr)) { vb->buffer->Unlock(); SafeRelease(vb->buffer); return NULL; } if (indexCount <= 0xffff) { hr = vb->indexBuffer->Lock(0, 0,(VOID**) &wdst, 0); } else { hr = vb->indexBuffer->Lock(0, 0,(VOID**) &idst, 0); } if (FAILED(hr)) { vb->buffer->Unlock(); SafeRelease(vb->buffer); SafeRelease(vb->indexBuffer); return NULL; } } BYTE *bsrc = NULL; WORD *wsrc = NULL; UINT *isrc = NULL; UINT offset = 0; DWORD len; BOOL stripType = true; if ((vb->primitiveType == D3DPT_POINTLIST) || (vb->primitiveType == D3DPT_LINELIST) || (vb->primitiveType == D3DPT_TRIANGLELIST)) { vb->numVertices = new USHORT[1]; if (indexCount <= 0) { vb->numVertices[0] = vcount; } else { vb->numVertices[0] = indexCount; } vb->numVerticesLen = 1; vb->stripLen = 1; stripType = false; } for (r = vstart; r != vend; r++) { hr = (*r)->buffer->Lock(0, 0,(VOID**) &bsrc, 0); if (FAILED(hr)) { vb->buffer->Unlock(); if (indexCount > 0) { vb->indexBuffer->Unlock(); } SafeRelease(vb->buffer); SafeRelease(vb->indexBuffer); return NULL; } if (indexCount > 0) { if (indexCount <= 0xffff) { hr = (*r)->indexBuffer->Lock(0, 0, (VOID**)&wsrc, 0); } else { hr = (*r)->indexBuffer->Lock(0, 0,(VOID**) &isrc, 0); } if (FAILED(hr)) { (*r)->buffer->Unlock(); vb->buffer->Unlock(); SafeRelease(vb->buffer); SafeRelease(vb->indexBuffer); return NULL; } } len = (*r)->vcount*(*r)->stride; CopyMemory(bdst, bsrc, len); if (stripType) { vb->appendStrides((*r)->stripLen, (*r)->numVertices); } if (indexCount > 0) { if (wdst != NULL) { if (wsrc != NULL) { for (i=0; i < (*r)->indexCount; i++) { *wdst++ = offset + *wsrc++; } } else { // should not happen printf("[Java3D] Error in merging index vertex buffer\n"); } } else { if (wsrc != NULL) { for (i=0; i < (*r)->indexCount; i++) { *idst++ = offset + *wsrc++; } } else { for (i=0; i < (*r)->indexCount; i++) { *idst++ = offset + *isrc++; } } } offset += (*r)->vcount; } bdst += len; (*r)->buffer->Unlock(); if (indexCount > 0) { (*r)->indexBuffer->Unlock(); wsrc = NULL; isrc = NULL; } } vb->buffer->Unlock(); if (indexCount > 0) { vb->indexBuffer->Unlock(); } if (vb->isIndexPrimitive && (indexCount <= 0)) { // QUAD is used, adjust size of index createQuadIndices(d3dCtx, vcount); } for (i=0; i < D3DDP_MAXTEXCOORD; i++) { vb->texCoordPosition[i] = -9999; } if (debug) { int n = 0; for (r = vstart; r != vend; r++) { n++; } printf("Merge %d VB with primitiveType %d, vcount %d, indexCount %d\n", n, vb->primitiveType, vcount, indexCount); } return vb; } /a> 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/**
* Copyright 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package jogamp.graph.curve.opengl;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLException;
import jogamp.graph.curve.opengl.shader.AttributeNames;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
public class RegionRendererImpl01 extends RegionRenderer {
public RegionRendererImpl01(RenderState rs, int renderModes) {
super(rs, renderModes);
}
@Override
protected boolean initShaderProgram(GL2ES2 gl) {
final ShaderState st = rs.getShaderState();
final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RegionRendererImpl01.class, "shader",
"shader/bin", getVertexShaderName(), true);
final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RegionRendererImpl01.class, "shader",
"shader/bin", getFragmentShaderName(), true);
rsVp.defaultShaderCustomization(gl, true, true);
// rsFp.defaultShaderCustomization(gl, true, true);
int pos = rsFp.addGLSLVersion(gl);
if( gl.isGLES() ) {
pos = rsFp.insertShaderSource(0, pos, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE));
}
final String rsFpDefPrecision = getFragmentShaderPrecision(gl);
if( null != rsFpDefPrecision ) {
rsFp.insertShaderSource(0, pos, rsFpDefPrecision);
}
final ShaderProgram sp = new ShaderProgram();
sp.add(rsVp);
sp.add(rsFp);
if( !sp.init(gl) ) {
throw new GLException("RegionRenderer: Couldn't init program: "+sp);
}
st.attachShaderProgram(gl, sp, false);
st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);
if(!sp.link(gl, System.err)) {
throw new GLException("RegionRenderer: Couldn't link program: "+sp);
}
st.useProgram(gl, true);
if(DEBUG) {
System.err.println("RegionRendererImpl01 initialized: " + Thread.currentThread()+" "+st);
}
return true;
}
@Override
protected void destroyImpl(GL2ES2 gl) {
super.destroyImpl(gl);
}
@Override
protected void drawImpl(GL2ES2 gl, Region region, float[] position, int[] texSize) {
((GLRegion)region).draw(gl, rs, vp_width, vp_height, texSize);
}
}