Results 1 to 6 of 6

Thread: faking standard opengl t&l with GL_NV_vertex_program

  1. #1
    Senior Member Regular Contributor
    Join Date
    Mar 2001
    Posts
    469

    faking standard opengl t&l with GL_NV_vertex_program

    Hi

    I would like to replicate standard opengl's lighting calculation using vertex programs to modify the lightings color selecting. Instead of just linear interpolation between two vertices colors I would like to use a 1d texture map as a gradient(perhaps a 2d texture for additional specular gradients).
    Texture coordinates would index the texture.
    this would also be useful for doing toon shading. I tried it but i had some problems.
    My goal is to use vertex and vertex state programs as easy and functional as gllightf...

    for example standard t&l:
    // scene positioning
    // local viewer, local light, no attenuation
    glLoadIdentity();
    glTranslatef(scene pos)// based upon user input
    glRotatef(scene rot)// -""-
    // light in object coorinates
    glLightf(light position)
    ...
    ...

    // draw some object
    glPushMatrix()
    glRotatef(object yrot ...)
    glutSoloidTeapot
    glPopMatrix();
    // another object
    glPushMatrix()
    glTranslatef(object pos ...)
    glutSoloidTeapot
    glPopMatrix();

    using vertexprograms:

    scene and object positioning using matrices

    glLoadIdentity();
    glTranslatef(scene pos)// based upon user input
    glRotatef(scene rot)// -""-
    // light in object coorinates

    //using vertex state program to calc lights eye coordinates using current modelview matrix
    glExecuteProgramNV(...,lightpos);
    ...
    ...
    glEnable(GL_VERTEX_PROGRAM_NV);
    glEnable(GL_TEXTURE_2d);
    // draw some object
    glBindTExture(material one gradient)
    glPushMatrix()
    glRotatef(object yrot ...)
    glutSoloidTeapot
    glPopMatrix();
    // another object
    glBindTExture(material two gradient)
    glPushMatrix()
    glTranslatef(object pos ...)
    glutSoloidTeapot
    glPopMatrix();

    I tested it in a program where I could switch between opengl lighting and vertex program lighting, but I recognized that both results were unequal.the light moved with the scene but when i rotated the scene the diffuse lighting changed, wether i wanted to stay the object const within my scene space.

    tracking of MODELVIEW_PROJECTION
    MODELVIEW
    MODELVIEW, INVERSE_TRANSPOSE
    in the vertex state program i do following

    matrix multiplication program paramter v[0] with modelview matrix and storing it in constant register


    the vertex program
    matrix multiplication v[OPOS] with MODELVIEWPROJECTION and storing it in o[HPOS]

    matrix multiplication v[OPOS] with MODELVIEW and storing it in a temporary register

    matrix mult v[NRML] with MODELVIEW_INVERSE_TRANSPOSE
    set length to 1

    vector vertex --> light
    set length to 1

    dot product normal with vertex-->light vector


    use as o[TEX0].x // 1D texture clamping active; GL_DECAL environment linear (greyscale)gradient -> should be equal do standard opengl t&l

    Can anyone help ??

    ScottManDeath

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    3,574

    Re: faking standard opengl t&l with GL_NV_vertex_program

    Can anyone help ??
    Maybe you should show us the actual vertex program and the rest of your code rather than this pseudo-code. The actual bug is likely not in the code you've given us.

  3. #3
    Senior Member Regular Contributor
    Join Date
    Mar 2001
    Posts
    469

    Re: faking standard opengl t&l with GL_NV_vertex_program

    [Hi

    you are right, pseudo code seems not be very helpful
    here are the important parts of my code.

    I changed the light calculation form eye space to object space.

    The vertex state program transform the light position v[0]
    using the tracked modelview matrix temporary into eye space.

    The vertex program uses the light position and converts it into object space by
    applying the current inverse modelviewmatrix. then the diffuse dot product is
    calculated by dotting the vertex' normal with the (normalized)vertex light vector
    Now diffuse lighting works as espected. because I specified the lights psosition in the
    current scene view space it stays as I move and rote the view .

    For the specular part I have a problem. the specular highlight moves when I move the light or the object but not when
    I rotate my scene view??

    tracked matrices and program parameters:
    (set up once after loading vertex program from disk)
    // ModelViewProjection in c[0] to c[3]
    glTrackMatrixNV(GL_VERTEX_PROGRAM_NV,0,GL_MODELVIE W_PROJECTION_NV,GL_IDENTITY_NV);
    // ModelView in c[4] to c[7]
    glTrackMatrixNV(GL_VERTEX_PROGRAM_NV,4,GL_MODELVIE W,GL_IDENTITY_NV);
    // Modelview invers transposed in c[8] to c[11]
    glTrackMatrixNV(GL_VERTEX_PROGRAM_NV,8,GL_MODELVIE W,GL_INVERSE_TRANSPOSE_NV);
    // Modelview invers in c[8] to c[11]
    glTrackMatrixNV(GL_VERTEX_PROGRAM_NV,12,GL_MODELVI EW,GL_INVERSE_NV);
    // helpful numbers
    glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV,95,0.0 f,0.5f,1.0f,2.0f);

    Vertex State Program
    !!VSP1.0

    # lightposition to eye space
    DP4 R1.x,v[0],c[4];
    DP4 R1.y,v[0],c[5];
    DP4 R1.z,v[0],c[6];
    DP4 R1.w,v[0],c[7];
    MOV c[16],R1;

    END


    Vertex program//not optimized
    !!VP1.0
    # c
    # 0 MODELVIEW_PROJECTION_0
    # 1 MODELVIEW_PROJECTION_1
    # 2 MODELVIEW_PROJECTION_2
    # 3 MODELVIEW_PROJECTION_3
    # 4 MODEL_VIEW_0
    # 5 MODEL_VIEW_1
    # 6 MODEL_VIEW_2
    # 7 MODEL_VIEW_3
    # 8 MODEL_VIEW_INVERSE_TRANSPOSE_0
    # 9 MODEL_VIEW_INVERSE_TRANSPOSE_1
    # 10 MODEL_VIEW_INVERSE_TRANSPOSE_2
    # 11 MODEL_VIEW_INVERSE_TRANSPOSE_3
    # 12 MODEL_VIEW_INVERSE_0
    # 13 MODEL_VIEW_INVERSE_1
    # 14 MODEL_VIEW_INVERSE_2
    # 15 MODEL_VIEW_INVERSE_3
    # 16 light position in eye space
    # 32 some material coeefficients 0.0f,32.0f,64.0f,128.0f;
    # 95 0.0f,0.5f,1.0f,2.0f
    # temp register
    # R0
    # R1
    # R2
    # R3
    # R4
    # R5
    # R6
    # R7
    # R8 > Temp

    #*************** Common ************************************

    # Vertex --> clip space
    MOV R11,v[OPOS];
    DP4 o[HPOS].x, R11, c[0];
    DP4 o[HPOS].y, R11, c[1];
    DP4 o[HPOS].z, R11, c[2];
    DP4 o[HPOS].w, R11, c[3];


    # vertex normal in object space
    MOV R1,v[NRML];

    # Normal --> length 1
    DP3 R1.w, R1, R1;
    RSQ R1.w, R1.w;
    MUL R1.xyz, R1, R1.w;

    #R1 contains normal object space

    # light in object space(from eye space)
    MOV R3,c[16];
    DP4 R4.x,R3,c[12];
    DP4 R4.y,R3,c[13];
    DP4 R4.z,R3,c[14];
    DP4 R4.w,R3,c[15];

    #R4 contains light pos object space

    # ---------------DIFFUSE-------------------------

    # vector light --> vertex in object space
    ADD R0,-v[OPOS],R4;

    # normalize vector light --> vertex
    DP3 R0.w, R0, R0;
    RSQ R0.w, R0.w;
    MUL R0.xyz, R0, R0.w;

    #R0 contains vector light vertex in object space

    # dot normal with vertex light vector

    # for lit instruction
    DP3 R7.x, R0, v[NRML];

    # ---------------SPECULAR------------------------
    # still buggy, shine only moves when light or object moves but not when
    # scene is moved
    MOV R6,c[95].x; # zero

    #R6 contains eye pos

    #build halfway vector into R9
    ADD R9,R6,R4;

    #normalize R9
    DP3 R9.w, R9, R9;
    RSQ R9.w, R9.w;
    MUL R9.xyz, R9, R9.w;

    #dot normal with half vector
    DP3 R7.y,R9,R1;

    #material shine
    MOV R7.w,c[32].x;

    # do lighting calcualtion
    LIT R8,R7;

    # for use with light map
    #MOV o[TEX0].x,R8.y;
    #MOV o[TEX0].y,R8.z;

    # only grey colors
    #primary diffuse color
    MOV o[COL0],R8.y;
    #secondary specular color;
    MOV o[COL1],R8.z;

    END


    // main program (partially
    // global variables changed by user interface/keystrokes/mouse
    // scene rotation
    float srotation[16]={1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f
    };
    // Scenentranslation
    float stranslation[3]={0.0f, 0.0f, -4.0f };

    // light
    float light_pos[4] ={0.0f, 0.0f, 2.0f, 1.0f};
    float light_ambient[4]={0.0f, 0.0f, 0.0f, 1.0f};
    float light_diffuse[4]={1.0f, 1.0f, 1.0f, 1.0f};
    float light_specular[4]={1.0f,1.0f, 1.0f, 1.0f};
    float light_attenuation[4]={0.0f,1.0f,0.0f,0.0f};
    //Material
    float mat_ambient[4]= {0.0f, 0.0f, 0.0f, 1.0f};
    float mat_diffuse[4]= {0.0f, 0.0f, 0.0f, 1.0f};
    float mat_specular[4]= {1.0f, 1.0f, 1.0f, 1.0f};
    float mat_shine = 64;
    // use lighting with glLightf...
    int gllighting=1;
    // use vertex program
    int usevp=1;

    // the render loop
    void OnInit()
    {
    glClearColor(0.5f,0.5f,0.5f,1.0f);
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_LIGHT0);

    float amb[4]={0.0f,0.0f,0.0f,1.0f};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,1);

    // glTrackMatrixNV ... see begin of post

    }
    void OnRender()
    {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glLoadIdentity();
    // Scene
    glTranslatef(stranslation[0],stranslation[1],stranslation[2]);
    glMultMatrixf(srotation);

    glPushMatrix();// storing of scene view
    ShowAxes();// jut draws coordinate systems axes with labels

    // where is the light ...
    glPushMatrix();
    glTranslatef(light_pos[0],light_pos[1],light_pos[2]);
    glColor3f(1.0f,1.0f,1.0f);
    glutSolidSphere(0.2f,16,16);
    glPopMatrix();

    if(gllighting&& !usevp)
    {
    glEnable(GL_LIGHTING);
    glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);// not meant to be a performance killer
    glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
    glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
    glLightfv(GL_LIGHT0,GL_CONSTANT_ATTENUATION,light_ attenuation+1);
    glLightfv(GL_LIGHT0,GL_LINEAR_ATTENUATION,light_at tenuation+2);
    glLightfv(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,light _attenuation+3);
    glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialf(GL_FRONT,GL_SHININESS,mat_shine);

    glLightfv(GL_LIGHT0,GL_POSITION,light_pos);

    }
    else if(usevp)
    {
    glEnable(GL_VERTEX_PROGRAM_NV);
    glExecuteProgramNV( GL_VERTEX_STATE_PROGRAM_NV, vspid, light_pos );
    glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV,32,mat _shine,32.0f,64.0f,128.0f);
    glBindProgramNV( GL_VERTEX_PROGRAM_NV, vpid );
    }

    glutSolidTeapot(0.5f);

    if(gllighting)
    {
    glDisable(GL_LIGHTING);
    }
    if(usevp)
    {
    glDisable(GL_VERTEX_PROGRAM_NV);
    }


    glPopMatrix();// scene view

    glPopMatrix();// matrix on entry of OnRender

    glutSwapBuffers();
    }

    I hope this will clear something a little bit up

    Bye ScottManDeath

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    2,411

    Re: faking standard opengl t&l with GL_NV_vertex_program

    If all you want is a custom diffuse lighting solution, it's much easier to do that using NORMAL_MAP texgen mode and the appropriate texture matrix.
    "If you can't afford to do something right,
    you'd better make sure you can afford to do it wrong!"

  5. #5
    Senior Member Regular Contributor
    Join Date
    Mar 2001
    Posts
    469

    Re: faking standard opengl t&l with GL_NV_vertex_program

    Originally posted by jwatte:
    If all you want is a custom diffuse lighting solution, it's much easier to do that using NORMAL_MAP texgen mode and the appropriate texture matrix.
    Hi
    that sounds interesting, what is that exactly. Which extension has to be used ?
    This would be sufficient for diffuse lighting but what can I do for specular lighting ?

    Bye
    ScottManDeath

  6. #6
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    2,411

    Re: faking standard opengl t&l with GL_NV_vertex_program

    NORMAL_MAP texgen is a standard part of OpenGL 1.3 and later; it's part of the cubemap extension before that. You can set up the texture matrix to collapse the 3 coordinates to a 1D texture; you don't need to bind a cube map texture just because you're using NORMAL_MAP texgen mode.

    I believe that the reflective environment map mode _might_ be used for specular with the right incantations, but I haven't delved into the math to see if that's right or not. Intuitively, you'd use the same trick of collapsing a 3D texture vector into a 1D texture using the matrix, and rotate that matrix by the half angle vector, perhaps?
    "If you can't afford to do something right,
    you'd better make sure you can afford to do it wrong!"

Similar Threads

  1. Faking an accumulation buffer in OpenGL es
    By Cubby208 in forum OpenGL: Advanced Coding
    Replies: 7
    Last Post: 12-04-2015, 01:20 PM
  2. Standard opengl pipeline
    By LeoRocha in forum OpenGL: GLSL
    Replies: 4
    Last Post: 07-27-2009, 08:18 AM
  3. GL_VERTEX_SHADER_EXT vs GL_NV_vertex_program
    By WeissNix in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 03-22-2002, 12:16 PM
  4. GL_NV_vertex_program exposure w/ GF2
    By bsenftner in forum OpenGL: Advanced Coding
    Replies: 1
    Last Post: 06-09-2001, 11:55 PM
  5. GL_NV_vertex_program extension (l'Arlesienne)
    By Eric in forum OpenGL: Advanced Coding
    Replies: 1
    Last Post: 11-06-2000, 06:57 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