Does NM16 work anymore? From src/tools dir

General discussion about Celestia that doesn't fit into other forums.
Avatar
Topic author
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Does NM16 work anymore? From src/tools dir

Post #1by cartrite » 29.05.2006, 06:53

I can't find anything in the code from the latest cvs or official source code of nm16 that writes any data. When I compiled it and ran it all it did was print the header in the ppm file and quit.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

Avatar
John Van Vliet
Posts: 2944
Joined: 28.08.2002
With us: 22 years 2 months

re

Post #2by John Van Vliet » 31.05.2006, 17:15

hi what did you use to build it

for me visual stuido builds it and so dose MinGW
on my xp box, and gcc4.1 in fedora

you may need to run ti in mingw and output it to a file with a >

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Does NM16 work anymore? From src/tools dir

Post #3by t00fri » 31.05.2006, 17:41

cartrite wrote:I can't find anything in the code from the latest cvs or official source code of nm16 that writes any data. When I compiled it and ran it all it did was print the header in the ppm file and quit.


Cartrite,

the input data are read from the STDIN file handle and the output goes to STDOUT. These filehandles are called "standard input (STDIN)" and "standard output(STDOUT)". This is a very handy setup, since one may use redirection to (>) and from (<) files.

eg.

nm16 <options> < elevations16bit.bin > normalmap.ppm

So the program reads from elevations16bit.bin and writes to normalmap.ppm in this example.

The best with programs using STDIN and STDOUT instead of filenames is that they may be piped (|) together. Suppose you have a tool called 'halfsize' that reduces the size of your texture by a factor of two, then you may write e.g.

halfsize < elevations16bit.bin | halfsize | halfsize > out16bit.bin

got it?

The file out16bit.bin then only has 1/8 size of the input texture elevations16bit.bin

Unfortunately under Win32 this all works not well for binary files. But for Linux it's wonderful!
There are hacks for Win32, however.

Bye Fridger
Image

Avatar
Topic author
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #4by cartrite » 31.05.2006, 19:02

First, This is an old thread that was written before I became aware of this normalmap problem and the new tools that will become available soon to rebuild them.

Second, just to bring me up to date if I'm missing something here, can someone show me were in the following code are the statements that writes actual data to the outputfile and highlight same in red?

Code: Select all

#include <iostream>
#include <cstdio>

using namespace std;

int kernelSize = 2;
int halfKernelSize = 1;


float readS16(istream& in)
{
    unsigned char c[2];
    cin.read((char*) c, 2);

    return (((short) c[0] << 8) | c[1]) * (1.0f / 65535.0f);
}


float* readRowS16(istream& in, int width)
{
    float* row = new float[width];
    for (int i = 0; i < width; i++)
        row[i] = readS16(in);

    return row;
}


int main(int argc, char* argv[])
{
    if (argc < 5)
    {
        cerr << "Usage: nm16 <width> <height> <bumpheight> <filter method>\n";
        return 1;
    }

    int width = 0;
    int height = 0;
    float bumpheight = 1.0f;
    int method = 0;

    if (sscanf(argv[1], " %d", &width) != 1 ||
        sscanf(argv[2], " %d", &height) != 1)
    {
        cerr << "Bad image dimensions.\n";
        return 1;
    }

    if (sscanf(argv[3], " %f", &bumpheight) != 1)
    {
        cerr << "Invalid bump height.\n";
        return 1;
    }

    if (sscanf(argv[4], " %d", &method) != 1)
    {
        cerr << "Bad filter method.\n";
        return 1;
    }

    // Binary 8-bit grayscale header
    // cout << "P5\n";
    // Binary 8-bit/channel RGB header
    cout << "P6\n";
    cout << width << ' ' << height << '\n' << "255\n";

    float** samples = new float*[height];

    for (int i = 0; i < kernelSize - 1; i++)
        samples[i] = readRowS16(cin, width);

    for (int y = 0; y < height; y++)
    {
        // Out with the old . . .
        if (y > halfKernelSize)
            delete[] samples[y - halfKernelSize - 1];

        // . . . and in with the new.
        if (y < height - halfKernelSize)
            samples[y + halfKernelSize] = readRowS16(cin, width);

        for (int x = 0; x < width; x++)
        {
#if 0
            unsigned char v = (unsigned char) (samples[y][x]  * 255.99f);
            cout.write((char*) &v, 1);
#endif
            float dx;
            if (x == width - 1)
                dx = samples[y][0] - samples[y][x];
            else
                dx = samples[y][x + 1] - samples[y][x];

            float dy;
            if (y == height - 1)
                dy = samples[y][x] - samples[y - 1][x];
            else
                dy = samples[y + 1][x] - samples[y][x];
        }
    }

    return 0;
}
This is what the file looks like back to Celestia version 1.4.0

I compiled the above code ( from celestia/src/tools/nm16 - cvs version 05/2006 ) with

Code: Select all

g++ -O3 nm16.cpp -o nm16
and then ran it with

Code: Select all

nm16 10800 4800 150.0 0 < a10g.bin > /srv/disk2/home/cartrite/BMNG/topo/out.ppm
with Suse 10 x86_64 using gcc 4.0.2 and Suse 9.2 using gcc 3.3.4 and here are the contents of out.ppm from both

Code: Select all

P6
10800 4800
255

Anyhow I ended up using the old code of nm16 which looks this at the end of the file

Code: Select all

            float dx;
            if (x == width - 1)
      dx = samples[y][x] - samples[y][0];
            else
      dx = samples[y][x] - samples[y][x + 1];

            float dy;
            if (y == height - 1)
      dy = samples[y - 1][x] - samples[y][x];
            else
      dy = samples[y][x] - samples[y + 1][x];

       dx *= bumpheight;
       dy *= bumpheight;
       float mag = (float) sqrt(dx * dx + dy * dy + 1.0f);
       float rmag = 1.0f / mag;
#if 0
       if (y % 100 == 0 && x == 1000)
      cerr << "dx: " << dx << '\n';
#endif

       rgb[x * 3 + 0] = (unsigned char) (128 + 127 * dx * rmag);
       rgb[x * 3 + 1] = (unsigned char) (128 + 127 * dy * rmag);
       rgb[x * 3 + 2] = (unsigned char) (128 + 127 * rmag);
        }

   fwrite(rgb, width * 3, 1, stdout);
    }

    return 0;
}
and the output file was normal.

cartrite
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Post #5by t00fri » 31.05.2006, 20:55

Cartrite,

you are correct, even the present CVS code is grossly incomplete. The whole rgb[] definition and the final fwrite() is missing. So this code cannot work!

I have never checked Chris' code that he had committed to CVS.

Bye Fridger
Image

Avatar
Topic author
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #6by cartrite » 31.05.2006, 21:30

Many Thanks,
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4


Return to “Celestia Users”