初始化Open Program的四个函数:
GLuint shaderProgram = glCreateProgram(); glLinkProgram(shaderProgram); glValidateProgram(shaderProgram); glUseProgram(shaderProgram);
GLuint shaderObj = glCreateShader(shaderType); glShaderSource(shaderObj, 1, &pTxt, &texLen); glCompileShader(shaderObj); glAttachShader(shaderProgram, shaderObj);
shader的文本是放在硬盘的text文本,当然什么格式是程序员定义的,也可以是加密的。
只要对C或者C++熟悉,就知道如何把文本shader读入内存操作, 让OpenGL编译并连接shader,比如,我这里自己写的操作函数如下:
void getShaderBuffer(const char *fileName, string &buffer)
{
FILE *fp;
fopen_s(&fp, fileName, "r");
if (!fp)
{
fprintf(stderr, "Error open file %s fail\n", pVSFileName);
exit(1);
}
char c;
while ((c = getc(fp)) != EOF)
{
buffer.push_back(c);
}
fclose(fp);
}
总体程序还是挺长的,贴出来参考下吧, 源文件提供下载:http://download.csdn.net/detail/kenden23/7413215
效果如下:
#pragma once
#include <stdio.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include "math_3d.h"
#include <string>
#include <iostream>
using namespace std;
namespace Shader_Begin_4_1
{
GLuint VBO;
const static float PI = 3.1415926f;
int gSegments;
const char* pVSFileName = "shader.vs";
const char* pFSFileName = "shader.fs";
static void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_POLYGON, 0, gSegments);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
static void initCallBackFunc()
{
glutDisplayFunc(renderScene);
}
void genHeart_2(Vector3f *vers, int offset, int segments,
float ox, float oy, float R = 0.05)
{
for (int i = 0; i < segments; i++)
{
float theta = 2.0f * PI * float(i) / float(segments);
float x = R * 16 * pow(sin(theta), 3);
float y = R * (13 * cos(theta) - 5*cos(2*theta)
- 2*cos(3*theta) - cos(4*theta));
vers[offset+i] = Vector3f(ox+x, oy+y, 0.0f);
}
}
void setupGeoAndBuffer()
{
const int segments = 360;
Vector3f vers[segments];
gSegments = segments;
genHeart_2(vers, 0, segments, 0.f, 0.f, 0.1f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vers), vers, GL_STATIC_DRAW);
}
static void attachShader(GLuint shaderProgram, const char *pShaderTxt,
GLenum shaderType, int offset, int texLen)
{
GLuint shaderObj = glCreateShader(shaderType);
if (!shaderObj)
{
fprintf(stderr, "Error create shader type %d\n", shaderType);
exit(1);
}
const char *pTxt = pShaderTxt + offset;
glShaderSource(shaderObj, 1, &pTxt, &texLen);
glCompileShader(shaderObj);
GLint res;
glGetShaderiv(shaderObj, GL_COMPILE_STATUS, &res);
if (!res)
{
GLchar infoLog[1024];
glGetShaderInfoLog(shaderObj, sizeof(infoLog), NULL, infoLog);
fprintf(stderr, "Error, compile shader type %d\n %s \n",
shaderType, infoLog);
exit(2);
}
glAttachShader(shaderProgram, shaderObj);
}
void getShaderBuffer(const char *fileName, string &buffer)
{
FILE *fp;
fopen_s(&fp, fileName, "r");
if (!fp)
{
fprintf(stderr, "Error open file %s fail\n", pVSFileName);
exit(1);
}
char c;
while ((c = getc(fp)) != EOF)
{
buffer.push_back(c);
}
fclose(fp);
}
static void compileShader()
{
GLuint shaderProgram = glCreateProgram();
if (!shaderProgram)
{
fprintf(stderr, "Error create program\n");
exit(1);
}
int size;
string vsBuffer;
getShaderBuffer(pVSFileName, vsBuffer);
size = vsBuffer.size();
attachShader(shaderProgram, vsBuffer.c_str(), GL_VERTEX_SHADER, 0, size);
vsBuffer.clear();
string psBuffer;
getShaderBuffer(pFSFileName, psBuffer);
size = psBuffer.size();
attachShader(shaderProgram, psBuffer.c_str(), GL_FRAGMENT_SHADER, 0, size);
psBuffer.clear();
GLint res = 0;
GLchar errorLog[1024] = {0};
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &res);
if (!res)
{
glGetProgramInfoLog(shaderProgram, sizeof(errorLog), NULL, errorLog);
fprintf(stderr, "Error create program %s\n", errorLog);
exit(3);
}
glValidateProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &res);
if (!res)
{
glGetProgramInfoLog(shaderProgram, sizeof(errorLog), NULL, errorLog);
fprintf(stderr, "Error validate program %s\n", errorLog);
exit(1);
}
glUseProgram(shaderProgram);
}
int run(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 50);
glutInitWindowSize(600, 600);
glutCreateWindow("Bill's Heart Program");
initCallBackFunc();
GLenum res = glewInit();
if (res != GLEW_OK)
{
fprintf(stderr, "GLEW init failed \n %s\n", glewGetErrorString(res));
exit(1);
}
printf("GL version is:\n%s\n", glGetString(GL_VERSION));
glClearColor(0.0f, 0.6f, 0.5f, 0.0f);
setupGeoAndBuffer();
compileShader();
glutMainLoop();
return 0;
}
}
OpenGL 5: Shader画心形,布布扣,bubuko.com
原文地址:http://blog.csdn.net/kenden23/article/details/27338943