1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <iostream>
  27 #include "D3DMesh.h"
  28 
  29 using std::cout;
  30 using std::endl;
  31 
  32 // Destructor definition
  33 
  34 D3DMesh::~D3DMesh() {
  35 //    cout << "@@@ D3DMesh Destructor called." << endl;
  36     releaseIndexBuffer();
  37     releaseVertexBuffer();
  38     context = NULL;
  39 }
  40 
  41 D3DMesh::D3DMesh(D3DContext *ctx) {
  42     //    cout << "*** D3DMesh Constructor called." << endl;
  43     context = ctx;
  44     indexBuffer = NULL;
  45     vertexBuffer = NULL;
  46     // See MeshData.cc where n = 1
  47     fvf = D3DFVF_XYZ | (2 << D3DFVF_TEXCOUNT_SHIFT) | D3DFVF_TEXCOORDSIZE4(1);
  48     numVertices = 0;
  49     numIndices = 0;
  50 }
  51 
  52 void printResult(const char *str, HRESULT result) {
  53     std::cout << str;
  54     if (SUCCEEDED(result)) {
  55         std::cout << "D3D_OK\n";
  56         return;
  57     }
  58     switch (result) {
  59         case D3DERR_INVALIDCALL:
  60             std::cout << "---- D3DERR_INVALIDCALL\n";
  61             break;
  62         case D3DERR_OUTOFVIDEOMEMORY:
  63             std::cout << "---- D3DERR_OUTOFVIDEOMEMORY\n";
  64             break;
  65         case D3DERR_INVALIDDEVICE:
  66             std::cout << "---- D3DERR_INVALIDDEVICE\n";
  67             break;
  68         case D3DERR_DEVICELOST:
  69             std::cout << "---- D3DERR_DEVICELOST\n";
  70             break;
  71         case E_OUTOFMEMORY:
  72             std::cout << "---- E_OUTOFMEMORY\n";
  73             break;
  74         default:
  75             std::cout << "---- UNKNOWN ERROR\n";
  76             break;
  77     }
  78 
  79 }
  80 
  81 void D3DMesh::releaseIndexBuffer() {
  82     if (indexBuffer) {
  83         ULONG status = indexBuffer->Release();
  84 //        cout << " - Release indexBuffer: status = " << status << endl;
  85         if (status == 0L) {
  86             indexBuffer = NULL;
  87         }
  88     }
  89     numIndices = 0;
  90 }
  91 
  92 void D3DMesh::releaseVertexBuffer() {
  93     if (vertexBuffer) {
  94         ULONG status = vertexBuffer->Release();
  95 //        cout << " - Release vertexBuffer: status = " << status << endl;
  96         if (status == 0L) {
  97             vertexBuffer = NULL;
  98         }
  99     }
 100     numVertices = 0;
 101 }
 102 
 103 boolean D3DMesh::buildBuffers(float *vb, UINT vbSize, USHORT *ib, UINT ibSize) {
 104 //    cout << "D3DMesh::buildBuffers: vertexBufferSize = " << vbSize
 105 //            << ", indexBufferSize = " << ibSize << endl;
 106 
 107     IDirect3DDevice9 *device = context->Get3DDevice();
 108     UINT size = vbSize * sizeof (float);
 109     HRESULT result = D3D_OK;
 110 
 111     if (numVertices != vbSize) {
 112         releaseVertexBuffer();
 113         result = device->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, fvf,
 114                 D3DPOOL_DEFAULT, &vertexBuffer, NULL);
 115         numVertices = vbSize;
 116     }
 117 
 118     if (SUCCEEDED(result) && (vertexBuffer != NULL)) {
 119         float *data;
 120         result = vertexBuffer->Lock(0, size, (void **) &data, 0);
 121         if (SUCCEEDED(result)) {
 122             memcpy_s(data, size, vb, size);
 123             result = vertexBuffer->Unlock();
 124         }
 125     }
 126 //    printResult("D3DMesh.buildBuffers: VertexBuffer's result = ", result);
 127     size = ibSize * sizeof (USHORT);
 128 
 129     if (SUCCEEDED(result) && (numIndices != ibSize)) {
 130         releaseIndexBuffer();
 131         result = device->CreateIndexBuffer(size, D3DUSAGE_WRITEONLY,
 132                 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBuffer, NULL);
 133         numIndices = ibSize;
 134     }
 135 
 136     if (SUCCEEDED(result) && (indexBuffer != NULL)) {
 137         USHORT *data;
 138                 result = indexBuffer->Lock(0, size, (void **) &data, 0);
 139         if (SUCCEEDED(result)) {
 140             memcpy_s(data, size, ib, size);
 141             result = indexBuffer->Unlock();
 142         }
 143     }
 144 //    printResult("D3DMesh.buildBuffers: IndexBuffer's result = ", result);
 145     return SUCCEEDED(result);
 146 
 147 }
 148 
 149 boolean D3DMesh::buildBuffers(float *vb, UINT vbSize, UINT *ib, UINT ibSize) {
 150 //    cout << "D3DMesh::buildBuffers: vertexBufferSize = " << vbSize
 151 //            << ", indexBufferSize = " << ibSize << endl;
 152 
 153     IDirect3DDevice9 *device = context->Get3DDevice();
 154     UINT size = vbSize * sizeof (float);
 155     HRESULT result = D3D_OK;
 156 
 157     if (numVertices != vbSize) {
 158         releaseVertexBuffer();
 159         result = device->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, fvf,
 160                 D3DPOOL_DEFAULT, &vertexBuffer, NULL);
 161         numVertices = vbSize;
 162     }
 163 
 164     if (SUCCEEDED(result) && (vertexBuffer != NULL)) {
 165         float *data;
 166         result = vertexBuffer->Lock(0, size, (void **) &data, 0);
 167         if (SUCCEEDED(result)) {
 168             memcpy_s(data, size, vb, size);
 169             result = vertexBuffer->Unlock();
 170         }
 171     }
 172 //    printResult("D3DMesh.buildBuffers: VertexBuffer's result = ", result);
 173     size = ibSize * sizeof (UINT);
 174 
 175     if (SUCCEEDED(result) && (numIndices != ibSize)) {
 176         releaseIndexBuffer();
 177         result = device->CreateIndexBuffer(size, D3DUSAGE_WRITEONLY,
 178                 D3DFMT_INDEX32, D3DPOOL_DEFAULT, &indexBuffer, NULL);
 179         numIndices = ibSize;
 180     }
 181 
 182     if (SUCCEEDED(result) && (indexBuffer != NULL)) {
 183         UINT *data;
 184                 result = indexBuffer->Lock(0, size, (void **) &data, 0);
 185         if (SUCCEEDED(result)) {
 186             memcpy_s(data, size, ib, size);
 187             result = indexBuffer->Unlock();
 188         }
 189     }
 190 //    printResult("D3DMesh.buildBuffers: IndexBuffer's result = ", result);
 191     return SUCCEEDED(result);
 192 
 193 }
 194 
 195 DWORD D3DMesh::getVertexFVF() {
 196     return fvf;
 197 }
 198 
 199 IDirect3DIndexBuffer9 * D3DMesh::getIndexBuffer() {
 200     return indexBuffer;
 201 }
 202 
 203 IDirect3DVertexBuffer9 * D3DMesh::getVertexBuffer() {
 204     return vertexBuffer;
 205 }
 206 
 207 UINT D3DMesh::getNumVertices() {
 208     return numVertices;
 209 }
 210 
 211 UINT D3DMesh::getNumIndices() {
 212     return numIndices;
 213 }