openGL可编程笔记三——将Shader,VertexBuffer封装

来源:互联网 发布:sql拼接 引号 编辑:程序博客网 时间:2024/06/06 01:42

如果每次都绘制不同的图形,我们就需要每次都写重复的代码。所以这里封装了一下


对于Shader而言:

第一部分:

shader初始化: 解码vs, fs,并且链接为程序,并且指定shader代码部分中,GPU插槽位置

void Shader::Init(const char *vs, const char *fs) {int nFileSize = 0;const char* vsCode = (char*)LoadFileContent(vs, nFileSize);const char* fsCode = (char*)LoadFileContent(fs, nFileSize);GLuint vsShader = CompileShader(GL_VERTEX_SHADER, vsCode);if (vsShader == 0) return;GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER, fsCode);if (fsShader == 0) return;mProgram = CreateProgram(vsShader, fsShader);glDeleteShader(vsShader);glDeleteShader(fsShader);if (mProgram != 0) {mModelMatrixLocation = glGetUniformLocation(mProgram, "ModelMatrix");mViewMatrixLocation = glGetUniformLocation(mProgram, "ViewMatrix");mProjectionMatrixLocation = glGetUniformLocation(mProgram, "ProjectionMatrix");mColorLocation = glGetAttribLocation(mProgram, "color");mPositionLocation = glGetAttribLocation(mProgram, "position");mTexcoordLocation = glGetAttribLocation(mProgram, "texcoord");mNormalLocation = glGetAttribLocation(mProgram, "normal");}}
第二部分:

在绘图之前需要指定图形绘制位置,MVP矩阵,以及绑定数据

void Shader::Bind(float *M, float *V, float *P) {glUseProgram(mProgram);glUniformMatrix4fv(mModelMatrixLocation, 1, GL_FALSE, M);glUniformMatrix4fv(mViewMatrixLocation, 1, GL_FALSE, V);glUniformMatrix4fv(mProjectionMatrixLocation, 1, GL_FALSE, P);glEnableVertexAttribArray(mPositionLocation);glVertexAttribPointer(mPositionLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);glEnableVertexAttribArray(mColorLocation);glVertexAttribPointer(mColorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 4));glEnableVertexAttribArray(mTexcoordLocation);glVertexAttribPointer(mTexcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 8)); glEnableVertexAttribArray(mNormalLocation);  glVertexAttribPointer(mNormalLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 12));}


对于VertexBuffer部分:

无非只是:初始化+设置数据+ 绘图时期指定vbo对象绘图的过程

1.初始化:

void VertexBuffer::SetSize(int vertexCount) {mVertexCount = vertexCount;mVertexes = new Vertex[mVertexCount];memset(mVertexes, 0, sizeof(mVertexes));mVBO = CreateBufferObject(GL_ARRAY_BUFFER,sizeof(Vertex) *mVertexCount, GL_STATIC_DRAW, nullptr);}

GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void *data) {GLuint object;glGenBuffers(1, &object);glBindBuffer(bufferType, object);glBufferData(bufferType, size, data, usage);glBindBuffer(bufferType, 0);return object;}

初始化数组,并且将vbo对象,绑定数据。

2.设置数据

void VertexBuffer::SetPosition(int index, float x, float y, float z,float w) {mVertexes[index].Position[0] = x;mVertexes[index].Position[1] = y;mVertexes[index].Position[2] = z;mVertexes[index].Position[3] = w;}void VertexBuffer::SetColor(int index, float r, float g, float b, float a ) {mVertexes[index].Color[0] = r;mVertexes[index].Color[1] = g;mVertexes[index].Color[2] = b;mVertexes[index].Color[3] = a;}void VertexBuffer::SetTexcoord(int index,float x, float y) {mVertexes[index].Texcoord[0] = x;mVertexes[index].Texcoord[1] = y;}void VertexBuffer::SetNormal(int index, float x, float y, float z) {mVertexes[index].Normal[0] = x;mVertexes[index].Normal[1] = y;mVertexes[index].Normal[2] = z;mVertexes[index].Normal[3] = 1.0;}
注意这两部分不要在draw的函数部分,否则内存爆炸

3.绘图部分的绑定vbo以及解绑定初始化

void VertexBuffer::Bind() { glBindBuffer(GL_ARRAY_BUFFER, mVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*mVertexCount, mVertexes,GL_STATIC_DRAW);//glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex)*mVertexCount, mVertexes);}void VertexBuffer::Unbind() {glBindBuffer(mVBO, 0);}Vertex& VertexBuffer::Get(int index) {return mVertexes[index];}

这里以绘制一个地形为例。

#include "Ground.h"void Ground::init() {mVertexBuffer = new VertexBuffer;mVertexBuffer->SetSize(1600);for (int z = 0; z < 20; ++z) {float zStart = 100.0f - z*10.0f;for (int x = 0; x < 20; ++x) {int offset = (x + z * 20) * 4;float xStart = x*10.0f - 100.0f;mVertexBuffer->SetPosition(offset, xStart, -1.0f, zStart);mVertexBuffer->SetPosition(offset + 1, xStart + 10.0f, -1.0f, zStart);mVertexBuffer->SetPosition(offset + 2, xStart, -1.0f, zStart - 10.0f);mVertexBuffer->SetPosition(offset + 3, xStart + 10.0f, -1.0f, zStart - 10.0f); mVertexBuffer->SetNormal(offset, 0.0f, 1.0f, 0.0f);mVertexBuffer->SetNormal(offset + 1, 0.0f, 1.0f, 0.0f);mVertexBuffer->SetNormal(offset + 2, 0.0f, 1.0f, 0.0f);if ((z & 1) ^ (x & 1)) {mVertexBuffer->SetColor(offset, 0.1f, 0.1f, 0.1f);mVertexBuffer->SetColor(offset+1, 0.1f, 0.1f, 0.1f);mVertexBuffer->SetColor(offset+2, 0.1f, 0.1f, 0.1f);mVertexBuffer->SetColor(offset+3, 0.1f, 0.1f, 0.1f);}else {mVertexBuffer->SetColor(offset, 0.3f, 0.8f, 0.8f);mVertexBuffer->SetColor(offset+1, 0.8f, 0.2f, 0.8f);mVertexBuffer->SetColor(offset+2, 0.8f, 0.8f, 0.7f);mVertexBuffer->SetColor(offset+3, 0.6f, 0.8f, 0.8f);}}}mShader = new Shader;mShader->Init("Res/ground.vs", "Res/ground.fs");}void Ground::Draw(glm::mat4&viewMatrix, glm::mat4 &projectionMatirx) {glEnable(GL_DEPTH_TEST);mVertexBuffer->Bind();mShader->Bind(glm::value_ptr(mModelMatrix), glm::value_ptr(viewMatrix), glm::value_ptr(projectionMatirx));for(int i=0;i<400;i++){glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);}mVertexBuffer->Unbind();}

全部代码:

https://github.com/ycb577114589/Shader_openGL/tree/master/Ground


原创粉丝点击