Results 1 to 5 of 5

Thread: Surfaces

  1. #1
    Senior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    Austria
    Posts
    328

    Surfaces

    Hi all!

    I've a problem. You all know the Tutorial with Heightfield Terrain while using a Bitmap-File.
    I want to make this code better while taking no triangles. I want to bulit the terrain by using Surfaces. I always take 3x3 points which describe my Surface.
    So, now my problem: When I'm using GL_AUTO_NORMAL the lightning isn't correct because of all some points use other tangents.

    How can I make the lightning here correct? I tried it by using my own normals but it didn't work!

    Thanks for every help!!
    greets, Corrail

    Here my code I'm using:
    (If you want the whole Source-Code pls Mail me! corrail@gmx.at)

    ///////////////////////
    // Terrain Variables //
    ///////////////////////

    #define MAPX 31
    #define MAPZ 31
    #define BitMAPX 32
    #define BitMAPZ 32
    #define MAPScale 20.0f

    float terPkt[MAPX][MAPZ][3];

    float terAktPkt[3][3][3];

    ///////////////////////
    // InitializeTerrain //
    ///////////////////////
    // ImageData is the black-white Image

    void InitializeTerrain()
    {

    for (int i = 0; i < MAPZ; i++)
    {
    for (int j = 0; j < MAPX; j++)
    {

    terPkt[j][0] = float(i)*MAPScale;
    terPkt[j][i][1] = (float)imageData[(j*BitMAPZ+i)*3];
    terPkt[j][i][2] = -float(j)*MAPScale;

    terNorm[j][i][0] = 0.0f;
    terNorm[j][i][1] = 0.0f;
    terNorm[j][i][2] = 0.0f;

    }
    }
    }

    ///////////////////////
    // Rendering Terrain //
    ///////////////////////

    glFrontFace(GL_CW);

    for (int a = 0; a < (int)((MAPX-1)/2); a++)
    {
    for (int b = 0; b < (int)((MAPZ-1)/2); b++)
    {
    for (int c = 0; c < 3; c++)
    {
    for (int d = 0; d < 3; d++)
    {
    terAktPkt[c][d][0] = terPkt[2*a+c][2*b+d][0];
    terAktPkt[c][d][1] = terPkt[2*a+c][2*b+d][1];
    terAktPkt[c][d][2] = terPkt[2*a+c][2*b+d][2];
    }
    }

    glColor3f(1.0,1.0,1.0);
    glMap2f(GL_MAP2_VERTEX_3, 0.0, count, 3, 3, 0.0, count, 9, 3, &terAktPkt[0][0][0]);
    glEnable(GL_MAP2_VERTEX_3);

    glMapGrid2f((int)count, 0.0f, count, (int)count, 0.0f, count);
    glEvalMesh2(GL_FILL, 0, (int)count, 0, (int)count);

    }
    }

    glFrontFace(GL_CCW);
    There is a theory which states that if ever anybody discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable.

    There is another theory which states that this has already happened...

  2. #2
    Senior Member Regular Contributor
    Join Date
    May 2000
    Location
    Oxford, England
    Posts
    472

    Re: Surfaces

    Using 3x3 patches will not give you surface continuity. Using patches for that matter will not give you continuity either for that matter. This is the fundamental problem with bezier patches and openGL's implimentation of them.

    The only way you can do it is to tessellate the surface yourself and use a b-spline basis for the surfaces; or tessellate them yourself using the bezier basis and fix the normals yourself so that they work.

    I suppose you could use 4x4 patches and fix the positions of the central 4 points so that they maintain continuity between neihgbouring patches, but that wont be pleasant.

  3. #3
    Senior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    Austria
    Posts
    328

    Re: Surfaces

    Thanks, I thought that...

    But how can I calculate the normals myself and, what is more important, how can I use them with bezier surfaces? Do I have to calculate the normals of each quad in my 3x3 surface or only for the four corner point?
    There is a theory which states that if ever anybody discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable.

    There is another theory which states that this has already happened...

  4. #4
    Senior Member Regular Contributor
    Join Date
    May 2000
    Location
    Oxford, England
    Posts
    472

    Re: Surfaces

    Run a search on this and the advanced forum, I've actually gone into loads of detail in the past that should answer most questions you may have.

    Calculating a bezier curve can be done with :

    Q(t) = (1-t)^3*P1 + 3*(1-t)^2*t*P2 + 3*(1-t)*t^2*P3 + t^3*P4

    where P1 - P4 are the four control points and Q(t) is the final point; and t varies between 0 and 1.

    tessellating a bezier patch involves calculating the points on the four curves going in one direction, and then using those points to form control points for curves in the other direction. This should give you your vertices of the patch.

    To get the normals, differentiate the bezier equation to get an equation that represents the rate of change of the curve. By calculating the rate of change of U & V directions, you'll get two tangents. Do a cross product of those to get the normal at that point on the surface.

    Having calculated the normals for each patch, you'll then have to average them to get them to maintain surface continuity.

    The other way of doing it is to presume that du/dt and dv/dt can be approximated by subtracting neighbouring vertices and use those values (with a couple of hacks) to do the cross product to calculate the normals. Faster, but not as elegant.

    Thirdly, use NURBS surfaces which have the benefit of surface continuity inherant in their structure, and the calculation required for any single point is always identical, no matter how many control points you add, but you'll need some slightly more hectic maths.

    Check out quite a few of the papers on www.gamasutra.com on the subject of bezier patches for more info.

  5. #5
    Senior Member Regular Contributor
    Join Date
    Mar 2002
    Posts
    103

    Re: Surfaces

    Rather than taking the derivative, and doing a cross product for every point, you can generate a degree 5x5 path that represents the normals. The derivative (wrt u) of the bicubic patch is degree 2x3 patch where the control points have been differenced in one direction. Crossing the 2X3 with the 3x2 patch gives a 5x5 patch which can be evaluated to give you the normals of the 3x3 patch at the same u,v coord.

    [This message has been edited by gumby (edited 04-07-2002).]

Similar Threads

  1. More black surfaces
    By in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 09-30-2003, 08:58 AM
  2. Surfaces. Help..
    By hcrogma in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 05-01-2003, 01:44 PM
  3. Help (Surfaces)
    By KurtCob in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 04-25-2001, 08:14 AM
  4. Surfaces & Trimming
    By adrian_helcman in forum OpenGL: Advanced Coding
    Replies: 0
    Last Post: 01-05-2001, 12:41 AM
  5. bezier surfaces
    By Lev in forum OpenGL: Advanced Coding
    Replies: 2
    Last Post: 11-27-2000, 07:55 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean