GLSL(2)记录-使用uniform block

#include <iostream>
#include"shadertool.h"
#include"glm/glm.hpp"
//using namespace std;
#include"glm/gtc/matrix_transform.hpp"

using glm::mat4;
using glm::vec3;

#define PI 3.1415926

GLuint vaoHandle;
GLuint programHandle;
float angle = 30.0f * PI/180.0f;//转换为弧度制

void InitUniformBlockBuffer();
//we create and populate the vertex buffer objects for each attribute
float positionData[] = {
    -0.8f, -0.8f, .0f,
    0.8f, -0.8f, 0.0f,
    0.8f, 0.8f, 0.0f,
    -0.8f,-0.8f,0.0f,
    0.8f,0.8f,0.0f,
    -0.8f,0.8f,0.0f
};//上面的六个点刚好形成一个正方形
//三角形三个顶点,每个顶点的RGB
float colorData[] = {
    1.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 1.0f
};
//正方形四个顶点,每个顶点的RGB
float tcData[] =
{
    .0f,.0f,1.0f,
    .0f,1.0f,1.0f,
    .0f,.0f,1.0f,
    1.0f,.0f,1.0f
};


void changeSize(int w,int h)
{
    if(h==0)
    {
        h=1;
    }
    float ratio=1.0*w/h;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0,0,w,h);
    gluPerspective(45,ratio,1,1000);
    glMatrixMode(GL_MODELVIEW);
}

void renderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vaoHandle);
    glDrawArrays(GL_TRIANGLES,0,6);//shader必须依附在一个物体上才能体现出来,unity里面也不能直接看shader效果
    //一般都需要给一个cube或者sphere一个带某种shader的材质才能出现效果。这里也一样,这里是把shader效果依附到两个
    //三角形上面(6个顶点),两个三角形是6个顶点,构成的正方形是4个顶点,注意这里要写三角形顶点的总数量
    glutSwapBuffers();
}

void processNormalKeys(unsigned char key,int x,int y)
{
    if(key==27)
    {
        exit(0);
    }
}

void setShaders()
{
    char* vs_code = LoadShaderFromFile("shader//uniform_block.vert");
    char* fs_code = LoadShaderFromFile("shader//uniform_block.frag");

    GLuint v = glCreateShader(GL_VERTEX_SHADER);//create shader obj,返回一个handle
    GLuint f = glCreateShader(GL_FRAGMENT_SHADER);

    const char* ff = fs_code;
    const char* vv = vs_code;
    /*
    load the source code into shader obj,第三个参数可以是一个字符串数组,可以载入多个文件string
    第二个参数是表示string array 的size,one string ,so 1.
    最后一个参数表示each source code string is terminated by a null character.
    一旦这个函数返回后,表明source code 已经被成功加载在opengl的内部内存,因此,之前的用来存储shader code的字符串变量
    可以被释放掉了
    */
    glShaderSource(v,1,&vv,NULL);
    glShaderSource(f,1,&ff,NULL); //
    //free the source code
    free(vs_code);
    free(fs_code);
    //next step:
    //compile shader and log error
    CompileShader(v,0);
    CompileShader(f,1);
    //final step : shaders must be linked togehter into a shader program object.
    programHandle = glCreateProgram();//create a empty program obj

    glAttachShader(programHandle,f);
    glAttachShader(programHandle,v);
    //link.can use glGetProgramiv to query status(GL_TRUE/GL_FALSE)->glGetProgramiv(GL_LINK_STATUS)
    glLinkProgram(programHandle);
    //install the program into the opengl pipeline
    glUseProgram(programHandle);

}
void InitUniformBlockBuffer()
{
    GLuint blockIndex = glGetUniformBlockIndex(programHandle,"BlobSettings");
    GLint blockSize;
    glGetActiveUniformBlockiv(programHandle,blockIndex,GL_UNIFORM_BLOCK_DATA_SIZE,&blockSize);
    GLubyte* blockBuffer;
    //allocate a temporary buffer to hold the data for our block
    blockBuffer = (GLubyte*)malloc(blockSize);

    const GLchar* names[] = {"InnerColor","OuterColor","RadiusInner","RadiusOuter"};
    GLuint indices[4];
    glGetUniformIndices(programHandle,4,names,indices);
    GLint offset[4];
    glGetActiveUniformsiv( programHandle, 4, indices, GL_UNIFORM_OFFSET, offset);
    //place the data into the buffer at the appropriate offsets:
    GLfloat outerColor[] = {.0f, .0f, .0f, .0f};
    GLfloat innerColor[] = {1.0f, 1.0f, .7f, .7f};
    GLfloat innerRadius = 0.1f, outerRadius = 0.45f;

    memcpy( blockBuffer + offset[0], innerColor, 4 * sizeof(GLfloat));
    memcpy( blockBuffer + offset[1], outerColor, 4 * sizeof(GLfloat));
    memcpy( blockBuffer + offset[2], &innerRadius, sizeof(GLfloat));
    memcpy( blockBuffer + offset[3], &outerRadius, sizeof(GLfloat));
    //create the buffer object and copy the data into it
    GLuint uboHandle;
    //generate a buffer handle
    glGenBuffers(1, &uboHandle);
    //bind the buffer to the GL_UNIFORM_BUFFER binding point
    glBindBuffer( GL_UNIFORM_BUFFER, uboHandle);
    // copy blockBuffer's data  to GL_UNIFORM_BUFFER,we use GL_DYNAMIC_DRAW as the usage hint
    //here because uniform data may be changed somewhat ofen during rendering.
    glBufferData( GL_UNIFORM_BUFFER, blockSize, blockBuffer, GL_DYNAMIC_DRAW);
    //finally,we associate the buffer object with the uniform block
    glBindBufferBase(GL_UNIFORM_BUFFER, 0 , uboHandle);
}
void InitScene(int argc,char* argv[])
{
    //
#pragma region 基本不动的代码
    glutInit(&argc,argv);    //初始化glut,必须调用,复制黏贴这句话即可

  //  glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT,GL_TRUE);
    glEnable(GL_DEBUG_OUTPUT);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE ); //设置显示方式,RGB、双缓冲
    glutInitWindowPosition(100,100);   //位置
    glutInitWindowSize(400,400);//窗口大小
    glutCreateWindow("GLSL FUN!");  //创建窗口,设置标题
    glutDisplayFunc(renderScene);  // 当绘制窗口时调用myDisplay
    glutIdleFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutKeyboardFunc(processNormalKeys);
    //glEnable(GL_DEPTH_TEST);
    glClearColor(0.0,0.0,0.0,0.0);//清除颜色设置为白色,这样glclear后面clear color就用白色clear
    glewInit();

    //
#pragma endregion OK
    //1.创建
    //create and populate the buffer objects
    GLuint vboHandles[2];
    glGenBuffers(2, vboHandles);
    GLuint positionBufferHandle = vboHandles[0];
    GLuint tcBufferHandle = vboHandles[1];
    //2.
   // populate the position buffer
    glBindBuffer( GL_ARRAY_BUFFER, positionBufferHandle);
    glBufferData( GL_ARRAY_BUFFER, 18 * sizeof(float), positionData, GL_STATIC_DRAW);
    //populate color buffer
    glBindBuffer( GL_ARRAY_BUFFER, tcBufferHandle);
    //最后一个参数告诉我们这个数据是用来干嘛的,static表示不能再被修改
    glBufferData( GL_ARRAY_BUFFER, 12 * sizeof(float), tcData, GL_STATIC_DRAW);
    //3.create and set up the vertex array objects
    glGenVertexArrays(1, &vaoHandle);
    glBindVertexArray( vaoHandle );
    //enable the vertex attribute arrays
    glEnableVertexAttribArray(0);//vertex position
    glEnableVertexAttribArray(1);//vertex color
    //map index 0 to the position buffer
    glBindBuffer( GL_ARRAY_BUFFER, positionBufferHandle);
    glVertexAttribPointer(0,3,GL_FLOAT, GL_FALSE, 0 ,NULL);
    //map index 1 to the color buffer
    glBindBuffer(GL_ARRAY_BUFFER, tcBufferHandle);
    glVertexAttribPointer(1,2,GL_FLOAT, GL_FALSE, 0 ,NULL);
    //
//    glEnable(GL_BLEND);
//    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

}

int main(int argc,char* argv[])
{

    //1.
    InitScene(argc,argv);
    //2.
    setShaders();
    //after linking,use the following steps to assign data to uniform block in the frag shader
    InitUniformBlockBuffer();
   // LogGLVersion();
     //4.
    glutMainLoop();  //消息循环
    //

    //check gl version

    return 0;
}

顶点着色器:

#version 430

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexTexCoord;

out vec3 TexCoord;

void main()
{
	TexCoord = VertexTexCoord;
	gl_Position = vec4(VertexPosition,1.0);
}
像素着色器:

#version 430

in vec3 TexCoord;
layout (location = 0) out vec4 FragColor;
layout (binding = 0) uniform BlobSettings
{
	vec4 InnerColor;
	vec4 OuterColor;
	float RadiusInner;
	float RadiusOuter;
};

void main()
{
	float dx = TexCoord.x - 0.5;
	float dy = TexCoord.y - 0.5;
	float dist = sqrt(dx*dx + dy*dy);
	FragColor = mix( InnerColor, OuterColor,smoothstep( RadiusInner,RadiusOuter,dist));
}
结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值