/* * Carga un programa a partir de un fichero binario (ya compilado), o, si este * no existe, compila y construye un programa a partir de un fichero con el * código fuente. * > ctx : Contexto en el cual crear el programa. * > ds : Array con los dispostivos seleccionados. * > src : Ruta del código fuente. * > bin : Ruta del fichero binario. */ cl_program loadProgramFromArgs (cl_context ctx, cl_device_id *ds, cl_uint ds_size, char *src, char *bin) { FILE *f; char *data; cl_program prg; size_t size; if ((f = fopen(bin, "rb")) != NULL) return loadBinaryProgram(ctx, ds, ds_size, bin); if ((f = fopen(src, "r")) != NULL) { printf("Compiling %s... ", src); fflush(stdout); data = (char*) malloc(PRG_BUFFER_SIZE * sizeof(char)); size = fread(data, 1, PRG_BUFFER_SIZE, f); fclose(f); data[size] = '\0'; prg = clCreateProgramWithSource(ctx, 1, (const char**)&data, NULL, NULL); if(clBuildProgram(prg, ds_size, ds, NULL, NULL, NULL) != CL_SUCCESS) { fprintf(stderr, "FAIL\n"); showProgramBuildLog(ds, ds_size, prg); return NULL; } printf("OK\n"); saveBinaryProgram(prg, ds, ds_size, bin); return prg; } return NULL; }
/*!**************************************************************************** @Function InitView @Return bool true if no error occured @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLES2BinaryShader::InitView() { // Initialise a colour to draw our triangle // (For this training course, binary loaded shaders use a different colour // To show which is being used. Red means it had to compile the shaders, // green shows that it retrieved the binary from memory. float afColour[]={0.0,0.0,0.0}; // Filename and path strings. char* pWritePath = (char*)PVRShellGet(prefWritePath); char* shaderPath = new char[strlen(pWritePath) + 13]; sprintf(shaderPath, "%sShaderBinary", pWritePath); //Checks if the program binary handling extension is supported. m_bBinaryShaderSupported=IsGLExtensionSupported("GL_OES_get_program_binary"); #if !defined (TARGET_OS_IPHONE) glGetProgramBinaryOES=0; glProgramBinaryOES=0; // Retrieves the functions needed to use the extension. if (m_bBinaryShaderSupported) { glGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) PVRGetProcAddress(glGetProgramBinaryOES); glProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC) PVRGetProcAddress(glProgramBinaryOES); } #endif // If binary shaders are not supported or there isn't a valid binary shader stored, recompile the shaders. if (!m_bBinaryShaderSupported || !loadBinaryProgram(shaderPath,m_uiProgramObject)) { { // Fragment shader code const char* pszFragShader = "\ uniform lowp vec3 myColour;\ void main (void)\ {\ gl_FragColor = vec4(myColour, 1.0);\ }"; // Create the fragment shader object m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER); // Load the source code into it glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL); // Compile the source code glCompileShader(m_uiFragShader); // Check if compilation succeeded GLint bShaderCompiled; glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { // An error happened, first retrieve the length of the log message int i32InfoLogLength, i32CharsWritten; glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); // Allocate enough space for the message and retrieve it char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); /* Displays the message in a dialog box when the application quits using the shell PVRShellSet function with first parameter prefExitMessage. */ char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to compile fragment shader: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } }
/*!**************************************************************************** @Function InitView @Return bool true if no error occured @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLES3BinaryShader::InitView() { // Initialise a colour to draw our triangle // (For this training course, binary loaded shaders use a different colour // To show which is being used. Red means it had to compile the shaders, // green shows that it retrieved the binary from memory. float afColour[]={0.0,0.0,0.0}; // Filename and path strings. char* pWritePath = (char*)PVRShellGet(prefWritePath); char* shaderPath = new char[strlen(pWritePath) + 13]; sprintf(shaderPath, "%sShaderBinary", pWritePath); // If binary shaders are not supported or there isn't a valid binary shader stored, recompile the shaders. if(!loadBinaryProgram(shaderPath,m_uiProgramObject)) { { // Fragment shader code const char* pszFragShader = "\ #version 300 es\n\ uniform lowp vec3 myColour;\ layout (location = 0) out lowp vec4 oColour;\ void main (void)\ {\ oColour = vec4(myColour, 1.0);\ }"; // Create the fragment shader object m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER); // Load the source code into it glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL); // Compile the source code glCompileShader(m_uiFragShader); // Check if compilation succeeded GLint bShaderCompiled; glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { // An error happened, first retrieve the length of the log message int i32InfoLogLength, i32CharsWritten; glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); // Allocate enough space for the message and retrieve it char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); /* Displays the message in a dialog box when the application quits using the shell PVRShellSet function with first parameter prefExitMessage. */ char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to compile fragment shader: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } } { // Vertex shader code. const char* pszVertShader = "\ #version 300 es\n\ layout (location = 0) in highp vec4 myVertex;\ uniform mediump mat4 myPMVMatrix;\ void main(void)\ {\ gl_Position = myPMVMatrix * myVertex;\ }"; // Loads the vertex shader in the same way m_uiVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(m_uiVertexShader, 1, (const char**)&pszVertShader, NULL); glCompileShader(m_uiVertexShader); // Checks if the shader has compiled. GLint bShaderCompiled; glGetShaderiv(m_uiVertexShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { int i32InfoLogLength, i32CharsWritten; glGetShaderiv(m_uiVertexShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(m_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to compile vertex shader: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } } // Create the shader program m_uiProgramObject = glCreateProgram(); // Attach the fragment and vertex shaders to the shader program. glAttachShader(m_uiProgramObject, m_uiFragShader); glAttachShader(m_uiProgramObject, m_uiVertexShader); // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY glBindAttribLocation(m_uiProgramObject, VERTEX_ARRAY, "myVertex"); // Link the program glLinkProgram(m_uiProgramObject); // Check if linking succeeded in the same way we checked for compilation success GLint bLinked; glGetProgramiv(m_uiProgramObject, GL_LINK_STATUS, &bLinked); if (!bLinked) { int i32InfoLogLength, i32CharsWritten; glGetProgramiv(m_uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength); char* pszInfoLog = new char[i32InfoLogLength]; glGetProgramInfoLog(m_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog); char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to link program: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } // As there is no stored binary, save the current binary out for use later. // Note that this is done after both binding attributes and linking - // none of these can be performed after saveBinaryProgram(shaderPath,m_uiProgramObject); //Set red channel of the colour to maximum - red shows that the shaders had to be compiled. afColour[0]=1.0f; } else { //Set green channel of the colour to maximum - green shows that the shaders were loaded from binary files. afColour[1]=1.0f; } delete[] shaderPath; // Uses the program. glUseProgram(m_uiProgramObject); // Bind the colour to the fragment shader. GLint i32ColourLocation = glGetUniformLocation(m_uiProgramObject, "myColour"); // Then passes the colour to that variable glUniform3fv(i32ColourLocation, 1, afColour); // Sets the clear color glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // Create VBO for the triangle from our data // Vertex data GLfloat afVertices[] = {-0.4f,-0.4f,0.0f, 0.4f,-0.4f,0.0f, 0.0f,0.4f,0.0f}; // Gen VBO glGenBuffers(1, &m_ui32Vbo); // Bind the VBO glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo); // Set the buffer's data glBufferData(GL_ARRAY_BUFFER, 3 * (3 * sizeof(GLfloat)) /* 3 Vertices of 3 floats in size */, afVertices, GL_STATIC_DRAW); // Unbind the VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // Enable culling glEnable(GL_CULL_FACE); return true; }