From 343b658c32a6473c545187c1e276ee5d06c2686a Mon Sep 17 00:00:00 2001 From: Kevin Rushforth Date: Wed, 9 Jun 2004 04:25:41 +0000 Subject: Initial creation of j3d-core-utils sources in CVS repository git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@7 ba19aa83-45c5-6ac9-afd3-db810772062c --- src/native/d3d/D3dVertexBuffer.cpp | 259 +++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 src/native/d3d/D3dVertexBuffer.cpp (limited to 'src/native/d3d/D3dVertexBuffer.cpp') diff --git a/src/native/d3d/D3dVertexBuffer.cpp b/src/native/d3d/D3dVertexBuffer.cpp new file mode 100644 index 0000000..e3cb8d1 --- /dev/null +++ b/src/native/d3d/D3dVertexBuffer.cpp @@ -0,0 +1,259 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" +#include "D3dVertexBuffer.hpp" + + +D3dVertexBuffer::D3dVertexBuffer() +{ + buffer = NULL; + indexBuffer = NULL; + numVertices = NULL; + numVerticesLen = 0; + isIndexPrimitive = FALSE; + nextVB = NULL; + stripLen = 0; + totalVertexCount = 0; + ctx = NULL; + next = NULL; + previous = NULL; + isPointFlagUsed = FALSE; + primitiveType = D3DPT_FORCE_DWORD; +} + +D3dVertexBuffer::~D3dVertexBuffer() +{ + release(); +} + +VOID D3dVertexBuffer::release() +{ + SafeRelease(buffer); + SafeRelease(indexBuffer); + SafeDelete(numVertices); + + numVerticesLen = 0; + isIndexPrimitive = FALSE; + isPointFlagUsed = FALSE; + stripLen = 0; + totalVertexCount = 0; + // recursively free the list + SafeDelete(nextVB); +} + + + +VOID D3dVertexBuffer::render(D3dCtx *d3dCtx) +{ + D3DPRIMITIVETYPE oldPrimitiveType; + BOOL renderPoint = false; + BOOL restorePointSize = false; + float oldPointSize = 1.0f; + + if ((buffer != NULL) && (numVertices != NULL)) { + // device is already check for NULL in callDisplayList + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; + BOOL setAmbientLight = false; + + if (((vertexFormat & D3DFVF_DIFFUSE) == 0) && + (!d3dCtx->isLightEnable)) { + setAmbientLight = true; + if (totalVertexCount > 0) { + // This is the first Node in the list + d3dCtx->setAmbientLightMaterial(); + } + } + + if ((d3dCtx->pointSize > 1) && + ((d3dCtx->fillMode == D3DFILL_POINT) || + (primitiveType == D3DPT_POINTLIST))) { + // Some driver may cull the point away if not + // set to CULL_NONE + if (!isPointFlagUsed) { + // restore point size to 1 + if (debug) { + printf("VB render with pointSize %d without D3DPOINT flag set\n", d3dCtx->pointSize); + } + device->SetRenderState(D3DRS_POINTSIZE, *((LPDWORD) + &oldPointSize)); + restorePointSize = true; + } else { + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + // workaround for driver bug, otherwise you will + // see four corner points instead of one big point + // if fill mode is POINT + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + if (d3dCtx->deviceInfo->maxPointSize < d3dCtx->pointSize) { + // Use software vertex processing mode + device->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + TRUE); + } + oldPrimitiveType = primitiveType; + // For Polygon D3DFill_POINT mode we need to + // temporary switch primitive to point list + primitiveType = D3DPT_POINTLIST; + renderPoint = true; + } + } + + device->SetStreamSource(0, buffer, stride); + device->SetVertexShader(vertexFormat); + + int startIdx=0; + int vc, i; + + if (!isIndexPrimitive || + ((indexBuffer == NULL) && renderPoint)) { + for (i = 0; i < stripLen; i++) { + vc = numVertices[i]; + device->DrawPrimitive(primitiveType, + startIdx, + getPrimitiveNum(primitiveType,vc)); + startIdx += vc; + } + } else { + if (indexBuffer != NULL) { + device->SetIndices(indexBuffer, 0); + for (i = 0; i < stripLen; i++) { + vc = numVertices[i]; + device->DrawIndexedPrimitive(primitiveType, + 0, + vcount, + startIdx, + getPrimitiveNum(primitiveType, vc)); + startIdx += vc; + } + } else { + if (d3dCtx->quadIndexBufferSize > 0) { + // Index is successfully set + device->SetIndices(d3dCtx->quadIndexBuffer, 0); + device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, + 0, + numVertices[0], + 0, + numVertices[0] >> 1); + } + // Otherwise not enough memory when index buffer + // is created, so draw nothing. + } + } + + if (setAmbientLight && (nextVB == NULL)) { + // This is the last Node in the list + d3dCtx->restoreDefaultLightMaterial(); + } + + if (renderPoint) { + device->SetRenderState(D3DRS_CULLMODE, d3dCtx->cullMode); + device->SetRenderState(D3DRS_FILLMODE, d3dCtx->fillMode); + device->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + d3dCtx->softwareVertexProcessing); + primitiveType = oldPrimitiveType; + } else if (restorePointSize) { + device->SetRenderState(D3DRS_POINTSIZE, + *((LPDWORD) &d3dCtx->pointSize)); + } + } + + if (nextVB != NULL) { + nextVB->render(d3dCtx); + } +} + + +VOID D3dVertexBuffer::addStride(int len) +{ + if (numVerticesLen <= stripLen) { + if (numVerticesLen == 0) { + numVertices = new USHORT[1]; + if (numVertices == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + return; + } + numVerticesLen = 1; + } else { + int size = numVerticesLen << 1; + USHORT *p = new USHORT[size]; + if (p == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + return; + } + CopyMemory(p, numVertices, numVerticesLen*sizeof(USHORT)); + delete numVertices; + numVertices = p; + numVerticesLen = size; + } + } + numVertices[stripLen++] = len; +} + + +/* + * This is used by Strip GeometryArray + * Replace all previously define stripLen by this one. + */ +VOID D3dVertexBuffer::addStrides(jint len, jint* strips) +{ + int i = len; + + if (numVerticesLen < len) { + if (numVertices) { + delete numVertices; + } + numVertices = new USHORT[len]; + numVerticesLen = len; + } + + USHORT *q = numVertices; + + while (--i >= 0) { + *q++ = *strips++; + } + stripLen = len; +} + + +/* + * This is used by D3dDisplayList optimize() + * Append this one to the current strip define. + */ +VOID D3dVertexBuffer::appendStrides(jint len, USHORT* strips) +{ + int i; + USHORT *oldVertices; + + if (numVerticesLen < stripLen + len) { + oldVertices = numVertices; + numVertices = new USHORT[len + stripLen]; + numVerticesLen = len + stripLen; + } + + USHORT *q = numVertices; + USHORT *p = oldVertices; + + if (oldVertices != NULL) { + i = stripLen; + while (--i >= 0) { + *q++ = *p++; + } + delete oldVertices; + } + + i = len; + while (--i >= 0) { + *q++ = *strips++; + } + + stripLen = numVerticesLen; +} + -- cgit v1.2.3