Subversion Repositories gelsvn

Rev

Rev 594 | Go to most recent revision | Blame | Compare with Previous | 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 "SinglePassWireframeRenderer.h"

using namespace CGLA;
using namespace std;
using namespace GLGraphics;

namespace 
{
        const string vp = 
        "#version 120\n"
        "#extension GL_EXT_gpu_shader4 : enable\n"
        "varying vec4 diffuseIn;\n"
        "void main(void)\n"
        "{\n"
        "   float ndot = dot(gl_NormalMatrix*gl_Normal,vec3(0,0,1));\n"
        "   diffuseIn = vec4(0.7,0.9,1,1) * abs(ndot);\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"
        "varying in vec4 diffuseIn[3];\n"
        "varying vec4 diffuse;\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"
        "  diffuse = diffuseIn[0];\n"
        "  EmitVertex();\n"
        "       \n"
        "  dist = vec3(0,area/length(v1),0);\n"
        "  gl_Position = gl_PositionIn[1];\n"
        "  diffuse = diffuseIn[1];\n"
        "  EmitVertex();\n"
        "\n"
        "  dist = vec3(0,0,area/length(v2));\n"
        "  gl_Position = gl_PositionIn[2];\n"
        "  diffuse = diffuseIn[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"
        "varying vec4 diffuse;\n"
        "uniform vec4 WIRE_COL;\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)*diffuse;\n"
        "}\n";
        
}


namespace GLGraphics
{
        
        SinglePassWireframeRenderer::SinglePassWireframeRenderer()
        {               
                static bool was_here = false;
                if(!was_here)
                {
                        was_here = true;
                        // Create s     haders directly from file
                        static GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, vp);
                        static GLuint gs = create_glsl_shader(GL_GEOMETRY_SHADER_EXT, gp);
                        static GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, fp);
                        
                        // Create the program
                        static GLuint _prog = glCreateProgram();
                        prog = _prog;
                        
                        // Attach all shaders
                        if(vs) glAttachShader(prog, vs);
                        if(gs) glAttachShader(prog, gs);
                        if(fs) glAttachShader(prog, fs);
                        
                        // Specify input and output for the geometry shader. Note that this must be
                        // done before linking the program.
                        glProgramParameteriEXT(prog,GL_GEOMETRY_INPUT_TYPE_EXT,GL_TRIANGLES);
                        glProgramParameteriEXT(prog,GL_GEOMETRY_VERTICES_OUT_EXT,3);
                        glProgramParameteriEXT(prog,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_TRIANGLE_STRIP);
                        
                        // Link the program object and print out the info log
                        glLinkProgram(prog);
                }
        }
        
        bool SinglePassWireframeRenderer::enable(const CGLA::Vec3f& line_col)
        {
                GLint o;
                glGetIntegerv(GL_CURRENT_PROGRAM, &o);
                old_prog = o;
                glUseProgram(prog);
                
                GLint vpdim[4];
                glGetIntegerv(GL_VIEWPORT,vpdim); 
                
                // Set the value of a uniform
                glUniform2f(glGetUniformLocation(prog,"WIN_SCALE"), 
                                        static_cast<float>(vpdim[2]/2), static_cast<float>(vpdim[3]/2));
                glUniform4f(glGetUniformLocation(prog,"WIRE_COL"), line_col[0], line_col[1], line_col[2], 0);
                
                return true;
        }
        
        void SinglePassWireframeRenderer::disable()
        {
                glUseProgram(old_prog);
        }
        
}