1//
2// Copyright (c) 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#include "shader_utils.h"
18#include "texture_utils.h"
19
20class MipMap2DSample : public SampleApplication
21{
22  public:
23    MipMap2DSample::MipMap2DSample()
24        : SampleApplication("MipMap2D", 1280, 720)
25    {
26    }
27
28    virtual bool initialize()
29    {
30        const std::string vs = SHADER_SOURCE
31        (
32            uniform float u_offset;
33            attribute vec4 a_position;
34            attribute vec2 a_texCoord;
35            varying vec2 v_texCoord;
36            void main()
37            {
38                gl_Position = a_position;
39                gl_Position.x += u_offset;
40                v_texCoord = a_texCoord;
41            }
42        );
43
44        const std::string fs = SHADER_SOURCE
45        (
46            precision mediump float;
47            varying vec2 v_texCoord;
48            uniform sampler2D s_texture;
49            void main()
50            {
51                gl_FragColor = texture2D(s_texture, v_texCoord);
52            }
53        );
54
55        mProgram = CompileProgram(vs, fs);
56        if (!mProgram)
57        {
58            return false;
59        }
60
61        // Get the attribute locations
62        mPositionLoc = glGetAttribLocation(mProgram, "a_position");
63        mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
64
65        // Get the sampler location
66        mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
67
68        // Get the offset location
69        mOffsetLoc = glGetUniformLocation(mProgram, "u_offset");
70
71        // Load the texture
72        mTextureID = CreateMipMappedTexture2D();
73
74        // Check Anisotropy limits
75        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mMaxAnisotropy);
76
77        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
78
79        return true;
80    }
81
82    virtual void destroy()
83    {
84        glDeleteProgram(mProgram);
85        glDeleteTextures(1, &mTextureID);
86    }
87
88    virtual void draw()
89    {
90        const GLfloat vertices[] =
91        {
92            -0.25f,  0.5f, 0.0f, 5.0f, // Position 0
93             0.0f,  0.0f,              // TexCoord 0
94            -0.25f, -0.5f, 0.0f, 1.0f, // Position 1
95             0.0f,  1.0f,              // TexCoord 1
96             0.25f, -0.5f, 0.0f, 1.0f, // Position 2
97             1.0f,  1.0f,              // TexCoord 2
98             0.25f,  0.5f, 0.0f, 5.0f, // Position 3
99             1.0f,  0.0f               // TexCoord 3
100        };
101        const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
102
103        // Set the viewport
104        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
105
106        // Clear the color buffer
107        glClear(GL_COLOR_BUFFER_BIT);
108
109        // Use the program object
110        glUseProgram(mProgram);
111
112        // Load the vertex position
113        glVertexAttribPointer(mPositionLoc, 4, GL_FLOAT,  GL_FALSE, 6 * sizeof(GLfloat), vertices);
114        // Load the texture coordinate
115        glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), vertices + 4);
116
117        glEnableVertexAttribArray(mPositionLoc);
118        glEnableVertexAttribArray(mTexCoordLoc);
119
120        // Bind the texture
121        glActiveTexture(GL_TEXTURE0);
122        glBindTexture(GL_TEXTURE_2D, mTextureID);
123
124        // Set the sampler texture unit to 0
125        glUniform1i(mSamplerLoc, 0);
126
127        // Draw quad with nearest sampling
128        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
129        glUniform1f(mOffsetLoc, -0.6f);
130        glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
131
132        // Draw quad with trilinear filtering
133        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
134        glUniform1f(mOffsetLoc, 0.0f);
135        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
136
137        // Draw quad with anisotropic filtering
138        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
139        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, mMaxAnisotropy);
140        glUniform1f(mOffsetLoc, 0.6f);
141        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
142        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
143    }
144
145  private:
146    // Handle to a program object
147    GLuint mProgram;
148
149    // Attribute locations
150    GLint mPositionLoc;
151    GLint mTexCoordLoc;
152
153    // Sampler location
154    GLint mSamplerLoc;
155
156    // Offset location
157    GLint mOffsetLoc;
158
159    // Texture handle
160    GLuint mTextureID;
161
162    float mMaxAnisotropy;
163};
164
165int main(int argc, char **argv)
166{
167    MipMap2DSample app;
168    return app.run();
169}
170