Imagination PowerVR SDK Blog

Shader doesn't load


#1

Anyone have any ideas as to why my shader does not load?



// Source and binary shaders

const char c_szFragShaderSrcFile[] = “FragShader.fsh”;

const char f_SkySrcFile[] = “f_Sky.fsh”;

const char c_szFragShaderBinFile[] = “FragShader.fsc”;

const char f_SkyBinFile[] = “f_Sky.fsc”;

const char c_szVertShaderSrcFile[] = “VertShader.vsh”;

const char v_SkySrcFile[] = “v_Sky.vsh”;

const char c_szVertShaderBinFile[] = “VertShader.vsc”;

const char v_SkyBinFile[] = “v_Sky.vsc”;




bool OGLES2Skybox2::skyboxShader(){

/

Compiles the shaders.

First we use CPVRTResourceFile to load a file into memory. After construction with a

file name, we just have to check whether the file is open or an error occured.

We load both source and binary shaders, then try the binary shader first.

The data of a CPVRTResourceFile will always be terminated with a 0 byte so it can

safely be used as a C string.

/

CPVRTResourceFile VertexShaderSrcFile(v_SkySrcFile);

CPVRTResourceFile VertexShaderBinFile(v_SkyBinFile);



CPVRTString ErrorStr = “sky shader does not load”;

/


PVRTShaderLoadBinaryFromMemory takes a pointer to the binary shader and the shader size as

its first arguments. Then follows the shader type and binary format.

On success, the handle to the new shader object is returned in the fifth parameter, while

an error string is returned on failure.

/

if (!VertexShaderBinFile.IsOpen() ||

(PVRTShaderLoadBinaryFromMemory(VertexShaderBinFile.DataPtr(), VertexShaderBinFile.Size(),

GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_uiVertexShader, &ErrorStr) != PVR_SUCCESS))

{

/


Fallback to source shader

PVRTShaderLoadSourceFromMemory() takes the shader source code as its 1st argument.

The shader type as 2nd argument (for now either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.

It returns the shader object in its 3rd argument.

If an error occurs during compilation, the resulting log is returned in the 4th parameter.

We could also use PVRTLoadAndCompileShaderFromFile() to load and

compile a shader from an external text file

/



CPVRTString vertexShaderSrc((const char
) VertexShaderSrcFile.DataPtr(), VertexShaderSrcFile.Size());



if (!VertexShaderSrcFile.IsOpen() ||

(PVRTShaderLoadSourceFromMemory(vertexShaderSrc.c_str(), GL_VERTEX_SHADER, &skyVShader, &ErrorStr) != PVR_SUCCESS))

{

PVRShellSet(prefExitMessage, ErrorStr.c_str());

OutputDebugString(“1 fails”);

return false;

}

}



/


PVRTShaderLoadFromFile can be used to try compiling/loading shaders from files. In this variant,

two files are tried before failing (usually binary and source files). The type of shader is determined

from the file extension (.fsh and .vsh for source, .fsc and .vsc for SGX binary shaders)

/

if (PVRTShaderLoadFromFile(f_SkyBinFile, f_SkySrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &skyFShader, &ErrorStr) != PVR_SUCCESS)

{

PVRShellSet(prefExitMessage, ErrorStr.c_str());

OutputDebugString(“2 fails”);

return false;

}



/


PVRTCreateProgram creates a new program object, attaches the shaders, binds attributes (given as an array

of strings and the size thereof), and makes the program current - or it returns an error string on failure.

*/

if (PVRTCreateProgram(&skyShaderProgram.uiId, skyVShader, skyFShader, skyAttribNames, eSkyAttribs, &ErrorStr) != PVR_SUCCESS)

{

PVRShellSet(prefExitMessage, ErrorStr.c_str());

OutputDebugString(“3 fails”);

return false;

}



return true;

}




I then call skybox shader within initView


#2

Hi John,



When you say the shader doesn’t load, what exactly do you mean? Is this a problem with your application loading the file into memory, or is it a shader compilation/linking issue?



Have you tried setting a break point in your code and stepping into the PVRTools to find the cause of the problem?



Thanks,

Joe


#3

Hi Joe I believe the problem is that it its not loading the source from memory as it fails right here



if (!VertexShaderSrcFile.IsOpen() ||

(PVRTShaderLoadSourceFromMemory(vertexShaderSrc.c_str(), GL_VERTEX_SHADER, &skyVShader, &ErrorStr) != PVR_SUCCESS))

{

PVRShellSet(prefExitMessage, ErrorStr.c_str());

OutputDebugString(“1 fails”);

return false;

}




Thanks

John


#4

Hi John,



This sounds like a similar problem to your cannot load in skybox texture post.



Are you calling this function at the start of InitApplication()?:


// Get and set the read path for content files<br />
CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));<br />

```<br />
<br />
This function tells our resource loader where the default file read location should be. The reason you're not seeing the problem for the Example's original files is that they have been converted into .cpp files that are built into the application, so the file system does not need to be accessed to load these files.<br />
<br />
The FileWrap tool in our SDK can be used to wrap your own files in the same way. Doing so removes the need to load from a file location, as your files will be built-in to the executable.<br />
<br />
Thanks,<br />
Joe

#5

Hi Joe, I have called that function at the start of InitApplication()



// Get and set the read path for content files

CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));



// Get and set the load/release functions for loading external files.

// In the majority of cases the PVRShell will return NULL function pointers implying that

// nothing special is required to load external files.

CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));




Also I have used the file wrap tool for my textures and shaders, but it won’t compile as the the problem with my skybox persists


#6

Have you included the wrapped .cpp files in your Visual Studio project?



Joe


#7

Hi Joe,



Thanks very much that actually solved all my problems I had.



John


#8

Hi John,



No problem. Glad to hear it’s working now :slight_smile:



Joe