您的位置:首页 > 其它

用着色器画Sierpinski

2015-10-13 00:42 288 查看
InitShader.cpp

#include "Angel.h"

namespace Angel {

// Create a NULL-terminated string by reading the provided file
static char*
readShaderSource(const char* shaderFile)
{
FILE* fp = fopen(shaderFile, "r");

if (fp == NULL) { return NULL; }

fseek(fp, 0L, SEEK_END);
long size = ftell(fp);

fseek(fp, 0L, SEEK_SET);
char* buf = new char[size + 1];
fread(buf, 1, size, fp);

buf[size] = NULL;
fclose(fp);

return buf;
}

// Create a GLSL program object from vertex and fragment shader files
GLuint
InitShader(const char* vShaderFile, const char* fShaderFile)
{
struct Shader {
const char*  filename;
GLenum       type;
GLchar*      source;
}  shaders[2] = {
{ vShaderFile, GL_VERTEX_SHADER, NULL },
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
};

GLuint program = glCreateProgram();

for (int i = 0; i < 2; ++i) {
Shader& s = shaders[i];
s.source = readShaderSource(s.filename);
if (shaders[i].source == NULL) {
std::cerr << "Failed to read " << s.filename << std::endl;
exit(EXIT_FAILURE);
}

GLuint shader = glCreateShader(s.type);
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
glCompileShader(shader);

GLint  compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
std::cerr << s.filename << " failed to compile:" << std::endl;
GLint  logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetShaderInfoLog(shader, logSize, NULL, logMsg);
std::cerr << logMsg << std::endl;
delete[] logMsg;

exit(EXIT_FAILURE);
}

delete[] s.source;

glAttachShader(program, shader);
}

/* link  and error check */
glLinkProgram(program);

GLint  linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
std::cerr << "Shader program failed to link" << std::endl;
GLint  logSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog(program, logSize, NULL, logMsg);
std::cerr << logMsg << std::endl;
delete[] logMsg;

exit(EXIT_FAILURE);
}

/* use program object */
glUseProgram(program);

return program;
}

}  // Close

Sinerpinski.cpp
// Two-Dimensional Sierpinski Gasket
// Generated using randomly selected vertices and bisection
#pragma comment(lib,"glew32.lib")
#include <stdlib.h>
#include "Angel.h"
#include<GL/glew.h>

const int NumPoints =5000;

//----------------------------------------------------------------------------

void
init(void)
{
vec2 points[NumPoints];

// Specifiy the vertices for a triangle
vec2 vertices[3] = {
vec2(-1.0, -1.0), vec2(0.0, 1.0), vec2(1.0, -1.0)
};

// Select an arbitrary initial point inside of the triangle
points[0] = vec2(0.25, 0.50);

// compute and store N-1 new points
for (int i = 1; i < NumPoints; ++i) {
int j = rand() % 3;   // pick a vertex at random

// Compute the point halfway between the selected vertex
//   and the previous point
points[i] = (points[i - 1] + vertices[j]) / 2.0;
}

// Load shaders and use the resulting shader program
GLuint program = InitShader("vshader_a2.glsl", "fshader_a2.glsl");
glUseProgram(program);

// Create a vertex array object
GLuint vao[1];
glGenVertexArrays(1, vao);
glBindVertexArray(vao[1]);

// Create and initialize a buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);

// Initialize the vertex position attribute from the vertex shader
GLuint loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0));

glClearColor(1.0, 1.0, 1.0, 1.0); // white background
}

//----------------------------------------------------------------------------

void
display(void)
{
glClear(GL_COLOR_BUFFER_BIT);     // clear the window
glDrawArrays(GL_POINTS, 0, NumPoints);    // draw the points
glFlush();
}

//----------------------------------------------------------------------------

//void
//keyboard(unsigned char key, int x, int y)
//{
//	switch (key) {
//	case 033:
//		exit(EXIT_SUCCESS);
//		break;
//	}
//}

//----------------------------------------------------------------------------

int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(512, 512);

// If you are using freeglut, the next two lines will check if
// the code is truly 3.2. Otherwise, comment them out

glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);

glutCreateWindow("Sierpinski Gasket");
glewExperimental = true;

/*if(GLEW_OK!=glewInit()){return 1;}
while(GL_NO_ERROR!=glGetError());*/
glewInit();

init();

glutDisplayFunc(display);
/*glutKeyboardFunc(keyboard);*/

glutMainLoop();
return 0;
}

fshader_a2.glsl
#version 150
out vec4 fColor;
void main()
{
fColor=vec4(1.0,0.0,0.0,1.0);
}

vshader_a1.glsl
#version 150
in vec4 vPosition;
void main()
{
gl_Position=vPosition;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: