#include "GPUProgram.h" #include "utils.h" #include GLuint CompileShader(const char*shaderPath, GLenum shaderType) { GLuint shader = glCreateShader(shaderType); const char* code = LoadFileContent(shaderPath); if (code == nullptr) { printf("cannot load shader source from file %s\n", shaderPath); return 0; } glShaderSource(shader, 1, &code, nullptr);//ram -> vram glCompileShader(shader); GLint nResult; glGetShaderiv(shader, GL_COMPILE_STATUS, &nResult); if (nResult == GL_FALSE) { printf("compile shader %s fail\n", shaderPath); GLint logLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); char*log = new char[logLength]; GLsizei writed = 0; glGetShaderInfoLog(shader, logLength, &writed, log); printf("%s\n", log); delete log; glDeleteShader(shader); return 0; } return shader; } GPUProgram::GPUProgram() { mProgram = glCreateProgram(); } GPUProgram::~GPUProgram() { } void GPUProgram::AttachShader(GLenum shaderType, const char*shaderPath) { GLuint shader = CompileShader(shaderPath, shaderType); if (shader!=0) { glAttachShader(mProgram, shader); mAttachedShaders.push(shader); } } void GPUProgram::Link() { glLinkProgram(mProgram); GLint nResult; glGetProgramiv(mProgram, GL_LINK_STATUS, &nResult); if (nResult == GL_FALSE) { printf("create gpu program fail,link error\n"); GLint logLength; glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &logLength); char*log = new char[logLength]; GLsizei writed = 0; glGetProgramInfoLog(mProgram, logLength, &writed, log); printf("%s\n", log); delete log; glDeleteProgram(mProgram); mProgram = 0; } while (!mAttachedShaders.empty()) { GLuint shader = mAttachedShaders.top(); glDetachShader(mProgram, shader); glDeleteShader(shader); mAttachedShaders.pop(); } } void GPUProgram::DetectAttribute(const char*attributeName) { GLint loc = glGetAttribLocation(mProgram, attributeName); if (loc!=-1) { mLocations.insert(std::pair(attributeName,loc)); } } void GPUProgram::DetectUniform(const char*uniformName) { GLint loc = glGetUniformLocation(mProgram, uniformName); if (loc != -1) { mLocations.insert(std::pair(uniformName, loc)); } } GLint GPUProgram::GetLocation(const char*name) { auto iter = mLocations.find(name); if (iter ==mLocations.end()) { return -1; } return iter->second; }