/* * $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);
    }
}