GLSL记录(1)-实时旋转的三角形

    main.cpp:

#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;//转换为弧度制


//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.0f, 0.8f, 0.0f
};

float colorData[] = {
    1.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 0.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 | GL_DEPTH_BUFFER_BIT);
    angle += 0.01f;
    mat4 rotationMatrix = glm::rotate( mat4(1.0f),angle,vec3(0.0f,0.0f,1.0f));
    GLuint location = glGetUniformLocation( programHandle, "RotationMatrix");
    if(location >= 0)
    {
        //printf("yes...........\n");
        glUniformMatrix4fv( location, 1, GL_FALSE, &rotationMatrix[0][0]);
    }
    else
    {
        printf("no...........\n");
    }

    //in the render func,we bind to the vertex array obj and call glDrawArrays to initiate rendering
    glBindVertexArray(vaoHandle);
    glDrawArrays(GL_TRIANGLES,0,3);
    glutSwapBuffers();
}

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

void setShaders()
{
    char* vs_code = LoadShaderFromFile("z_basic.vert");
    char* fs_code = LoadShaderFromFile("z_basic.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 InitGL(int argc,char* argv[])
{
    //
    glutInit(&argc,argv);    //初始化glut,必须调用,复制黏贴这句话即可
    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(1.0,1.0,1.0,1.0);//清除颜色设置为白色,这样glclear后面clear color就用白色clear
    glewInit();
    //

    //1.创建
    //create and populate the buffer objects
    GLuint vboHandles[2];
    glGenBuffers(2, vboHandles);
    GLuint positionBufferHandle = vboHandles[0];
    GLuint colorBufferHandle = vboHandles[1];
    //2.
    //populate the position buffer
    glBindBuffer( GL_ARRAY_BUFFER, positionBufferHandle);
    glBufferData( GL_ARRAY_BUFFER, 9 * sizeof(float), positionData, GL_STATIC_DRAW);
    //populate color buffer
    glBindBuffer( GL_ARRAY_BUFFER, colorBufferHandle);
    //最后一个参数告诉我们这个数据是用来干嘛的,static表示不能再被修改
    glBufferData( GL_ARRAY_BUFFER, 9 * sizeof(float), colorData, 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, colorBufferHandle);
    glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, 0 ,NULL);

}

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

    //1.
    InitGL(argc,argv);
    //2.
    setShaders();
    //3.
   // LogGLVersion();
    glutMainLoop();  //消息循环
    //

    //check gl version

    return 0;
}
着色器:

z_basic.vert:

#version 430
/*
the main opengl program refers to vertex attributes by associating each input variable with a generic attribute index.
those index are simply integers between 0 and GL_MAX_VERTEX_ATTRIBS - 1.
we  can specify the relationship between these indices and the attributes using the layout qualifier.
*/
//input
layout (location=0) in vec3 VertexPosition;
layout (location=1) in vec3 VertexColor;
//output
out vec3 Color;

/*
uniform variables are uintended to used for data that may change relatively infrequently compared to per-vertex attributes.
uniform variables are well suited for the matrics used for modeling , viewing, and projective transformations.
*/
uniform mat4 RotationMatrix;

void main()
{
	Color = VertexColor;
	gl_Position = RotationMatrix * vec4 ( VertexPosition, 1.0);
}
z_basic.frag:

#version 430

in vec3 Color;

layout (location = 0) out vec4 FragColor;

void main()
{
    FragColor = vec4(Color, 1.0);
}

shadertool.cpp:

#include"shadertool.h"

char* LoadShaderFromFile( char* fileName)
{
    FILE *fp;
    char* content = NULL;
    int count= 0;
    if( fileName != NULL)
    {
        fp = fopen(fileName,"rt");
        if(fp != NULL)
        {
            fseek( fp, 0, SEEK_END);
            count = ftell(fp);
            rewind(fp);
            if(count > 0)
            {
                content = (char*)malloc( sizeof(char)*(count + 1));
                count = fread(content,sizeof(char),count,fp);
                content[count] = '\0';
            }
            fclose(fp);
        }
    }
    return content;
}
//compile shader and if error log it.
void CompileShader(GLuint s,int type)
{

    glCompileShader(s);   //编译shader
    //get compile info and log it
    GLint result;
    //query compile status info by call this func.
    glGetShaderiv( s, GL_COMPILE_STATUS, &result);
    //if false , query the shader log
    if( GL_FALSE == result)
    {
        if(type == 0 )
        fprintf(stderr,"vertex shader compile failed\n");
        else fprintf(stderr,"fragment shader compile failed\n");
        GLint logLen;
        glGetShaderiv( s, GL_INFO_LOG_LENGTH,&logLen);
        if( logLen > 0)
        {
            char* log = new char[ logLen ];
            GLsizei written;
            glGetShaderInfoLog(s,logLen, &written, log);
            fprintf( stderr, "shader log : \n%s",log);
            delete[] log;//free the memeory
        }
        else
        {
             fprintf( stderr, "log length <= 0");
        }

    }

}
void LogGLVersion()
{
    const GLubyte *renderer = glGetString(GL_RENDERER);
    const GLubyte *vendor = glGetString(GL_VENDOR);
    const GLubyte *version = glGetString(GL_VERSION);
    const GLubyte *glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
    GLint major, minor;
    glGetIntegerv(GL_MAJOR_VERSION, &major);
    glGetIntegerv(GL_MINOR_VERSION, &minor);

    printf("GL Vendor               :%s\n",vendor);
    printf("GL Render               :%s\n",renderer);
    printf("GL Version string       :%s\n",version);
    printf("GL Version int          :%d.%d\n",major,minor);
    printf("GLSL Version            :%s\n",glslVersion);
}

效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值