Subversion Repositories gelsvn

Rev

Rev 370 | Blame | Last modification | View Log | RSS feed

/*
 *  wireframe.cpp
 *  GEL
 *
 *  Created by J. Andreas Bærentzen on 05/08/08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */
#include <iostream>
#include <GLGraphics/glsl_shader.h>
#include "wireframe.h"

using namespace std;
using namespace GLGraphics;

namespace 
{
        const string vp = 
        "#version 120\n"
        "#extension GL_EXT_gpu_shader4 : enable\n"
        "\n"
        "void main(void)\n"
        "{\n"
        "   gl_Position =  ftransform();\n"
        "}\n";
        
        const string gp = 
        "#version 120\n"
        "#extension GL_EXT_gpu_shader4 : enable\n"
        "\n"
        "uniform vec2 WIN_SCALE;\n"
        "noperspective varying vec3 dist;\n"
        "void main(void)\n"
        "{\n"
        "  vec2 p0 = WIN_SCALE * gl_PositionIn[0].xy/gl_PositionIn[0].w;\n"
        "  vec2 p1 = WIN_SCALE * gl_PositionIn[1].xy/gl_PositionIn[1].w;\n"
        "  vec2 p2 = WIN_SCALE * gl_PositionIn[2].xy/gl_PositionIn[2].w;\n"
        "  \n"
        "  vec2 v0 = p2-p1;\n"
        "  vec2 v1 = p2-p0;\n"
        "  vec2 v2 = p1-p0;\n"
        "  float area = abs(v1.x*v2.y - v1.y * v2.x);\n"
        "\n"
        "  dist = vec3(area/length(v0),0,0);\n"
        "  gl_Position = gl_PositionIn[0];\n"
        "  EmitVertex();\n"
        "       \n"
        "  dist = vec3(0,area/length(v1),0);\n"
        "  gl_Position = gl_PositionIn[1];\n"
        "  EmitVertex();\n"
        "\n"
        "  dist = vec3(0,0,area/length(v2));\n"
        "  gl_Position = gl_PositionIn[2];\n"
        "  EmitVertex();\n"
        "\n"
        "  EndPrimitive();\n"
        "}\n";
        
        const string fp =
        "#version 120\n"
        "#extension GL_EXT_gpu_shader4 : enable\n"
        "\n"
        "noperspective varying vec3 dist;\n"
        "const vec4 WIRE_COL = vec4(1.0,0.0,0.0,1);\n"
        "const vec4 FILL_COL = vec4(1,1,1,1);\n"
        "\n"
        "void main(void)\n"
        "{\n"
        "       float d = min(dist[0],min(dist[1],dist[2]));\n"
        "       // Compute intensity\n"
        "\n"
        "       float I = exp2(-2*d*d);\n"
        "       gl_FragColor = I*WIRE_COL + (1.0 - I)*FILL_COL;\n"
        "}\n";
        
        static GLhandleARB prog_P0;
}


void initialize_wireframe_shaders()
{
        static bool washere = false;
        if(!washere)
        {
                washere = true;
                
                // Create s     haders directly from file
                GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, vp);
                GLuint gs = create_glsl_shader(GL_GEOMETRY_SHADER_EXT, gp);
                GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, fp);
                
                // Create the program
                prog_P0 = glCreateProgram();
                
                // Attach all shaders
                if(vs) glAttachShader(prog_P0, vs);
                if(gs) glAttachShader(prog_P0, gs);
                if(fs) glAttachShader(prog_P0, fs);
                
                // Specify input and output for the geometry shader. Note that this must be
                // done before linking the program.
                glProgramParameteriEXT(prog_P0,GL_GEOMETRY_INPUT_TYPE_EXT,GL_TRIANGLES);
                glProgramParameteriEXT(prog_P0,GL_GEOMETRY_VERTICES_OUT_EXT,3);
                glProgramParameteriEXT(prog_P0,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_TRIANGLE_STRIP);
                
                // Link the program object and print out the info log
                glLinkProgram(prog_P0);
        }
}

void enable_wireframe()
{
        glUseProgram(prog_P0);
        
        GLint vpdim[4];
        glGetIntegerv(GL_VIEWPORT,vpdim); 
        
        // Set the value of a uniform
        glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), 
              static_cast<float>(vpdim[2]/2), static_cast<float>(vpdim[3]/2));
}