⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 normalmapper.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//=============================================================================
// NormalMapper.cpp -- Program that converts a low and high res model into
//                     a normal map, lots of options see main() for details.
//=============================================================================
// $File: //depot/3darg/Tools/NormalMapper/NormalMapper.cpp $ $Revision: #35 $ $Author: gosselin $
//=============================================================================
// (C) 2002 ATI Research, Inc., All rights reserved.
//=============================================================================

#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <float.h>

#include "NmFileIO.h"
#include "TGAIO.h"
#include "ArgFileIO.h"
#include "SMDFileIO.h"

#define PACKINTOBYTE_MINUS1TO1(X)  ((BYTE)((X)*127.5+127.5))
#define UNPACKBYTE_MINUS1TO1(x)    ((((float)(x)-127.5)/127.5))
#define PACKINTOBYTE_0TO1(x)       ((BYTE)((x)*255))
#define UNPACKBYTE_0TO1(x)         (((float)(x)/255.0f))

#define PACKINTOSHORT_0TO1(x)      ((unsigned short)((x)*65535))
#define UNPACKSHORT_0TO1(x)        (((float)(x)/65535.0f))
#define PACKINTOSHORT_MINUS1TO1(X)  ((short)((X)*32767.5+32767.5))
#define UNPACKSHORT_MINUS1TO1(x)    ((((float)(x)-32767.5)/32767.5))
#define PACKINTOSHORT_SMINUS1TO1(x) ((short)((x)*32767.5))
#define UNPACKSHORT_SMINUS1TO1(x)   (((float)(x))/32767.5)

#define VEC_Subtract(a, b, c) ((c)[0] = (a)[0] - (b)[0], \
                               (c)[1] = (a)[1] - (b)[1], \
                               (c)[2] = (a)[2] - (b)[2])
#define VEC_Add(a, b, c) ((c)[0] = (a)[0] + (b)[0], \
                          (c)[1] = (a)[1] + (b)[1], \
                          (c)[2] = (a)[2] + (b)[2])
#define VEC_Cross(a, b, c) ((c)[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1], \
                            (c)[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2], \
                            (c)[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0])
#define VEC_DotProduct(a, b) ((a)[0] * (b)[0] + \
                              (a)[1] * (b)[1] + \
                              (a)[2] * (b)[2])
#define INT_ROUND_TEXCOORD_U(X)  (int)(((X)*(float)(gWidth-1))+0.5f)
#define INT_ROUND_TEXCOORD_V(X)  (int)(((X)*(float)(gHeight-1))+0.5f)
#define INT_TEXCOORD_U(X)  (int)((X)*(float)(gWidth-1))
#define INT_TEXCOORD_V(X)  (int)((X)*(float)(gHeight-1))

// Value that's close enough to be called 0.0
#define EPSILON 1.0e-7

// Edge structure.
typedef struct
{
   int idx0;
   int idx1;

   // Min/max info
   int yMin;
   int yMax;
   int x;
   int x1;
   int increment;
   int numerator;
   int denominator;
} NmEdge;

// Tangent space structure.
typedef struct
{
   double m[3][9];
} NmTangentMatrix;

// High res "visibility"
typedef struct
{
   int numTris;
   unsigned int* index;
} NmVisible;

// Experimental pixel format.      
typedef union
{
   struct { BYTE r, g, b, a; };
   struct { BYTE v[4]; };
} JohnPixel;

// Local print routines.
void NmErrorLog (const char *szFmt, ...);
void NmErrorLog (char *szFmt);
#define NmPrint NmErrorLog

// Width and height of the resultant texture
int gWidth;
int gHeight;

// Supersampling variables.
int gNumSamples = 1;
typedef union
{
   struct { float x, y; };
   struct { float v[2]; };
} Sample;

// Rules for figuring out which normal is better.
enum
{
   NORM_RULE_CLOSEST = 0,
   NORM_RULE_BEST_CLOSEST,
   NORM_RULE_BEST_FARTHEST,
   NORM_RULE_FARTHEST,
   NORM_RULE_MIXED,
   NORM_RULE_BEST_MIXED,
   NORM_RULE_BEST,
   NORM_RULE_FRONT_FURTHEST,
   NORM_RULE_FRONT_BEST_FURTHEST,
   NORM_RULE_FRONT_CLOSEST,
   NORM_RULE_FRONT_BEST_CLOSEST
};
int gNormalRules = NORM_RULE_BEST_CLOSEST;

// The output format
enum
{
   NORM_OUTPUT_8_8_8_TGA = 0,
   NORM_OUTPUT_JOHN_TGA,
   NORM_OUTPUT_16_16_ARG,
   NORM_OUTPUT_16_16_16_16_ARG,
   NORM_OUTPUT_10_10_10_2_ARG,
   NORM_OUTPUT_10_10_10_2_ARG_MS,
   NORM_OUTPUT_11_11_10_ARG_MS,
};
int gOutput = NORM_OUTPUT_8_8_8_TGA;


// How to generate mip levels
enum
{
   MIP_NONE = 0,
   MIP_RECOMPUTE,
   MIP_BOX
};
int gComputeMipLevels = MIP_NONE;


double gEpsilon = 0.0;       // Tolerance value
double gDistance = FLT_MAX;  // Maximum distance that a normal is considered
bool gInTangentSpace = true; // Are we putting the normals into tangent space
bool gExpandTexels = true;   // Expand the border texels so we don't get crud
                             // when bi/trilinear filtering
bool gBoxFilter = false;     // Perform a post-box filter on normal map?

//////////////////////////////////////////////////////////////////////////////
// Get the sample offsets for supersampling.
//////////////////////////////////////////////////////////////////////////////
Sample*
GetSamples (int numSamples)
{
   static Sample s1[] = { {0.0f, 0.0f} };
   switch (numSamples)
   {
      case 1:
         {
            return s1;
         }
      case 2:
         {
            static Sample s2[2] = { {0.5f, 0.5f},
                                    {-0.5f, -0.5f} };
            return s2;
         }
      case 3:
         {
            static Sample s3[3] = { {0.5f, 0.5f},
                                    {0.0f, 0.0f},
                                    {-0.5f, -0.5f} };
            return s3;
         }
      case 4:
         {
            static Sample s4[4] = { {0.5f, 0.5f}, 
                                    {-0.5f, 0.5f},
                                    {0.5f, -0.5f},
                                    {-0.5f, -0.5f} };
            return s4;
         }
      case 5:
         {
            static Sample s5[5] = { {0.5f, 0.5f},
                                    {-0.5f, 0.5f},
                                    {0.0f, 0.0f},
                                    {0.5f, -0.5f},
                                    {-0.5f, -0.5f} };
            return s5;
         }
      case 9:
         {
            static Sample s9[9] = { {0.5f, 0.5f},
                                    {0.0f, 0.5f},
                                    {-0.5f, 0.5f},
                                    {-0.5f, 0.0f},
                                    {0.0f, 0.0f},
                                    {0.5f, 0.0f},
                                    {0.5f, -0.5f},
                                    {0.0f, -0.5f},
                                    {-0.5f, -0.5f} };
            return s9;
         }
      case 13:
         {
            static Sample s13[13] = { { 0.33f, 0.33f},
                                      { 0.0f,  0.33f},
                                      {-0.33f, 0.33f},
                                      {-0.33f, 0.0f},
                                      { 0.0f,  0.0f},
                                      { 0.33f, 0.0f},
                                      { 0.33f,-0.33f},
                                      { 0.0f, -0.33f},
                                      {-0.33f,-0.33f},
                                      { 0.66f, 0.00f},
                                      {-0.66f, 0.00f},
                                      { 0.00f, 0.66f},
                                      { 0.00f, 0.66f}};
            return s13;
         }
      case 21:
         {
            static Sample s21[21] = { { 0.33f, 0.33f},
                                      { 0.0f,  0.33f},
                                      {-0.33f, 0.33f},
                                      {-0.33f, 0.0f},
                                      { 0.0f,  0.0f},
                                      { 0.33f, 0.0f},
                                      { 0.33f,-0.33f},
                                      { 0.0f, -0.33f},
                                      {-0.33f,-0.33f},
                                      { 0.66f, 0.00f},
                                      { 0.66f, 0.33f},
                                      { 0.66f,-0.33f},
                                      {-0.66f, 0.00f},
                                      {-0.66f, 0.33f},
                                      {-0.66f,-0.33f},
                                      { 0.00f, 0.66f},
                                      { 0.33f, 0.66f},
                                      {-0.33f, 0.66f},
                                      { 0.33f,-0.66f},
                                      {-0.33f,-0.66f},
                                      { 0.00f,-0.66f}};
            return s21;
         }
      case 37:
         {
            static Sample s37[37] = { { 0.25f, 0.25f},
                                      { 0.0f,  0.25f},
                                      {-0.25f, 0.25f},
                                      {-0.25f, 0.0f},
                                      { 0.0f,  0.0f},
                                      { 0.25f, 0.0f},
                                      { 0.25f,-0.25f},
                                      { 0.0f, -0.25f},
                                      {-0.25f,-0.25f},
                                      { 0.50f, 0.00f},
                                      { 0.50f, 0.25f},
                                      { 0.50f,-0.25f},
                                      {-0.50f, 0.00f},
                                      {-0.50f, 0.25f},
                                      {-0.50f,-0.25f},
                                      { 0.00f, 0.50f},
                                      { 0.25f, 0.50f},
                                      {-0.25f, 0.50f},
                                      { 0.25f,-0.50f},
                                      {-0.25f,-0.50f},
                                      { 0.00f,-0.50f},
                                      { 0.75f, 0.25f},
                                      { 0.75f, 0.00f},
                                      { 0.75f,-0.25f},
                                      { 0.50f, 0.50f},
                                      { 0.50f,-0.50f},
                                      { 0.25f, 0.75f},
                                      { 0.25f,-0.75f},
                                      { 0.00f, 0.75f},
                                      { 0.00f,-0.75f},
                                      {-0.25f, 0.75f},
                                      {-0.25f,-0.75f},
                                      {-0.50f, 0.50f},
                                      {-0.50f,-0.50f},
                                      {-0.75f, 0.25f},
                                      {-0.75f, 0.00f},
                                      {-0.75f,-0.25f}};
            return s37;
         }
      case 57:
         {
            static Sample s57[57] = { {-0.8f, 0.2f},
                                      {-0.8f, 0.0f},
                                      {-0.8f,-0.2f},
                                      {-0.6f, 0.4f},
                                      {-0.6f, 0.2f},
                                      {-0.6f, 0.0f},
                                      {-0.6f,-0.2f},
                                      {-0.6f,-0.4f},
                                      {-0.4f, 0.6f},
                                      {-0.4f, 0.4f},
                                      {-0.4f, 0.2f},
                                      {-0.4f, 0.0f},
                                      {-0.4f,-0.2f},
                                      {-0.4f,-0.4f},
                                      {-0.4f,-0.6f},
                                      {-0.2f, 0.8f},
                                      {-0.2f, 0.6f},
                                      {-0.2f, 0.4f},
                                      {-0.2f, 0.2f},
                                      {-0.2f, 0.0f},
                                      {-0.2f,-0.2f},
                                      {-0.2f,-0.4f},
                                      {-0.2f,-0.6f},
                                      {-0.2f,-0.8f},
                                      {-0.0f, 0.8f},
                                      {-0.0f, 0.6f},
                                      {-0.0f, 0.4f},
                                      {-0.0f, 0.2f},
                                      {-0.0f, 0.0f},
                                      {-0.0f,-0.2f},
                                      {-0.0f,-0.4f},
                                      {-0.0f,-0.6f},
                                      {-0.0f,-0.8f},
                                      { 0.2f, 0.8f},
                                      { 0.2f, 0.6f},
                                      { 0.2f, 0.4f},
                                      { 0.2f, 0.2f},
                                      { 0.2f, 0.0f},
                                      { 0.2f,-0.2f},
                                      { 0.2f,-0.4f},
                                      { 0.2f,-0.6f},
                                      { 0.2f,-0.8f},
                                      { 0.4f, 0.6f},
                                      { 0.4f, 0.4f},
                                      { 0.4f, 0.2f},
                                      { 0.4f, 0.0f},
                                      { 0.4f,-0.2f},
                                      { 0.4f,-0.4f},
                                      { 0.4f,-0.6f},
                                      { 0.6f, 0.4f},
                                      { 0.6f, 0.2f},
                                      { 0.6f, 0.0f},
                                      { 0.6f,-0.2f},
                                      { 0.6f,-0.4f},
                                      { 0.8f, 0.2f},
                                      { 0.8f, 0.0f},
                                      { 0.8f,-0.2f}};
            return s57;
         }
   }
   return s1;
}

//////////////////////////////////////////////////////////////////////////
// Test if the new normal is a better fit than the last one.
//////////////////////////////////////////////////////////////////////////
inline bool
IntersectionIsBetter (int rule, NmRawPointD* norm,
                      double nNorm[3], NmRawPointD* nIntersect,
                      double lNorm[3], NmRawPointD* lIntersect)
{
   // First see if the normal is roughly in the same direction as the low
   // resoultion normal.
   if (VEC_DotProduct (nNorm, norm->v) > 0.1)
   {
      // If this is the first intersection we've found.
      if ((lNorm[0] == 0.0) && (lNorm[1] == 0.0) && (lNorm[2] == 0.0))
      {
         return true;
      }
     
      // Which ruleset to use.
      switch (rule)
      {
         default:
            NmPrint ("Error: Unknown rules set (%d)!\n", rule);
            exit (-1);
               
         case NORM_RULE_CLOSEST:
            // Pick the closest
             if ( (fabs (nIntersect->x) < gDistance) &&
                 (fabs(nIntersect->x) < fabs(lIntersect->x)) )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -