dx11ShaderProgram::dx11ShaderProgram(const char *vshader, const char *pshader,int flags, const ConstantDesc *uniforms, const DataDesc *attributes) { bool fromCode=(flags&ShaderProgram::Flag_FromCode); long VSLen, PSLen; void *VSFile = fromCode?NULL:LoadShaderFile(vshader, "cso", &VSLen); if (!VSFile) { void *src = fromCode?(void *)vshader:LoadShaderFile(vshader, "hlsl", &VSLen); ID3DBlob *pCode; ID3DBlob *pError; if (fromCode&&vshader) VSLen = strlen(vshader); D3DCompile(src, VSLen, vshader, NULL, NULL, "VShader", "vs_4_0_level_9_3", D3DCOMPILE_PREFER_FLOW_CONTROL, 0, &pCode, &pError); if (src&&(!fromCode)) free(src); if (pError) { errorLog.append("VertexShader:\n"); errorLog.append((char *) pError->GetBufferPointer(), pError->GetBufferSize()); errorLog.append("\n"); pError->Release(); } if (pCode) { VSLen = pCode->GetBufferSize(); VSFile = malloc(VSLen); memcpy(VSFile, pCode->GetBufferPointer(), VSLen); pCode->Release(); } } void *PSFile = fromCode?NULL:LoadShaderFile(pshader, "cso", &PSLen); if (!PSFile) { void *src = fromCode?(void *)pshader:LoadShaderFile(pshader, "hlsl", &PSLen); ID3DBlob *pCode; ID3DBlob *pError; if (fromCode&&pshader) PSLen = strlen(pshader); D3DCompile(src, PSLen, pshader, NULL, NULL, "PShader", "ps_4_0_level_9_3", D3DCOMPILE_PREFER_FLOW_CONTROL, 0, &pCode, &pError); if (src&&(!fromCode)) free(src); if (pError) { errorLog.append("PixelShader:\n"); errorLog.append((char *) pError->GetBufferPointer(), pError->GetBufferSize()); errorLog.append("\n"); pError->Release(); } if (pCode) { PSLen = pCode->GetBufferSize(); PSFile = malloc(PSLen); memcpy(PSFile, pCode->GetBufferPointer(), PSLen); pCode->Release(); } } buildShaderProgram(VSFile, VSLen, PSFile, PSLen, flags, uniforms, attributes); if (VSFile) free(VSFile); if (PSFile) free(PSFile); }
// This function loads a vertex and fragment shader file and creates them void Shader::Initialize(std::string strVertexFile, std::string strFragmentFile) { // These will hold the shader's text file data std::string strVShader, strFShader; // Make sure the user passed in a vertex and fragment shader file if ( !strVertexFile.length() || !strFragmentFile.length() ) return; // If any of our shader pointers are set, let's free them first if ( VertexShaderId || FragmentShaderId || ShaderProgramId ) Destroy(); // Reset the last OpenGL error so we can check if down below GLenum ErrorCheckValue = glGetError(); // Here we get an Id to our vertex and fragment shaders VertexShaderId = glCreateShader(GL_VERTEX_SHADER); FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); // Now we load the shaders from the respective files and store it in a string strVShader = LoadShaderFile(strVertexFile.c_str()); strFShader = LoadShaderFile(strFragmentFile.c_str()); // Do a quick switch so we can do a double pointer below const char *szVShader = strVShader.c_str(); const char *szFShader = strFShader.c_str(); // Now this assigns the shader text file to each shader pointer glShaderSource(VertexShaderId, 1, &szVShader, nullptr); glShaderSource(FragmentShaderId, 1, &szFShader, nullptr); // Now we actually compile the shader code glCompileShader(VertexShaderId); glCompileShader(FragmentShaderId); // Next we create a program object to represent our shaders ShaderProgramId = glCreateProgram(); // We attach each shader we just loaded to our program object glAttachShader(ShaderProgramId, VertexShaderId); glAttachShader(ShaderProgramId, FragmentShaderId); // Our last init function is to link our program object with OpenGL glLinkProgram(ShaderProgramId); // Now check to see if any errors happened in this function ErrorCheckValue = glGetError(); // If there was an error found, print it to the screen and close the OpenGL window. if ( ErrorCheckValue != GL_NO_ERROR ) { // Use gluErrorString(ErrorCheckValue) if you want to get the string value of the // error, but I removed this since Mac OSX 10.9 (Mavericks) deprecated this function. fprintf(stderr, "ERROR: Could not create the shader program with error Id: %d\n", ErrorCheckValue); exit(-1); } }
//--------------------------- Constructor cShader::cShader(char* Filename){ //printf("------------- Loading Shader. /n"); //Temp Variables GLint iPass = 0; GLchar cErrorLog[1024] = { 0 }; //create 2 temp chars, adding the .vert and .frag extensions //vert std::string sVert; sVert.append(Filename); sVert.append(".vert"); char* vertShad = Filename; vertShad = LoadShaderFile(sVert.c_str()); //frag std::string sFrag; sFrag.append(Filename); sFrag.append(".frag"); char* fragShad = Filename; fragShad = LoadShaderFile(sFrag.c_str()); //Create the shader Program GLuint ShaderProgram = glCreateProgram(); //check it opened if (ShaderProgram == 0){ printf("Error creating ShaderProgram \n '%i' \n",ShaderProgram); iShaderID = -1; return; } //apply the shader LoadShader(ShaderProgram,GL_VERTEX_SHADER,vertShad); LoadShader(ShaderProgram,GL_FRAGMENT_SHADER,fragShad); //Link the Shader glLinkProgram(ShaderProgram); glGetProgramiv(ShaderProgram,GL_LINK_STATUS,&iPass); //Check it is linked if (iPass == 0){ glGetProgramInfoLog(ShaderProgram,sizeof(cErrorLog),NULL,cErrorLog); printf("Error while linking ShaderProgram \n '%s' \n",cErrorLog); iShaderID = -1; return; } //Validate the Shader glValidateProgram(ShaderProgram); glGetProgramiv(ShaderProgram,GL_LINK_STATUS,&iPass); //Check it is Valid if (iPass == 0){ glGetProgramInfoLog(ShaderProgram,sizeof(cErrorLog),NULL,cErrorLog); printf("Error while validating ShaderProgram \n '%s' \n",cErrorLog); iShaderID = -1; return; } iShaderID = ShaderProgram; //printf("------------- Shader Loading finished! \n \n"); }
GLuint Shader::GenerateShader(string from, GLenum type) { cout << "Compiling Shader..." << endl; string load; if(!LoadShaderFile(from,load)) { cout << "Compiling failed!" << endl; loadFailed = true; return 0; } GLuint shader = glCreateShader(type); const char *chars = load.c_str(); glShaderSource(shader, 1, &chars, NULL); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { cout << "Compiling failed!" << endl; char error[512]; glGetInfoLogARB(shader, sizeof(error), NULL, error); cout << error; loadFailed = true; return 0; } cout << "Compiling success!" << endl << endl; loadFailed = false; return shader; }
/** * Loads a shader from file and recursively adds all includes. * @param filename the name of the file to load. * @param defines the defines to add at the beginning. * @param fileId the id of the current file. */ std::string Shader::LoadShaderFile(const std::string& filename, const std::vector<std::string>& defines, unsigned int& fileId, unsigned int recursionDepth) const { if (recursionDepth > 32) { LOG(ERROR) << L"Header inclusion depth limit reached! Cyclic header inclusion?"; throw resource_loading_error() << ::boost::errinfo_file_name(filename) << fileid_info(fileId) << resid_info(id) << errdesc_info("Header inclusion depth limit reached! Cyclic header inclusion?"); } boost::filesystem::path sdrFile{ filename }; auto currentPath = sdrFile.parent_path().string() + "/"; std::ifstream file(filename.c_str(), std::ifstream::in); std::string line; std::stringstream content; unsigned int lineCount = 1; auto nextFileId = fileId + 1; while (file.good()) { std::getline(file, line); auto trimedLine = line; boost::trim(trimedLine); static const boost::regex re("^[ ]*#[ ]*include[ ]+[\"<](.*)[\">].*"); boost::smatch matches; if (boost::regex_search(line, matches, re)) { auto includeFile = currentPath + matches[1]; if (!boost::filesystem::exists(includeFile)) { LOG(ERROR) << filename.c_str() << L"(" << lineCount << ") : fatal error: cannot open include file \"" << includeFile.c_str() << "\"."; throw resource_loading_error() << ::boost::errinfo_file_name(includeFile) << fileid_info(fileId) << lineno_info(lineCount - 1) << resid_info(id) << errdesc_info("Cannot open include file."); } content << "#line " << 1 << " " << nextFileId << std::endl; content << LoadShaderFile(includeFile, std::vector<std::string>(), nextFileId, recursionDepth + 1); content << "#line " << lineCount + 1 << " " << fileId << std::endl; } else { content << line << std::endl; } if (boost::starts_with(trimedLine, "#version")) { for (auto& def : defines) { auto trimedDefine = def; boost::trim(trimedDefine); content << "#define " << trimedDefine << std::endl; } content << "#line " << lineCount + 1 << " " << fileId << std::endl; } ++lineCount; } file.close(); fileId = nextFileId; return content.str(); }
void Game::InitPipeline() { // load the shader files Array<byte>^ VSFile = LoadShaderFile("VertexShader.cso"); Array<byte>^ PSFile = LoadShaderFile("PixelShader.cso"); // create the shader objects dev->CreateVertexShader(VSFile->Data, VSFile->Length, nullptr, &vertexshader); dev->CreatePixelShader(PSFile->Data, PSFile->Length, nullptr, &pixelshader); // set the shader objects as the active shaders devcon->VSSetShader(vertexshader.Get(), nullptr, 0); devcon->PSSetShader(pixelshader.Get(), nullptr, 0); // initialize input layout D3D11_INPUT_ELEMENT_DESC ied[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; // create the input layout dev->CreateInputLayout(ied, ARRAYSIZE(ied), VSFile->Data, VSFile->Length, &inputlayout); devcon->IASetInputLayout(inputlayout.Get()); }
/* The 'old' way of compiling shaders is to read in the shader text file, and run it through the shader compiler. See the GCM tutorial text for an overview of how this function works, but for now just know that it's not very good, and the shaders it compiles will probably break. */ void Shader::LoadTextShader(std::string name, ShaderType type) { CGCcontext* cgCompiler = sceCgcNewContext(); CGCinclude include = {0,0}; CGCbin* bin = sceCgcNewBin(); CGCbin* output = sceCgcNewBin(); std::cout << "Compiling shader: " << name << std::endl; if(sceCgcCompileString(cgCompiler, LoadShaderFile(name).c_str(), type == VERTEX_SHADER ? "sce_vp_rsx" : "sce_fp_rsx", NULL,NULL,bin,0,output,&include) != SCECGC_OK){ std::cout << "Compiling failed!" << std::endl; return; } else{ std::cout << "Compiling success!" << std::endl; } program = (CGprogram)(void*)sceCgcGetBinData(bin); char* outputchars = (char*)sceCgcGetBinData(output); std::string outstring = std::string(outputchars); std::cout << "Compiling output:" << outstring << std::endl; cellGcmCgInitProgram(program); unsigned int ucodeSize; void *ucodePtr; cellGcmCgGetUCode(program, &ucodePtr, &ucodeSize); ucode = GCMRenderer::localMemoryAlign(64,ucodeSize); memcpy(ucode, ucodePtr, ucodeSize); cellGcmAddressToOffset(ucode, &offset); sceCgcDeleteContext(cgCompiler); sceCgcDeleteBin(bin); sceCgcDeleteBin(output); }
/** * Loads a shader from file and compiles it. * @param filename the shaders file name * @param type the shaders type * @param strType the shaders type as string * @return the compiled shader if successful */ GLuint Shader::CompileShader(const std::string& filename, const std::vector<std::string>& defines, GLenum type, const std::string& strType) const { unsigned int firstFileId = 0; if (!boost::filesystem::exists(filename)) { LOG(ERROR) << "Cannot open shader file \"" << filename.c_str() << "\"."; throw resource_loading_error() << ::boost::errinfo_file_name(filename) << fileid_info(firstFileId) << resid_info(id) << errdesc_info("Cannot open shader file."); } auto shaderText = LoadShaderFile(filename, defines, firstFileId, 0); auto shader = OGL_CALL(glCreateShader, type); if (shader == 0) { LOG(ERROR) << L"Could not create shader!"; throw std::runtime_error("Could not create shader!"); } auto shaderTextArray = shaderText.c_str(); auto shaderLength = static_cast<int>(shaderText.length()); OGL_CALL(glShaderSource, shader, 1, &shaderTextArray, &shaderLength); OGL_CALL(glCompileShader, shader); GLint status; OGL_CALL(glGetShaderiv, shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLint infoLogLength; OGL_CALL(glGetShaderiv, shader, GL_INFO_LOG_LENGTH, &infoLogLength); auto strInfoLog = new GLchar[infoLogLength + 1]; OGL_CALL(glGetShaderInfoLog, shader, infoLogLength, NULL, strInfoLog); std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; LOG(ERROR) << L"Compile failure in " << converter.from_bytes(strType) << L" shader (" << filename.c_str() << "): " << std::endl << strInfoLog; std::string infoLog = strInfoLog; delete[] strInfoLog; OGL_CALL(glDeleteShader, shader); throw shader_compiler_error() << ::boost::errinfo_file_name(filename) << compiler_error_info(infoLog) << resid_info(id) << errdesc_info("Shader compilation failed."); } return shader; }
bool Graphics::CompileShader(const char* filename, GLenum type, unsigned& shader, unsigned program) { int why = -1; char log[1024]; const char* buffer = LoadShaderFile(filename); shader = glCreateShader(type); glShaderSource(shader, 1, &buffer, &why); glCompileShader(shader); int size = 0; glGetShaderInfoLog(shader, 1024, 0, log); //if(size >= 1) //{ std::cout<<log; // return false; //} //glAttachShader(program, shader); return true; }
bool CShaderInstance::Initialize( CBaseShader* pShader ) { assert( pShader ); assert( m_Program == 0 ); m_pShader = pShader; const char* const pszName = pShader->GetName(); std::unique_ptr<char[]> vertex( LoadShaderFile( pszName, SHADER_VERTEX_EXT ) ); std::unique_ptr<char[]> frag( LoadShaderFile( pszName, SHADER_FRAG_EXT ) ); if( !vertex || !frag ) return false; GLuint vertexShader; GLuint fragShader; if( !CreateShader( pszName, vertex.get(), GL_VERTEX_SHADER, vertexShader ) ) return false; if( !CreateShader( pszName, frag.get(), GL_FRAGMENT_SHADER, fragShader ) ) { glDeleteShader( vertexShader ); check_gl_error(); return false; } m_Program = glCreateProgram(); check_gl_error(); glAttachShader( m_Program, vertexShader ); check_gl_error(); glAttachShader( m_Program, fragShader ); check_gl_error(); OnPreLink(); //Link program glLinkProgram( m_Program ); check_gl_error(); //Mark shaders as deleted so they'll be freed when the program is deleted. glDeleteShader( fragShader ); check_gl_error(); glDeleteShader( vertexShader ); check_gl_error(); //Check for errors GLint programSuccess = GL_TRUE; glGetProgramiv( m_Program, GL_LINK_STATUS, &programSuccess ); check_gl_error(); if( programSuccess != GL_TRUE ) { printf( "Error linking shader program \"%s\" (%d)!\n", pszName, m_Program ); PrintProgramLog( m_Program ); glDeleteProgram( m_Program ); check_gl_error(); m_Program = 0; return false; } if( !OnPostLink() ) { printf( "Error post-linking shader program \"%s\" (%d)!\n", pszName, m_Program ); glDeleteProgram( m_Program ); check_gl_error(); m_Program = 0; return false; } return true; }
void GLShader::Compile( ShaderType type, const std::string& path ) { CompileString(type, LoadShaderFile(path)); }