123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /******************************************************************************
- @File OGLES2Texturing.cpp
- @Title Texturing
- @Version
- @Copyright Copyright (C) Imagination Technologies Limited.
- @Platform Independant
- @Description Shows how to use textures in OpenGL ES 2.0
- ******************************************************************************/
- #include <stdio.h>
- #include <string.h>
- #if defined(__APPLE__)
- #import <OpenGLES/ES2/gl.h>
- #import <OpenGLES/ES2/glext.h>
- #else
- #if defined(__BADA__)
- #include <FGraphicsOpengl2.h>
- using namespace Osp::Graphics::Opengl;
- #else
- #include <GLES2/gl2.h>
- #endif
- #endif
- #include "PVRShell.h"
- /******************************************************************************
- Defines
- ******************************************************************************/
- // Index to bind the attributes to vertex shaders
- #define VERTEX_ARRAY 0
- #define TEXCOORD_ARRAY 1
- // Size of the texture we create
- #define TEX_SIZE 128
- /*!****************************************************************************
- Class implementing the PVRShell functions.
- ******************************************************************************/
- class OGLES2Texturing : public PVRShell
- {
- // The vertex and fragment shader OpenGL handles
- GLuint m_uiVertexShader, m_uiFragShader;
- // The program object containing the 2 shader objects
- GLuint m_uiProgramObject;
- // Texture handle
- GLuint m_uiTexture;
- // VBO handle
- GLuint m_ui32Vbo;
- //
- unsigned int m_ui32VertexStride;
- public:
- virtual bool InitApplication();
- virtual bool InitView();
- virtual bool ReleaseView();
- virtual bool QuitApplication();
- virtual bool RenderScene();
- };
- /*!****************************************************************************
- @Function InitApplication
- @Return bool true if no error occured
- @Description Code in InitApplication() will be called by PVRShell once per
- run, before the rendering context is created.
- Used to initialize variables that are not dependant on it
- (e.g. external modules, loading meshes, etc.)
- If the rendering context is lost, InitApplication() will
- not be called again.
- ******************************************************************************/
- bool OGLES2Texturing::InitApplication()
- {
- return true;
- }
- /*!****************************************************************************
- @Function QuitApplication
- @Return bool true if no error occured
- @Description Code in QuitApplication() will be called by PVRShell once per
- run, just before exiting the program.
- If the rendering context is lost, QuitApplication() will
- not be called.
- ******************************************************************************/
- bool OGLES2Texturing::QuitApplication()
- {
- return true;
- }
- /*!****************************************************************************
- @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 OGLES2Texturing::InitView()
- {
- // Fragment and vertex shaders code
- const char* pszFragShader = "\
- uniform sampler2D sampler2d;\
- varying mediump vec2 myTexCoord;\
- void main (void)\
- {\
- gl_FragColor = texture2D(sampler2d,myTexCoord);\
- }";
- const char* pszVertShader = "\
- attribute highp vec4 myVertex;\
- attribute mediump vec4 myUV;\
- uniform mediump mat4 myPMVMatrix;\
- varying mediump vec2 myTexCoord;\
- void main(void)\
- {\
- gl_Position = myPMVMatrix * myVertex;\
- myTexCoord = myUV.st;\
- }";
- // 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;
- return false;
- }
- // 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);
- 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;
- return false;
- }
- // Create the shader program
- m_uiProgramObject = glCreateProgram();
- // Attach the fragment and vertex shaders to it
- 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");
- // Bind the custom vertex attribute "myUV" to location TEXCOORD_ARRAY
- glBindAttribLocation(m_uiProgramObject, TEXCOORD_ARRAY, "myUV");
- // 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;
- return false;
- }
- // Actually use the created program
- glUseProgram(m_uiProgramObject);
- // Sets the sampler2D variable to the first texture unit
- glUniform1i(glGetUniformLocation(m_uiProgramObject, "sampler2d"), 0);
- // Sets the clear color
- glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
- /*
- Creates the texture
- */
- // Allocates one texture handle
- glGenTextures(1, &m_uiTexture);
- // Binds this texture handle so we can load the data into it
- glBindTexture(GL_TEXTURE_2D, m_uiTexture);
- // Creates the data as a 32bits integer array (8bits per component)
- GLuint* pTexData = new GLuint[TEX_SIZE*TEX_SIZE];
- for (int i=0; i<TEX_SIZE; i++)
- for (int j=0; j<TEX_SIZE; j++)
- {
- // Fills the data with a fancy pattern
- GLuint col = (255L<<24) + ((255L-j*2)<<16) + ((255L-i)<<8) + (255L-i*2);
- if ( ((i*j)/8) % 2 ) col = (GLuint) (255L<<24) + (255L<<16) + (0L<<8) + (255L);
- pTexData[j*TEX_SIZE+i] = col;
- }
- /*
- glTexImage2D loads the texture data into the texture object.
- void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, const GLvoid *pixels );
- target must be GL_TEXTURE_2D.
- level specify the mipmap level we want to upload.
- internalformat and format must be the same. Here we use GL_RGBA for 4 component colors (r,g,b,a).
- We could use GL_RGB, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA to use different color component combinations.
- width, height specify the size of the texture. Both of the dimensions must be power of 2.
- border must be 0.
- type specify the format of the data. We use GL_UNSIGNED_BYTE to describe a color component as an unsigned byte.
- So a pixel is described by a 32bits integer.
- We could also use GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, and GL_UNSIGNED_SHORT_5_5_5_1
- to specify the size of all 3 (or 4) color components. If we used any of these 3 constants,
- a pixel would then be described by a 16bits integer.
- */
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData);
- /*
- glTexParameterf is used to set the texture parameters
- void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
- target must be GL_TEXTURE_2D.
- pname is the parameter name we want to modify.
- If pname is GL_TEXTURE_MIN_FILTER, param is used to set the way the texture is rendered when made smaller.
- We can tell OpenGL to interpolate between the pixels in a mipmap level but also between different mipmap levels.
- We are not using mipmap interpolation here because we didn't defined the mipmap levels of our texture.
- If pname is GL_TEXTURE_MAG_FILTER, param is used to set the way the texture is rendered when made bigger.
- Here we can only tell OpenGL to interpolate between the pixels of the first mipmap level.
- if pname is GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T, then param sets the way a texture tiles in both directions.
- The default if GL_REPEAT to wrap the texture (repeat it). We could also set it to GL_CLAMP or GL_CLAMP_TO_EDGE
- to clamp the texture.
- On OpenGL ES 1.1 and 2.0, if pname is GL_GENERATE_MIPMAP, param tells OpenGL to create mipmap levels automatically.
- */
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- // Deletes the texture data, it's now in OpenGL memory
- delete [] pTexData;
- // Create VBO for the triangle from our data
- // Interleaved vertex data
- GLfloat afVertices[] = {-0.4f,-0.4f,0.0f, // Pos
- 0.0f,0.0f , // UVs
- 0.4f,-0.4f,0.0f,
- 1.0f,0.0f ,
- 0.0f,0.4f ,0.0f,
- 0.5f,1.0f};
- glGenBuffers(1, &m_ui32Vbo);
- m_ui32VertexStride = 5 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs
- // Bind the VBO
- glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);
- // Set the buffer's data
- glBufferData(GL_ARRAY_BUFFER, 3 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
- // Unbind the VBO
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- return true;
- }
- /*!****************************************************************************
- @Function ReleaseView
- @Return bool true if no error occured
- @Description Code in ReleaseView() will be called by PVRShell when the
- application quits or before a change in the rendering context.
- ******************************************************************************/
- bool OGLES2Texturing::ReleaseView()
- {
- // Frees the texture
- glDeleteTextures(1, &m_uiTexture);
- // Release Vertex buffer object.
- glDeleteBuffers(1, &m_ui32Vbo);
- // Frees the OpenGL handles for the program and the 2 shaders
- glDeleteProgram(m_uiProgramObject);
- glDeleteShader(m_uiVertexShader);
- glDeleteShader(m_uiFragShader);
- return true;
- }
- /*!****************************************************************************
- @Function RenderScene
- @Return bool true if no error occured
- @Description Main rendering loop function of the program. The shell will
- call this function every frame.
- eglSwapBuffers() will be performed by PVRShell automatically.
- PVRShell will also manage important OS events.
- Will also manage relevent OS events. The user has access to
- these events through an abstraction layer provided by PVRShell.
- ******************************************************************************/
- bool OGLES2Texturing::RenderScene()
- {
- // Clears the color buffer
- glClear(GL_COLOR_BUFFER_BIT);
- /*
- Bind the projection model view matrix (PMVMatrix) to
- the associated uniform variable in the shader
- */
- // Matrix used for projection model view
- float afIdentity[] = {
- 1,0,0,0,
- 0,1,0,0,
- 0,0,1,0,
- 0,0,0,1
- };
- // First gets the location of that variable in the shader using its name
- int i32Location = glGetUniformLocation(m_uiProgramObject, "myPMVMatrix");
- // Then passes the matrix to that variable
- glUniformMatrix4fv(i32Location, 1, GL_FALSE, afIdentity);
- /*
- Draw a triangle.
- Please refer to HelloTriangle or IntroducingPVRShell for a detailed explanation.
- */
- // Bind the VBO
- glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);
- // Pass the vertex data
- glEnableVertexAttribArray(VERTEX_ARRAY);
- glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
- // Pass the texture coordinates data
- glEnableVertexAttribArray(TEXCOORD_ARRAY);
- glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (3 * sizeof(GLfloat)));
- // Draws a non-indexed triangle array
- glDrawArrays(GL_TRIANGLES, 0, 3);
- // Unbind the VBO
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- return true;
- }
- /*!****************************************************************************
- @Function NewDemo
- @Return PVRShell* The demo supplied by the user
- @Description This function must be implemented by the user of the shell.
- The user should return its PVRShell object defining the
- behaviour of the application.
- ******************************************************************************/
- PVRShell* NewDemo()
- {
- return new OGLES2Texturing();
- }
- /******************************************************************************
- End of file (OGLES2Texturing.cpp)
- ******************************************************************************/
|