Monogame内容管道中的自定义默认效果

时间:2019-05-21 23:14:41

标签: xna monogame

因此,我最终为MonoGame编写了第一个HLSL着色器,并设法以某种方式将其连接到我要绘制的模型。 到目前为止,一切都很好。 但是,我认为“以某种方式设法编写代码”很难看,而且可能不是实现此目的的预期方式:

internal Model(ContentManager content)
{
    mModel = content.Load<Microsoft.Xna.Framework.Graphics.Model>("models/CustomModel");
    // individual effect for individual models
    var effect = content.Load<Effect>("effects/CustomEffect").Clone();
    effect.Parameters["Texture"].SetValue(mModel.Meshes[0].MeshParts[0].Effect.Parameters["Texture"].GetValueTexture2D());

    foreach (var mesh in mModel.Meshes)
    {
        foreach (var meshPart in mesh.MeshParts)
        {
            meshPart.Effect = effect;
        }
    }
}

如您所见,我分别加载了模型和效果,并用新加载的自定义效果替换了模型的所有BasicEffects。并保留旧的TextureVariable。

我自己确信有一个更优雅的解决方案,该解决方案涉及告诉MonoGame使用CustomEffect而不是BasicEffect。 我知道我可以使用MGCB工具为ModelProcessor指定一个DefaultEffect,但是我没有找到需要做的事情,因此我可以在那里指定我的效果而不会导致游戏崩溃,并告诉我effect / CustomEffect不是有效的效果。

那么有没有更好的方法可以实现我现有代码所实现的相同目标?如果可以,怎么办?

2 个答案:

答案 0 :(得分:1)

您的解决方案是最主要的解决方案,也是最灵活的。

您确实需要将效果克隆和参数行移到foreach循环内,并将其更改为:

public class IndexValueAction extends EPSBaseAction {
  public IndexValueAction() {
    super();
  }

  boolean isValidContentType(contentType) {
    return (contentType != null) && (contentType.indexOf("multipart/form-data") >= 0)
  }

  String readContent(request) throws Exception {
    DataInputStream in = new DataInputStream(request.getInputStream());

    int             formDataLength = request.getContentLength();
    byte            dataBytes[]    = new byte[formDataLength];
    int             totalBytesRead = 0;

    while (totalBytesRead < formDataLength) {
      totalBytesRead += in.read(dataBytes, totalBytesRead, formDataLength);
    }

    return new String(dataBytes);
  }

  void scanFile(realPath, outFilePath, errors) throws Exception {
    if (!FileScanner.loadProperty(realPath)) {
      return false;
    }

    if (!FileScanner.cleanFile(outFilePath)) {
      FileScaner.cleanFile(outFilePath);
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("errors.dynamic", "<li>Virus found!!"));
      return;
    }

    if (!FileScanner.checkFileSign(outFilePath)) {
      FileScaner.cleanFile(filepath);
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("errors.dynamic", "<li>File type not supported!!"));
    }
  }

  IndexValueReportObject loadIndexValueReportObject(String[] fields, int i, Vector<String> vector) {
    IndexValueReportObject indexValueReportObj = new IndexValueReportObject();

    try {
      indexValueReportObj.setDate(Timestamp.valueOf(fields[0]));
    } catch (Exception e) {
      vector.add("Invalid Date at row " + (i + 2));
    }

    try {
      indexValueReportObj.setPlatts(new BigDecimal(fields[1]));
    } catch (Exception e) {
      vector.add("Invalid Platts Value at row " + (i + 2));
    }

    try {
      indexValueReportObj.setArgus(new BigDecimal(fields[2]));
    } catch (Exception e) {
      vector.add("Invalid Argus Value at row " + (i + 2));
    }

    try {
      indexValueReportObj.setTsi(new BigDecimal(fields[3]));
    } catch (Exception e) {
      vector.add("Invalid TSI value at row " + (i + 2));
    }

    return indexValueReportObj;
  }

  @Override
  @SuppressWarnings("unchecked")
  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
    Vector<String> vector = new Vector<String>();

    if (!isValidContentType(request.getContentType())) {
      vector.add("File Type mismatch");
      return mapping.findForward("failureUpload");
    }

    String file;
    try {
      file = readContent(request);
    } catch (Exception e) {
      vector.add("No excel has been selected");
      return mapping.findForward("failureUpload");
    }

    ActionErrors errors = new ActionErrors();
    try {
      String saveFile = file.substring(file.indexOf("filename=\"") + 10);
             saveFile = saveFile.substring(0, saveFile.indexOf("\n"));
             saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1,  saveFile.indexOf("\""));

      int    lastIndex = contentType.lastIndexOf("=");
      String boundary  = contentType.substring(lastIndex + 1, contentType.length());

      int pos = file.indexOf("filename=\"");
          pos = file.indexOf("\n", pos) + 1;
          pos = file.indexOf("\n", pos) + 1;
          pos = file.indexOf("\n", pos) + 1;

      int boundaryLocation = file.indexOf(boundary, pos) - 4;
      int startPos         = ((file.substring(0, pos)).getBytes()).length;
      int endPos           = file.substring(0, boundaryLocation).getBytes().length;

      Vector<IndexValueReportObject> indexObjectVector = new Vector<IndexValueReportObject>();

      SimpleDateFormat df         = new SimpleDateFormat("dd-MM-yy hh-mm-ss");
      String           fileSuffix = "-" + df.format(new Date()) + ".xls";
                        saveFile   = saveFile.substring(0, saveFile.indexOf(".")) + fileSuffix;

      ServletContext sc1        = request.getSession().getServletContext();
      Properties     properties = new Properties();
      String         realPath1  = sc1.getRealPath("serverPath.properties");

      FileInputStream fis = new FileInputStream(realPath1);
      properties.load(fis);
      String uploadFilePath = properties.getProperty("fileUpload.path");
      FileOutputStream fileOut =    new FileOutputStream(uploadFilePath + saveFile);
      System.out.println(uploadFilePath);
      if (endPos > dataBytes.length) {
        endPos = dataBytes.length;
      }

      fileOut.write(dataBytes, startPos, (endPos - startPos));
      fileOut.flush();
      fileOut.close();

      Vector<String []> rowVector = new Vector<String[]>();
      Vector<Object> errorVector  = new Vector<Object>();
      UploadObject   uploadObject = new UploadObject();
      int            errorId      = 0;

      try {
        ServletContext sc          = getServlet().getServletContext();
        String         realPath    = sc.getRealPath("virusCheck.properties");
        File           outFile     = new File(uploadFilePath  + saveFile);
        String         outFilePath = outFile.getAbsolutePath();

        scanFile(realPath, outFilePath, errors);
        if (errors.isEmpty()) {
          FileInputStream inputStream = new FileInputStream(uploadFilePath + saveFile);
          Workbook        w           = Workbook.getWorkbook(inputStream);
          Sheet           read_sheet  = w.getSheet(0);***
          int             rows        = read_sheet.getRows();

          for (int j = 1; j < rows; j++) {
            String[] fields = new String[4];
            for(int i = 0; i < fields.length; i++) {
              Cell cell = read_sheet.getCell(i, j);
              fields[i] = cell.getContents().trim();
              if (fields[0] != null) {
                try {
                  if (fields[i].indexOf(".") > 0) {
                    if (i != 1) {
                      fields[i] = fields[i];
                    } else {
                      fields[i].substring(0, fields[i].indexOf("."));
                    }
                  }
                } catch(Exception e1) {
                  int k = i+1;
                  errorVector.add("Invalid data at field " + k);
                  errorId = 1;
                }
              }
            }

            if (!(fields[0] == null || (fields[0].trim().equals("")))) {
              rowVector.add(fields);
            } else {
              break;
            }
          }

          uploadObject.setErrorId(errorId);
          uploadObject.setErrorVector(errorVector);
          uploadObject.setRowVector(rowVector);

          if (errorId == 0) {
            if (rowVector.size() > 0) {
              for (int i = 0; i < rowVector.size(); i++) {
                String[] fields = rowVector.elementAt(i);
                indexObjectVector.add(loadIndexValueReportObject(loadIndexValueReportObject(fields, i, vector)));
              }
            } else {
              vector.add("No Bidder is created in the excel file ");
            }
          } else {
            for (int k = 0; k < errorVector.size(); k++) {
              String errorDescription = (String) errorVector.get(k);
              vector.add(errorDescription);
            }
          }
        }
      } catch (Exception e1) {
        errorId     = uploadObject.getErrorId();
        rowVector   = uploadObject.getRowVector();
        errorVector = uploadObject.getErrorVector();

        for (int k = 0; k < errorVector.size(); k++) {
          String errorDescription = (String) errorVector.get(k);
          vector.add(errorDescription);
        }
      }

      request.setAttribute(IConstant.UPLOAD_MESSAGE, "uploaded");
      request.setAttribute(IConstant.INDEX_OBJECT_VECTOR, indexObjectVector);
      request.getSession().setAttribute(IConstant.FILE_NAME, uploadFilePath + saveFile);
    } catch (Exception e1) {
      vector.add("File name or sheet name error ");
    }

    if (!errors.isEmpty()) {
      request.setAttribute(IConstant.ERROR_VECTOR, errors);
      return mapping.findForward("failureUpload");
    }

    return mapping.findForward("success");
  }
}

否则,模型的所有部分将使用相同的纹理。

缺乏优雅是因为这是var effect = content.Load<Effect>("effects/CustomEffect").Clone(); effect.Parameters["Texture"].SetValue(meshPart.Effect.Parameters["Texture"].GetValueTexture2D()); 平台的直接继承物。

另一个选择是使您的参数和语义与XNA的参数和语义匹配,这时您应该能够在模型处理器中进行设置。模型处理器期望参数以该特定顺序存在。

答案 1 :(得分:0)

看起来每个effect都具有相同的值,因为它在for循环中没有变化。

所以我想您也可以在effect中定义meshPart。因此您不必为每个人都进行for循环。

您还可以在game1.cs的Loadcontent类中创建效果,因此您不必每次都定义它。

据我所知就是这样。