Page 11 of 14

Re: The official "Seamless Planetary Flight" thread

Posted: Mon Sep 27, 2010 3:26 pm
by Gungnir
strook wrote:ok, guys here is where i am:
i loaded in a sphere with 500 slices and 500 stacks (this limit is set by blender - does anybody know a program where i can make spheres with higher detail?)
SubSurf is your friend.

Re: The official "Seamless Planetary Flight" thread

Posted: Tue Sep 28, 2010 8:53 pm
by strook
I wrote Code that modified the sphere which is now loaded in As surface of à Planet. With 500 slices and stacks it is possible to Show Mountains from à perspective like 10000 Feet. If you Fly lower the perspective is Not realistic you Fly in at à too fast speed and you see the inner sphere in the Bottom half screen.

I recommend to enlarge the planets by the Factor 10-100.
There is à collision detection implemented with the Class continuousterrain, but i don't use that Class yet.
Maybe that Class is used to create Terrain on à Planet to Be Seen from à lower perspective, but i dunno it yet.
Tomorrow i try to Place textures on it. I think there are already functions for it in the mesh Class.
Then i'll complete the Basic mounain creation alogrythm shown above before i continue with that Terrain Class.

Re: The official "Seamless Planetary Flight" thread

Posted: Thu Sep 30, 2010 11:21 am
by strook
i got problems to load in the textures:

in this func:

Code: Select all

GamePlanet::GamePlanet( QVector x,
                        QVector y,
                        float vely,
                        const Vector &rotvel,
                        float pos,
                        float gravity,
                        float radius,
                        const string &textname,
                        const string &technique,
                        const string &unitname,
                        BLENDFUNC blendSrc,
                        BLENDFUNC blendDst,
                        const vector< string > &dest,
                        const QVector &orbitcent,
                        Unit *parent,
                        const GFXMaterial &ourmat,
                        const std::vector< GFXLightLocal > &ligh,
                        int faction,
                        string fgid,
                        bool inside_out ) :
{
...
//my code
//FIXME:an error with loading textures.. the texture wont be loaded in correctly
        std::vector< std::string > textures;
        textures.push_back( "planets/forest.texture" );
   //     textures.push_back( textname.c_str() );


 
        vector< Mesh* > m = Mesh::LoadMeshes( f, Vector(radius,radius,radius), faction, NULL, surface_unit.c_str(), textures );
        Unit *surface = UnitFactory::createUnit( m, true, faction );
...

Image
(click on the pic to see the original)


how can i load in textures correctly and why is there a vector for the textures?

Re: The official "Seamless Planetary Flight" thread

Posted: Thu Sep 30, 2010 6:58 pm
by klauss
Did you run vs with --debug and see what's going on?

Re: The official "Seamless Planetary Flight" thread

Posted: Thu Sep 30, 2010 9:16 pm
by strook
I didnt debug the texture Part because i think i have to Know what à diffuse Map etc is and how they are loaded in- i mean what Must i so in Blender that i get à correct .mat file with allthe textures?

Re: The official "Seamless Planetary Flight" thread

Posted: Thu Sep 30, 2010 10:41 pm
by klauss
Not sure what you have to do in blender, but if you have a textures/planets/forest.texture in your data folder and it's a png, jpg, bmp or a dds surface (the formats supported by VS), then it should be ok.

If not, debug output should state what's wrong.

Re: The official "Seamless Planetary Flight" thread

Posted: Sat Oct 02, 2010 6:16 pm
by strook
I cant give you any Screenshots yet, but i have Found out that i modified old Code that didnt work, but the experience that i collected let me modify the actual Code that creates à sphere with 1000x1000 Segments with athmosphere and textures. There is à Bug, too in spheregeneric.cpp the athmosphere has exact the Same Size As the surface. So you wont See it. Maybe you should add à multiplcator to The Radius of the athmosphere so that it has multiple heights.

I can modify the stacks and slices of the surface correctly.
You could Save à two dimensional Byte Array, though that represents the surface height of the sphere to Save the General Look of the sphere.

The continuous Terrain Class that should present the surface from lower heights i havent touched yet but it is much implemented in it yet and i don't Know wether it all functionates. There is à Lot of debug work with it to do.

At this Point i can say now that à View of Mountains from 10000 ft is going to Work.

Another question: i want to create the surface in Dependance to the textures that are already there. Can we say that some colors (like Deep Blue for Water) are predefined? I mean if you want to make à texture for à Planet, you'll use certain colors for Water. I could use this Information to heighten only the continents.

Re: The official "Seamless Planetary Flight" thread

Posted: Sat Oct 02, 2010 8:43 pm
by klauss
I don't think you can assume any fixed pallette. I've seen quite a lot of creative planet textures in VS.

Re: The official "Seamless Planetary Flight" thread

Posted: Tue Oct 05, 2010 10:39 am
by strook
here is the newest pic:

all issues are done.

Image
(click on the pic to enlarge)
(planet with 1000x1000 stacks done a mountain top every 8th vertices)

i think i should now go to procedural texture generation.
that improves the detail degree very much.

is it ok that we replace the textures by randomly generated ones?

Re: The official "Seamless Planetary Flight" thread

Posted: Tue Oct 05, 2010 2:41 pm
by charlieg
Or use the textures as seeds for generating terrain? That would probably require some textures to be thrown out (from the discussion before where klauss suggested relying on colours could be a bad idea).

Also, please attach patches, just in case you lose work or in case somebody (well, klauss) has feedback on code style that would be easier to address earlier rather than later.

Re: The official "Seamless Planetary Flight" thread

Posted: Tue Oct 05, 2010 7:29 pm
by strook
I think i'll reduce the bitmaps to Black and White where Black is the Zero height Field.
The height will Be divided in 10 steps from Zero Level .
I have an Array representing the heights where the Zero Level will Be marked and Left out at calculation.
There will Be .png Revision work for extracting the Data.

After i have calculated the height i could modify the textures, depending on how they are painted, maybe, but at First i'll use White for Level 8-10 Brown for Level 7-5 Green for Level 4-2 Yellow for Level 1 and Blue for 0.

After that i'll figure out how to keep the Grid closed with Random Data and more texture work, i think about an alogrythm that creates border Parts.

We could use totally Random planets As well then.

After that i could Complete the continuous Terrain Class and make an overlay Matrix randomly generated or an subdivision surface or use some predefined surfaces for the quads in the viewport.

I think predefined surface Parts would Be the fastest Way and the Terrain could Be saved in à Map.

Re: The official "Seamless Planetary Flight" thread

Posted: Tue Oct 05, 2010 10:09 pm
by strook
I'll Write à program that converts a texture to à b/w Map. On this Way we can easily create heightmaps by putting in the color Range that should Be Black.
I Know this function exists in Photoshop, too, but i Need this function later when creating higher Detail textures randomly and interrogating the height for à higher detail Map and for interrogating the Sea Level.

Re: The official "Seamless Planetary Flight" thread

Posted: Wed Oct 06, 2010 10:31 am
by strook
here is the code:
(in lack of time i'll post only code sniplets)

planet.cpp, Func GamePlanet::GamePlanet:

Code: Select all

...
    if (!wormhole) {
        static int stacks = XMLSupport::parse_int( vs_config->getVariable( "graphics", "planet_detail", "24" ) );
        atmospheric = !(blendSrc == ONE && blendDst == ZERO);
//changed from here on
        //FIXED BUG: the radius of the sphere (the surface) must be a little bit smaller than the athmosphere in order to see the athmosphere
        SphereMesh* m = new SphereMesh( radius * 0.95, 1000, 1000, textname.c_str(), technique, NULL, inside_out, blendSrc, blendDst, false, 0.0, M_PI, 0.0, 2*M_PI, MIPMAP, false, true); //<--there is the last var is added and remarks that a planet surfsce sphere //shall be generated, it is the surface var below, add it to the class constructor and //InitSphere; set stacks and slices to 1000
        meshdata.push_back( m );
...
gl_sphere_list.cpp, func GFXSphereVertexList::GFXSphereVertexList:

Code: Select all

...
//not changed code
        float rhol[2];
        float thetal[2];
#define g_rho( i ) ((rhol[((i))&1]))
#define g_theta( i ) ((thetal[((i))&1]))

//new code - this creates a basic height map - the only function implemented right now is
//to set a mountain top with all border pieces to zero level
        int   thir  = 2;
        int   four  = 3;
        int pos[stacks+2][slices+4];
        if(surface) {
            for(int i=0; i<stacks; i+=2) {
                //this row must be zero cause of alignment - maybe there is only one
                //stack needed
                pos[i][fir] = 0;
                pos[i][sec] = 0;
                pos[i+sec][fir] = 0;
                pos[i+sec][sec] = 0;
                for(int j=1; j<slices; j+=4)
                        //there are 
                        //the middle part that marks the mountain top
                        pos[i+fir][j+fir] = 0; //top border
                        pos[i+fir][j+sec] = 1; //mountain top first row
                        pos[i+sec][j+fir] = 1; //mountain top second row - must be at same
                                                     // level with first else the stacks are not linked
                        pos[i+sec][j+sec] = 0; //bottom border
                        
                        //the right border
                        pos[i+fir][j+thir] = 0;
                        pos[i+fir][j+four] = 0;
                        pos[i+sec][j+thir] = 0;
                        pos[i+sec][j+four] = 0;
                 }
            }
        }

....
//not changed
                //texcoords
                vertexlist[j*2+fir].s = GetS( g_theta( j ), theta_min, theta_max );                 //1-s;
                vertexlist[j*2+fir].t = GetT( g_rho( i ), rho_min, rho_max );                 //t;
//changed from here on
                //position
                if(!surface) {
                    vertexlist[j*2+fir].x = x*radius;
                    vertexlist[j*2+fir].z = -y*radius;
                    vertexlist[j*2+fir].y = z*radius;
                } else {
                    if(pos[i][j] == 0) {
                        vertexlist[j*2+fir].x = x*radius;
                        vertexlist[j*2+fir].z = -y*radius;
                        vertexlist[j*2+fir].y = z*radius;
                    } else {
                        vertexlist[j*2+fir].x = x*radius*1.005; //here is the terrain raised top
                                                                            //vertex of the stack
                        vertexlist[j*2+fir].z = -y*radius*1.005;
                        vertexlist[j*2+fir].y = z*radius*1.005;
                    }
                }
...




//not changed
                //texcoords
                vertexlist[j*2+sec].s  = GetS( g_theta( j ), theta_min, theta_max );                 //1-s;
                vertexlist[j*2+sec].t  = GetT( g_rho( i+1 ), rho_min, rho_max );                 //t - dt;
//changed from here on
                //position
                if(!surface) {
                    vertexlist[j*2+sec].x = x*radius;
                    vertexlist[j*2+sec].z = -y*radius;
                    vertexlist[j*2+sec].y = z*radius;
                } else {
                    if(pos[i+1][j] == 0) {
                        vertexlist[j*2+sec].x = x*radius;
                        vertexlist[j*2+sec].z = -y*radius;
                        vertexlist[j*2+sec].y = z*radius;
                    } else {
                        vertexlist[j*2+sec].x = x*radius*1.005; //here too - bottom vertex
                        vertexlist[j*2+sec].z = -y*radius*1.005;
                        vertexlist[j*2+sec].y = z*radius*1.005;
                    }
                }
//not changed
                s       += ds;
...

Re: The official "Seamless Planetary Flight" thread

Posted: Thu Oct 07, 2010 6:03 pm
by strook
The last days i modified the texture Class. It has an Extension that there can Be à function given at load Time to make texture Operations.
I created the Code that creates à Simple heightmap (height 0-1) from à texture. It can extrapolate, for example, the Water Part from à carribean texture.
All you Need to do is rename the textures by their Type.
For example, if you rename à Planet texture blah.texture to blah.carribean.texture (the only One Type supported yet) , the Blue Part of the texture will generate the 0 part of the heightmap.
It has to Be debugged, though, but i think in à few days i have First results.

Re: The official "Seamless Planetary Flight" thread

Posted: Thu Oct 07, 2010 7:32 pm
by strook
I Know now how to create the Terrain.
As http://http.developer.nvidia.com/GPUGem ... _ch01.html
says i Need to create voxels from the heightmap. Theese are cubic objects whith which multiple forms of Terrain can Be created mainly with the shader "Noise " function.
I havent Seen any shader Effects in vs yet, so i think i'll Need to Write the implementation myself.
There is already shader functionality in freeorion, but it uses Ogre. But ogre is based on OpenGL and OpenGL supports with Version 2.0 shader functionality.

When i have à voxel i can create à 3d surface in it by subdividing it to other voxels and Setting the border vertices with the Noise func.

This Terrain can't Be saved, but One can supply predefined heightmap Parts where for example a Base could Be.

Re: The official "Seamless Planetary Flight" thread

Posted: Fri Oct 08, 2010 2:44 am
by klauss
Just what version of VS are you using?

Because ever since 0.5.0 VS has supported shaders. Just fire up vssetup and see the shader settings combo.

Somehow from your screenshots I gather they're not working or not enabled. You probably want to get them working before moving further with that technique, but know that nVidia's voxel technique has many unresolved issues. (it's pretty cool anyway).

Re: The official "Seamless Planetary Flight" thread

Posted: Sat Oct 09, 2010 9:40 am
by strook
the actual svn dev code.
my pics are from the landing paradise of the unitConverter.
there are vertex shader and fragment shader progs and the code, which is initialized in the technique class, but it seems that there is no technique initialized. the technique string is empty as is debug the technique for cephid 17A, the start point of the campaign.

also i have initialized the code for image manipulation, it was not used.
here is the code:

in vsimage, func unsigned char* VSImage::ReadImage( VSFile *f, textureTransform *t, bool strip, VSFile *f2 ):

Code: Select all

...
//not modified
        case JpegImage:
            ret = this->ReadJPEG();
            break;
        case BmpImage:
            ret = this->ReadBMP();
            break;
        default:
            vs_dprintf( 1, "%s\n", img_file->GetFilename().c_str() );
            ret = NULL;
        }
//modified from here on
        if (t) {
           unsigned char* r[sizeY];
           for( int i=0; i < sizeY; i++)
               r[i] = &ret[ sizeX * img_depth/8 * i ];
           unsigned char* tmp_ret = (*t)(img_depth, img_color_type, sizeX, sizeY, r);
           free( ret );
           ret = tmp_ret;
        }
//not modified
        return ret;
...
although the transform code doesn't work anyway yet, it wont transform actual images, it does nothing yet, but i'm on it.

Re: The official "Seamless Planetary Flight" thread

Posted: Sun Oct 10, 2010 10:27 am
by strook
there was a bug in my code. the real code is:

Code: Select all

        if (t) {
           unsigned char** rp = new unsigned char*[sizeY];
           for (unsigned int i = 0; i < sizeY; i++) {
               rp[i] = new unsigned char[sizeX * img_depth/8];
               memcpy( rp[i], ret+(sizeX * img_depth/8 * i), sizeX * img_depth/8 );
           }
           free( ret );
           ret = (*t)(img_depth, img_color_type, sizeX, sizeY, rp);
           for (int i = 0; i < sizeY; i++)
               free(rp[i]);
           free(rp); 
        }


Re: The official "Seamless Planetary Flight" thread

Posted: Sun Oct 10, 2010 11:58 am
by breese
strook wrote:there was a bug in my code. the real code is:

Code: Select all

        if (t) {
           unsigned char** rp = new unsigned char*[sizeY];
           for (unsigned int i = 0; i < sizeY; i++) {
               rp[i] = new unsigned char[sizeX * img_depth/8];
               memcpy( rp[i], ret+(sizeX * img_depth/8 * i), sizeX * img_depth/8 );
           }
           free( ret );
           ret = (*t)(img_depth, img_color_type, sizeX, sizeY, rp);
           for (int i = 0; i < sizeY; i++)
               free(rp[i]);
           free(rp); 
        }

There is a subtle bug (or compatibility problem) in the above code.

The rp and rp arrays were allocated with new[], so they must be deallocated with delete[], not free().

Maybe your t function does the same with ret, which will eventually be freed with free().

Re: The official "Seamless Planetary Flight" thread

Posted: Mon Oct 11, 2010 11:44 am
by strook
here is the image transform update:
there was transform functionality to .jpeg and .png files.
i added the functionality to .bmp and dds files, too.
even to dds cubemaps.

here is the code:
vsimage.cpp, func unsigned char* VSImage::ReadDDS():

Code: Select all

...
//old code
        if ( header.dcaps2&(DDS_CUBEMAP|DDS_CUBEMAP_ALLFACES) ) {
            vs_dprintf(3, "Reading Cubemap %s\n", img_file->GetFilename().c_str() );
            inputSize = inputSize*6;
            this->img_sides =
                SIDE_POS_X|SIDE_NEG_X
                |SIDE_POS_Y|SIDE_NEG_Y
                |SIDE_POS_Z|SIDE_NEG_Z;                  //all sides, we don't support partial DDS files
            this->img_color_type = 998;             //Cubemap'd dds
        } else {
            this->img_color_type = 999;              //Regular DDS
        }
//new code
        if(tt) {
            vs_dprintf(3, "Doing a transformation \n");

            JSAMPARRAY     row_pointers = NULL; //Output row buffer
            row_pointers    = (unsigned char**) malloc( sizeof (unsigned char*)*this->sizeY );
            s = (unsigned char*) malloc( inputSize+3 );
            unsigned char* s2 = s+2;

            sprintf( (char*) s, "%i", header.nmips );         //if cubemap, mips per face

            if(img_color_type = 998) {
                for(int side = 0; side < 6; side++) { //side is a side of the cubemap
                    int side_offset = inputSize/6*side;
                    int row_offset = side_offset/this->sizeY;

                    for (unsigned int i = 0; i < this->sizeY; i++)
                        row_pointers[i] = &s2[i*row_offset];

                    vs_dprintf(3, "transforming %i \n", side);

                    img_file->Read( s2+side_offset, inputSize/6 );

                    unsigned char *result = s2+side_offset;
                    result = (*tt)(this->img_depth, this->img_color_type, this->sizeX, this->sizeY, row_pointers);
                    memcpy( s2+side_offset, result, inputSize/6 );
                    free(result);
                    result = NULL;
                }
            } else {
                for (unsigned int i = 0; i < this->sizeY; i++)
                    row_pointers[i] = &s2[i*inputSize/this->sizeY];

                img_file->Read( s+2, inputSize );

                unsigned char *result = s;
                result = (*tt)(this->img_depth, this->img_color_type, this->sizeX, this->sizeY, row_pointers);
                free( s );
                s = result;
            }
        } else {
            s = (unsigned char*) malloc( inputSize+3 );
            sprintf( (char*) s, "%i", header.nmips );         //if cubemap, mips per face
            img_file->Read( s+2, inputSize );
        }
//old code
        //At the end of execution what we have is the following:
        //s contains the number of mipmaps then the main texture and all it's mipmaps
        //sizeY is the height of the initial texture, sizeX is the width.
        //mode is the compressed format of the texture. It is assumed to be rgba
        //depth is the depth of the uncompressed image. not sure where this is used
        //nmaps is the number of mipmaps
        return s;
...
vsimage.cpp, func unsigned char* VSImage::ReadBMP():

Code: Select all

...
//old code
            for (int palcount = 0; palcount < 256; palcount++) {
                img_file->Read( paltemp, SIZEOF_RGBQUAD );
                ctemp      = paltemp[0];
                paltemp[0] = paltemp[2];
                paltemp[2] = ctemp;
                paltemp   += 4;                 //pal size
            }
            if (!data)
                return NULL;
//new code
            if(tt) {
                vs_dprintf(3, "Doing a transformation \n");

                JSAMPARRAY     row_pointers = NULL; //Output row buffer
                row_pointers    = (unsigned char**) malloc( sizeof (unsigned char*)*this->sizeY );

                unsigned long stride = sizeof (unsigned char)*this->img_depth/8;
                for (unsigned int i = 0; i < this->sizeY; i++)
                    row_pointers[i] = &data[i*stride*this->sizeX];
                unsigned int count = 0;

                for (int i = sizeY-1; i >= 0; i--)
                    for (unsigned int j = 0; j < sizeX; j++)
                        img_file->Read( (void*)&row_pointers[i][j], sizeof (unsigned char) );

                unsigned char *result = data;
                result = (*tt)(this->img_depth, this->img_color_type, this->sizeX, this->sizeY, row_pointers);
                free( data );
                data = result;
            } else {
                for (int i = sizeY-1; i >= 0; i--)
                    for (unsigned int j = 0; j < sizeX; j++)
                        img_file->Read( data+j+i*sizeX, sizeof (unsigned char) );
            }
        }
//old code
        return data;
however, the .bmp code isn't tested yet, but there are just minor differences from the other running code.

Re: The official "Seamless Planetary Flight" thread

Posted: Mon Oct 11, 2010 1:26 pm
by charlieg
Keep it up! Enjoying seeing this progress. :D

Re: The official "Seamless Planetary Flight" thread

Posted: Mon Oct 11, 2010 8:11 pm
by strook
heightmaps are odd i ll try now another way for the lower orbit

Image

i ll use dds maps with 32 bpp as voxels.
the rgb value is the color and
the alpha channel will be 12 x 20 steps for the sides of a voxel.
the rest 12 numbers index the edge that is the solid part in the voxel.
Image
feel free to supply your suggestions.

this must be set up in the shaders....

Re: The official "Seamless Planetary Flight" thread

Posted: Mon Oct 11, 2010 9:40 pm
by Haggis
It's been a while since I've visited this forum. In the mean time I've been playing a "new" spacesim called Pioneer. Of course I don't want to advertise too much for a different game here on the VS forums, but I thought I'd share this information anyway since Pioneer features a very, very impressive seamless planetary terrain engine. Maybe programmers (like Strook or Klaus?) can get some inspiration from it and try to work out something similar for Vegastrike. In fact, I see Strook is already working on something. I hope it'll work cause that's what I always wanted! I'm sure Vegastrike will benefit greatly from the atmosphere.

Anyway, Pioneer is visually a very nice game to play. It's almost like a dream come true for me. The only downside is the lack of gameplay but maybe that will change in the future. For those of you interested to see what Pioneer looks like, I've created a litte Youtube video. I hope I'm allowed to place the link here:

http://www.youtube.com/watch?v=1aVf-8qVdsg

I´ll be checking on Vegastrike on a more regular basis now that I know Strook is busy adding seamless planetary flight.

Re: The official "Seamless Planetary Flight" thread

Posted: Tue Oct 12, 2010 9:34 am
by strook
after concerning with voxels and cubemaps, i give up trying to map a cubemap to a standard map.
i have now the exact implementation of the voxel technique on the gpu.

this means, you can forget using predefined texture maps for planet texturizing.
anyway, therir number is just limited.

do you want to see in an huge universe ~20 different planets, odd textured?

Re: The official "Seamless Planetary Flight" thread

Posted: Wed Oct 13, 2010 5:26 pm
by strook
along what i ve read, i created code that generates a sphere this way:
the data will be stored basically as a byte array, each bit of a byte represents an edge of a voxel.
there will be a header for each cube of voxels where some values are stored like position and subdivide factor.
the subdivide factor determines the size of a cube that is inserted at the position of an existing larger voxel, when coming nearer to the surface and more detail is needed.
a voxel can be determined not to be drawed if all bits are zero( value=0 (air)) or 1 (value=255 (inner rock)).
later additionally a for side of a voxel a byte value,not just the edge data, will be used, thus extracting interpolarisation data for the resulting vertices.

creating the basic cube data (the sphere) is done by the cpu, but the rest is done on the gpu.
in the moment, i'm on creating the lookup tables for extracting the vertex data, which is done by the gpu shader, which is time consuming.

this would be a different implementation like it exists now on the shaders.

a water, lava or whatever surface could easily be done by placing a simple sphere, where we have already the code from, with the approitate radius.

also there will be multiple ways to modify the terrain.