OpenGL着色器的使用总结

1.把着色器写到文本文件中,以便在程序中读取调用shader.vert;shader.fragment

2.用读文件的方式把两个着色器中的代码读到字符串中

3.新建shader对象,判断创建是否成功glCreateShader()

4.将着色器字符串关联到shader对象glShaderSource()

5.编译着色器对象,判断编译是否成功,如果不成功,输出错误日志glCompileShader()

6.创建着色器程序,判断是否创建成功glCreateProgram()

7.关联着色器对象和着色器程序glAttachShader()

8.链接着色器程序,判断链接是否成功glLinkProgram()

9.使用着色器程序 即让着色器在主程序运行过程中发挥作用glUseProgram()

1234567见AddShader()函数

具体代码如下:

#include <stdio.h>
#include <string>
#include <iostream>
#include <glew.h>
#include <assert.h>
#include <freeglut.h>
#include "Utils.h"
#include "Vertex.h"

const char * pVS = "shader.vert";//已经用着色语言编辑好的着色器(其实就是文本文件)
const char * pFS = "shader.frag";
GLuint VBO;
GLuint gScaleLocation;
static void RenderSceneCB()
{
 glClear(GL_COLOR_BUFFER_BIT);

 static float Scale = 0.0f;
 Scale += 0.001f;
 glUniform1f(gScaleLocation,sinf(Scale));

 glEnableVertexAttribArray(1);//设置是否启用与index索引相关联的顶点数组
 glBindBuffer(GL_ARRAY_BUFFER,VBO);//第二次调用激活绑定到目标GL_ARRAY_BUFFER的缓存对象
 glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,3*4,0);//从缓冲区获取数据,传入到顶点着色器对应的in变量中(即给顶点着色器输入数据,即opengl将要处理的所有顶点数据)
 glDrawArrays(GL_TRIANGLES,0,3);
 glDisableVertexAttribArray(1);
 
 glutSwapBuffers();
}

static void CreateVertexBuffer()
{
 Vector3f Vertices[3];
 Vertices[0] = Vector3f(-1.0f,-1.0f,0.0f);
 Vertices[1] = Vector3f(1.0f,-1.0f, 0.0f);
 Vertices[2] = Vector3f(0.0f,1.0f, 0.0f);

 glGenBuffers(1,&VBO);//返回n个未使用的缓存对象名称,并保存到buffer数组中
 glBindBuffer(GL_ARRAY_BUFFER,VBO);//第一次调用,创建一个与该名称相对应的新缓存对象(且将它作为当前对象),并真正地分配所需内存
 glBufferData(GL_ARRAY_BUFFER,sizeof(Vertices), Vertices, GL_STATIC_DRAW);

}
static void AddShader(GLuint ShaderProgram,const char* shaderText, GLenum shaderType)
{
 GLuint ShaderObj = glCreateShader(shaderType);
 if (ShaderObj == 0)
 {
  ErrorOut();
  exit(1);
 }
 const GLchar* p[1];
 p[0]= shaderText;
 GLint L[1];
 L[0] = strlen(shaderText);

 glShaderSource(ShaderObj,1,p,L);
 glCompileShader(ShaderObj);
 GLint success;
 glGetShaderiv(ShaderObj,GL_COMPILE_STATUS,&success);
 if (!success)
 {
  GLchar InfoLog[1024];
  glGetShaderInfoLog(ShaderObj,1024,NULL,InfoLog);
  fprintf(stderr,"Error compiling shader type %d:'%s'\n",shaderType,InfoLog);
  exit(1);
 }
 glAttachShader(ShaderProgram,ShaderObj);
}
void CompileShaders()
{
 string vs,fs;
 if (!ReadFile(pVS,vs))
 {
  exit(1);
 }
 if (!ReadFile(pFS,fs))
 {
  exit(1);
 }
 //cout<<vs<<endl;
 //cout<<fs<<endl;
 GLuint ShaderProgram = glCreateProgram();
 if (0 == ShaderProgram)
 {
  ErrorOut();
  exit(1);
 }
 AddShader(ShaderProgram,vs.c_str(),GL_VERTEX_SHADER);
 AddShader(ShaderProgram,fs.c_str(),GL_FRAGMENT_SHADER);

 glLinkProgram(ShaderProgram);
 GLint Success=0;
 GLchar ErrorLog[1024] = {0};
 glGetProgramiv(ShaderProgram,GL_LINK_STATUS,&Success);
 if (Success == 0)
 {
  glGetProgramInfoLog(ShaderProgram,sizeof(ErrorLog),NULL,ErrorLog);
  fprintf(stderr,"Error linking shader program:'%s'\n",ErrorLog);
  exit(1);
 }

 gScaleLocation = glGetUniformLocation(ShaderProgram,"gScale");
 //assert(gScaleLocation != OxFFFFFFFF);

 glValidateProgram(ShaderProgram);
 glGetProgramiv(ShaderProgram,GL_VALIDATE_STATUS,&Success);
 if (Success == 0)
 {
  glGetProgramInfoLog(ShaderProgram,sizeof(ErrorLog),NULL,ErrorLog);
  fprintf(stderr, "Error linking shader program:'%s'\n",ErrorLog);
  exit(1);
 }
 glUseProgram(ShaderProgram);
}
int main(int argc, char** argv)
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
 glutInitWindowSize(800, 600);
 glutCreateWindow("tutorial 01");
 GLenum res = glewInit();
  if (GLEW_OK != res)
  {
   fprintf(stderr,"Error:%s",glewGetErrorString(res));
   return 1;
  }

 glutDisplayFunc(RenderSceneCB);
 glutIdleFunc(RenderSceneCB);
 glClearColor(0.0f,1.0f,0.0f,0.0f);

 CompileShaders();
 CreateVertexBuffer();
 glutMainLoop();
 return 0;
}

附加:

(1)shader.vert :

#version 330

layout (location = 1) in vec3 Position;

unifor float gScale;
// varying
out vec3 color;

void main()
{
  gl_Position = vec4(Position.x*gScale, Position.y*gScale, Position.z , 1.0);
  color = vec3(Position.x*gScale,Position.y*gScale,Position.z);
}

(2) shader.frag:

#version 330

out vec4 FragColor;

uniform float gScale;

in vec3 color;

void main()
{
 FragColor = vec4(color.x, color.y, color.z, 0.1);
}


(3)Vertex内容:

#pragma  once
class Vector3f
{
public:
 float x,y,z;
 Vector3f(){}
 Vector3f(float _x,float _y,float _z)
 {
  x = _x;
  y = _y;
  z = _z;
 }
};

(4)Utis.h内容:

#pragma once
#include <iostream>
#include <string>
using namespace std;
//添加宏定义错误文件和位置
void error_out(string file,unsigned int linenum);
#define ErrorOut() error_out(__FILE__,__LINE__)

bool ReadFile(const char* fileName, string& outFile);

Utis.cpp内容:

#include "Utils.h"
#include <fstream>

void error_out(string file, unsigned int linenum)
{
 cout<<file<<":"<<linenum<<endl;
}
bool ReadFile(const char* pFileName,string& outFile)
{
 ifstream f(pFileName);
 bool ret = false;
 if (f.is_open())
 {
  string line;
  while(getline(f,line))
  {
   outFile.append(line);
   outFile.append("\n");
  }
  f.close();
  ret = true;
 }
 else
 {
  ErrorOut();
 }
 return ret;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值