1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 //            Based on MipMap2D.c from
8 // Book:      OpenGL(R) ES 2.0 Programming Guide
9 // Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10 // ISBN-10:   0321502795
11 // ISBN-13:   9780321502797
12 // Publisher: Addison-Wesley Professional
13 // URLs:      http://safari.informit.com/9780321563835
14 //            http://www.opengles-book.com
15 
16 #include "SampleApplication.h"
17 
18 #include "texture_utils.h"
19 #include "util/shader_utils.h"
20 
21 class MipMap2DSample : public SampleApplication
22 {
23   public:
MipMap2DSample(int argc,char ** argv)24     MipMap2DSample(int argc, char **argv) : SampleApplication("MipMap2D", argc, argv) {}
25 
initialize()26     bool initialize() override
27     {
28         constexpr char kVS[] = R"(uniform float u_offset;
29 attribute vec4 a_position;
30 attribute vec2 a_texCoord;
31 varying vec2 v_texCoord;
32 void main()
33 {
34     gl_Position = a_position;
35     gl_Position.x += u_offset;
36     v_texCoord = a_texCoord;
37 })";
38 
39         constexpr char kFS[] = R"(precision mediump float;
40 varying vec2 v_texCoord;
41 uniform sampler2D s_texture;
42 void main()
43 {
44     gl_FragColor = texture2D(s_texture, v_texCoord);
45 })";
46 
47         mProgram = CompileProgram(kVS, kFS);
48         if (!mProgram)
49         {
50             return false;
51         }
52 
53         // Get the attribute locations
54         mPositionLoc = glGetAttribLocation(mProgram, "a_position");
55         mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
56 
57         // Get the sampler location
58         mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
59 
60         // Get the offset location
61         mOffsetLoc = glGetUniformLocation(mProgram, "u_offset");
62 
63         // Load the texture
64         mTextureID = CreateMipMappedTexture2D();
65 
66         // Check Anisotropy limits
67         glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mMaxAnisotropy);
68 
69         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
70 
71         return true;
72     }
73 
destroy()74     void destroy() override
75     {
76         glDeleteProgram(mProgram);
77         glDeleteTextures(1, &mTextureID);
78     }
79 
draw()80     void draw() override
81     {
82         const GLfloat vertices[] = {
83             -0.25f, 0.5f,  0.0f, 5.0f,  // Position 0
84             0.0f,   0.0f,               // TexCoord 0
85             -0.25f, -0.5f, 0.0f, 1.0f,  // Position 1
86             0.0f,   1.0f,               // TexCoord 1
87             0.25f,  -0.5f, 0.0f, 1.0f,  // Position 2
88             1.0f,   1.0f,               // TexCoord 2
89             0.25f,  0.5f,  0.0f, 5.0f,  // Position 3
90             1.0f,   0.0f                // TexCoord 3
91         };
92         const GLushort indices[] = {0, 1, 2, 0, 2, 3};
93 
94         // Set the viewport
95         glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
96 
97         // Clear the color buffer
98         glClear(GL_COLOR_BUFFER_BIT);
99 
100         // Use the program object
101         glUseProgram(mProgram);
102 
103         // Load the vertex position
104         glVertexAttribPointer(mPositionLoc, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), vertices);
105         // Load the texture coordinate
106         glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
107                               vertices + 4);
108 
109         glEnableVertexAttribArray(mPositionLoc);
110         glEnableVertexAttribArray(mTexCoordLoc);
111 
112         // Bind the texture
113         glActiveTexture(GL_TEXTURE0);
114         glBindTexture(GL_TEXTURE_2D, mTextureID);
115 
116         // Set the sampler texture unit to 0
117         glUniform1i(mSamplerLoc, 0);
118 
119         // Draw quad with nearest sampling
120         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
121         glUniform1f(mOffsetLoc, -0.6f);
122         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
123 
124         // Draw quad with trilinear filtering
125         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
126         glUniform1f(mOffsetLoc, 0.0f);
127         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
128 
129         // Draw quad with anisotropic filtering
130         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
131         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, mMaxAnisotropy);
132         glUniform1f(mOffsetLoc, 0.6f);
133         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
134         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
135     }
136 
137   private:
138     // Handle to a program object
139     GLuint mProgram;
140 
141     // Attribute locations
142     GLint mPositionLoc;
143     GLint mTexCoordLoc;
144 
145     // Sampler location
146     GLint mSamplerLoc;
147 
148     // Offset location
149     GLint mOffsetLoc;
150 
151     // Texture handle
152     GLuint mTextureID;
153 
154     float mMaxAnisotropy;
155 };
156 
main(int argc,char ** argv)157 int main(int argc, char **argv)
158 {
159     MipMap2DSample app(argc, argv);
160     return app.run();
161 }
162