【OpenGL】几何着色器——Explode爆炸案例

【OpenGL】几何着色器——Explode爆炸案例

原理:计算出法线,将顶点沿着法线方向移动自定义距离,其他不变。

// Normal visualizer
// Fragment Shader
// Graham Sellers
// OpenGL SuperBible
#version 150

precision highp float;

in Fragment
{
    vec4 color;
} fragment;

out vec4 output_color;

void main(void)
{
    output_color = fragment.color;
}
// Cell lighting Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 150

precision highp float;

// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;

uniform vec3 vLightPosition;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;

out Fragment
{
    vec4 color;
} fragment;

void main(void)
{
    // Get surface normal in eye coordinates
    vec3 vEyeNormal = normalMatrix * vNormal;

    // Get vertex position in eye coordinates
    vec4 vPosition4 = mvMatrix * vVertex;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    // Get vector to light source
    vec3 vLightDir = normalize(vLightPosition - vPosition3);

    // Dot product gives us diffuse intensity
    fragment.color = vec4(0.0, 0.0, 0.6, 1.0) * max(0.0, dot(vEyeNormal, vLightDir));

    gl_Position = mvpMatrix * vVertex;
}
// Normal visualizer
// Fragment Shader
// Graham Sellers
// OpenGL SuperBible
#version 150

precision highp float;

in vec4 color;

out vec4 output_color;

void main(void)
{
    output_color = color;
}
// Normal Visualizer
// Geometry Shader
// Graham Sellers
// OpenGL SuperBible
#version 150

precision highp float;

layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

in Vertex
{
    vec3 normal;
    vec4 color;
} vertex[];

out vec4 color;

uniform vec3 vLightPosition;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;

uniform float push_out;

void main(void)
{
    int n;

    vec3 face_normal = normalize(cross(gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz,
                                       gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz));

    for (n = 0; n < gl_in.length(); n++) {
        color = vertex[n].color;
        gl_Position = mvpMatrix * vec4(gl_in[n].gl_Position.xyz + face_normal * push_out, gl_in[n].gl_Position.w);
        EmitVertex();
    }
    EndPrimitive();
}
// Cell lighting Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 150

precision highp float;

// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;

out Vertex
{
    vec3 normal;
    vec4 color;
} vertex;

uniform vec3 vLightPosition;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;

void main(void)
{
    // Get surface normal in eye coordinates
    vec3 vEyeNormal = normalMatrix * vNormal;

    // Get vertex position in eye coordinates
    vec4 vPosition4 = mvMatrix * vVertex;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    // Get vector to light source
    vec3 vLightDir = normalize(vLightPosition - vPosition3);

    // Dot product gives us diffuse intensity
    vertex.color = vec4(0.3, 0.3, 0.9, 1.0) * max(0.0, dot(vEyeNormal, vLightDir));

    gl_Position = vVertex;
    vertex.normal = vNormal;
}
// Geometry Shader 'Explode' Example
// OpenGL SuperBible 5th Edition
// Demonstrates 'explosion' of geometry using OpenGL geometry shaders
// Program by Graham Sellers

// OpenGL toolkit
#pragma comment(lib, "gltools.lib")
#include <GLTools.h>
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
#include <Stopwatch.h>

#include <math.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

#ifdef _MSC_VER
#pragma comment (lib, "GLTools.lib")
#endif /* _MSC_VER */

static GLFrame              viewFrame;
static GLFrustum            viewFrustum;
static GLTriangleBatch      torusBatch;
static GLMatrixStack        modelViewMatrix;
static GLMatrixStack        projectionMatrix;
static GLGeometryTransform  transformPipeline;
static GLShaderManager      shaderManager;

static GLuint               explodeProgram;         // The geometry shader 'exploder' program
static GLint                locMVP;                 // The location of the ModelViewProjection matrix uniform
static GLint                locMV;                  // The location of the ModelView matrix uniform
static GLint                locNM;                  // The location of the Normal matrix uniform

static GLint                locPushOut;             // How far to push the geomery out

// This function does any needed initialization on the rendering context.
void SetupRC(void)
{
	// Background
	glClearColor(0.2f, 0.2f, 0.3f, 1.0f);

	glEnable(GL_DEPTH_TEST);

	shaderManager.InitializeStockShaders();
	viewFrame.MoveForward(4.0f);

	// Make the torus
	gltMakeTorus(torusBatch, .70f, 0.10f, 11, 7);

	explodeProgram = gltLoadShaderTripletWithAttributes("GSExplode.vs",
		"GSExplode.gs",
		"GSExplode.fs",
		2,
		GLT_ATTRIBUTE_VERTEX, "vVertex",
		GLT_ATTRIBUTE_NORMAL, "vNormal");

	locMVP = glGetUniformLocation(explodeProgram, "mvpMatrix");
	locMV = glGetUniformLocation(explodeProgram, "mvMatrix");
	locNM = glGetUniformLocation(explodeProgram, "normalMatrix");
	locPushOut = glGetUniformLocation(explodeProgram, "push_out");
}

// Cleanup
void ShutdownRC(void)
{
	glDeleteProgram(explodeProgram);
}

// Called to draw scene
void RenderScene(void)
{
	static CStopWatch rotTimer;

	// Clear the window and the depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	modelViewMatrix.PushMatrix(viewFrame);
	modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 10.0f, 0.0f, 1.0f, 0.0f);
	modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 13.0f, 1.0f, 0.0f, 0.0f);

	GLfloat vEyeLight[] = { -100.0f, 100.0f, 100.0f };
	GLfloat vAmbientColor[] = { 0.1f, 0.1f, 0.1f, 1.0f };
	GLfloat vDiffuseColor[] = { 0.1f, 1.0f, 0.1f, 1.0f };
	GLfloat vSpecularColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };

	glUseProgram(explodeProgram);
	glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
	glUniformMatrix4fv(locMV, 1, GL_FALSE, transformPipeline.GetModelViewMatrix());
	glUniformMatrix3fv(locNM, 1, GL_FALSE, transformPipeline.GetNormalMatrix());

	float push_out = sinf(rotTimer.GetElapsedSeconds() * 3.0f) * 0.1f + 0.2f;

	glUniform1f(locPushOut, push_out);

	torusBatch.Draw();

	modelViewMatrix.PopMatrix();


	glutSwapBuffers();
	glutPostRedisplay();
}

void ChangeSize(int w, int h)
{
	// Prevent a divide by zero
	if (h == 0)
		h = 1;

	// Set Viewport to window dimensions
	glViewport(0, 0, w, h);

	viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 100.0f);

	projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
	transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}

///
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
{
	gltSetWorkingDirectory(argv[0]);

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Geometry Shader Exploder");
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);

	GLenum err = glewInit();
	if (GLEW_OK != err) {
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		return 1;
	}

	SetupRC();
	glutMainLoop();
	ShutdownRC();
	return 0;
}

 

上一篇:c++(生成随机数)


下一篇:nodejs的package.json依赖dependencies中 ^ 和 ~ 的区别