1e977efc43aab920b397c1388720287105140cb76Geoff Lang//
2e977efc43aab920b397c1388720287105140cb76Geoff Lang// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3e977efc43aab920b397c1388720287105140cb76Geoff Lang// Use of this source code is governed by a BSD-style license that can be
4e977efc43aab920b397c1388720287105140cb76Geoff Lang// found in the LICENSE file.
5e977efc43aab920b397c1388720287105140cb76Geoff Lang//
6e977efc43aab920b397c1388720287105140cb76Geoff Lang
7e977efc43aab920b397c1388720287105140cb76Geoff Lang//            Based on Simple_VertexShader.c from
8e977efc43aab920b397c1388720287105140cb76Geoff Lang// Book:      OpenGL(R) ES 2.0 Programming Guide
9e977efc43aab920b397c1388720287105140cb76Geoff Lang// Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10e977efc43aab920b397c1388720287105140cb76Geoff Lang// ISBN-10:   0321502795
11e977efc43aab920b397c1388720287105140cb76Geoff Lang// ISBN-13:   9780321502797
12e977efc43aab920b397c1388720287105140cb76Geoff Lang// Publisher: Addison-Wesley Professional
13e977efc43aab920b397c1388720287105140cb76Geoff Lang// URLs:      http://safari.informit.com/9780321563835
14e977efc43aab920b397c1388720287105140cb76Geoff Lang//            http://www.opengles-book.com
15e977efc43aab920b397c1388720287105140cb76Geoff Lang
16e977efc43aab920b397c1388720287105140cb76Geoff Lang#include "SampleApplication.h"
17e977efc43aab920b397c1388720287105140cb76Geoff Lang#include "shader_utils.h"
18e977efc43aab920b397c1388720287105140cb76Geoff Lang#include "texture_utils.h"
19e977efc43aab920b397c1388720287105140cb76Geoff Lang#include "geometry_utils.h"
20e977efc43aab920b397c1388720287105140cb76Geoff Lang#include "Vector.h"
21e977efc43aab920b397c1388720287105140cb76Geoff Lang#include "Matrix.h"
22e977efc43aab920b397c1388720287105140cb76Geoff Lang#include <iostream>
23e977efc43aab920b397c1388720287105140cb76Geoff Lang
24e977efc43aab920b397c1388720287105140cb76Geoff Langclass PostSubBufferSample : public SampleApplication
25e977efc43aab920b397c1388720287105140cb76Geoff Lang{
26e977efc43aab920b397c1388720287105140cb76Geoff Lang  public:
27e977efc43aab920b397c1388720287105140cb76Geoff Lang    PostSubBufferSample::PostSubBufferSample()
28e977efc43aab920b397c1388720287105140cb76Geoff Lang        : SampleApplication("PostSubBuffer", 1280, 720)
29e977efc43aab920b397c1388720287105140cb76Geoff Lang    {
30e977efc43aab920b397c1388720287105140cb76Geoff Lang    }
31e977efc43aab920b397c1388720287105140cb76Geoff Lang
32e977efc43aab920b397c1388720287105140cb76Geoff Lang    virtual bool initialize()
33e977efc43aab920b397c1388720287105140cb76Geoff Lang    {
34e977efc43aab920b397c1388720287105140cb76Geoff Lang        mPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC)eglGetProcAddress("eglPostSubBufferNV");
35e977efc43aab920b397c1388720287105140cb76Geoff Lang        if (!mPostSubBufferNV)
36e977efc43aab920b397c1388720287105140cb76Geoff Lang        {
37e977efc43aab920b397c1388720287105140cb76Geoff Lang            std::cerr << "Could not load eglPostSubBufferNV.";
38e977efc43aab920b397c1388720287105140cb76Geoff Lang            return false;
39e977efc43aab920b397c1388720287105140cb76Geoff Lang        }
40e977efc43aab920b397c1388720287105140cb76Geoff Lang
41e977efc43aab920b397c1388720287105140cb76Geoff Lang        const std::string vs = SHADER_SOURCE
42e977efc43aab920b397c1388720287105140cb76Geoff Lang        (
43e977efc43aab920b397c1388720287105140cb76Geoff Lang            uniform mat4 u_mvpMatrix;
44e977efc43aab920b397c1388720287105140cb76Geoff Lang            attribute vec4 a_position;
45e977efc43aab920b397c1388720287105140cb76Geoff Lang            attribute vec2 a_texcoord;
46e977efc43aab920b397c1388720287105140cb76Geoff Lang            varying vec2 v_texcoord;
47e977efc43aab920b397c1388720287105140cb76Geoff Lang            void main()
48e977efc43aab920b397c1388720287105140cb76Geoff Lang            {
49e977efc43aab920b397c1388720287105140cb76Geoff Lang                gl_Position = u_mvpMatrix * a_position;
50e977efc43aab920b397c1388720287105140cb76Geoff Lang                v_texcoord = a_texcoord;
51e977efc43aab920b397c1388720287105140cb76Geoff Lang            }
52e977efc43aab920b397c1388720287105140cb76Geoff Lang        );
53e977efc43aab920b397c1388720287105140cb76Geoff Lang
54e977efc43aab920b397c1388720287105140cb76Geoff Lang        const std::string fs = SHADER_SOURCE
55e977efc43aab920b397c1388720287105140cb76Geoff Lang        (
56e977efc43aab920b397c1388720287105140cb76Geoff Lang            precision mediump float;
57e977efc43aab920b397c1388720287105140cb76Geoff Lang            varying vec2 v_texcoord;
58e977efc43aab920b397c1388720287105140cb76Geoff Lang            void main()
59e977efc43aab920b397c1388720287105140cb76Geoff Lang            {
60e977efc43aab920b397c1388720287105140cb76Geoff Lang                gl_FragColor = vec4(v_texcoord.x, v_texcoord.y, 1.0, 1.0);
61e977efc43aab920b397c1388720287105140cb76Geoff Lang            }
62e977efc43aab920b397c1388720287105140cb76Geoff Lang        );
63e977efc43aab920b397c1388720287105140cb76Geoff Lang
64e977efc43aab920b397c1388720287105140cb76Geoff Lang        mProgram = CompileProgram(vs, fs);
65e977efc43aab920b397c1388720287105140cb76Geoff Lang        if (!mProgram)
66e977efc43aab920b397c1388720287105140cb76Geoff Lang        {
67e977efc43aab920b397c1388720287105140cb76Geoff Lang            return false;
68e977efc43aab920b397c1388720287105140cb76Geoff Lang        }
69e977efc43aab920b397c1388720287105140cb76Geoff Lang
70e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Get the attribute locations
71e977efc43aab920b397c1388720287105140cb76Geoff Lang        mPositionLoc = glGetAttribLocation(mProgram, "a_position");
72e977efc43aab920b397c1388720287105140cb76Geoff Lang        mTexcoordLoc = glGetAttribLocation(mProgram, "a_texcoord");
73e977efc43aab920b397c1388720287105140cb76Geoff Lang
74e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Get the uniform locations
75e977efc43aab920b397c1388720287105140cb76Geoff Lang        mMVPMatrixLoc = glGetUniformLocation(mProgram, "u_mvpMatrix");
76e977efc43aab920b397c1388720287105140cb76Geoff Lang
77e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Generate the geometry data
78e977efc43aab920b397c1388720287105140cb76Geoff Lang        GenerateCubeGeometry(0.5f, &mCube);
79e977efc43aab920b397c1388720287105140cb76Geoff Lang
80e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Set an initial rotation
81e977efc43aab920b397c1388720287105140cb76Geoff Lang        mRotation = 45.0f;
82e977efc43aab920b397c1388720287105140cb76Geoff Lang
83e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Clear the whole window surface to blue.
84e977efc43aab920b397c1388720287105140cb76Geoff Lang        glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
85e977efc43aab920b397c1388720287105140cb76Geoff Lang        glClear(GL_COLOR_BUFFER_BIT);
86e977efc43aab920b397c1388720287105140cb76Geoff Lang        SampleApplication::swap();
87e977efc43aab920b397c1388720287105140cb76Geoff Lang
88e977efc43aab920b397c1388720287105140cb76Geoff Lang        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
89e977efc43aab920b397c1388720287105140cb76Geoff Lang        glCullFace(GL_BACK);
90e977efc43aab920b397c1388720287105140cb76Geoff Lang        glEnable(GL_CULL_FACE);
91e977efc43aab920b397c1388720287105140cb76Geoff Lang
92e977efc43aab920b397c1388720287105140cb76Geoff Lang        return true;
93e977efc43aab920b397c1388720287105140cb76Geoff Lang    }
94e977efc43aab920b397c1388720287105140cb76Geoff Lang
95e977efc43aab920b397c1388720287105140cb76Geoff Lang    virtual void destroy()
96e977efc43aab920b397c1388720287105140cb76Geoff Lang    {
97e977efc43aab920b397c1388720287105140cb76Geoff Lang        glDeleteProgram(mProgram);
98e977efc43aab920b397c1388720287105140cb76Geoff Lang    }
99e977efc43aab920b397c1388720287105140cb76Geoff Lang
100e977efc43aab920b397c1388720287105140cb76Geoff Lang    virtual void step(float dt, double totalTime)
101e977efc43aab920b397c1388720287105140cb76Geoff Lang    {
102e977efc43aab920b397c1388720287105140cb76Geoff Lang        mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);
103e977efc43aab920b397c1388720287105140cb76Geoff Lang
104e977efc43aab920b397c1388720287105140cb76Geoff Lang        Matrix4 perspectiveMatrix = Matrix4::perspective(60.0f, float(getWindow()->getWidth()) / getWindow()->getHeight(),
105e977efc43aab920b397c1388720287105140cb76Geoff Lang                                                         1.0f, 20.0f);
106e977efc43aab920b397c1388720287105140cb76Geoff Lang
107e977efc43aab920b397c1388720287105140cb76Geoff Lang        Matrix4 modelMatrix = Matrix4::translate(Vector3(0.0f, 0.0f, -2.0f)) *
108e977efc43aab920b397c1388720287105140cb76Geoff Lang                              Matrix4::rotate(mRotation, Vector3(1.0f, 0.0f, 1.0f));
109e977efc43aab920b397c1388720287105140cb76Geoff Lang
110e977efc43aab920b397c1388720287105140cb76Geoff Lang        Matrix4 viewMatrix = Matrix4::identity();
111e977efc43aab920b397c1388720287105140cb76Geoff Lang
112e977efc43aab920b397c1388720287105140cb76Geoff Lang        Matrix4 mvpMatrix = perspectiveMatrix * viewMatrix * modelMatrix;
113e977efc43aab920b397c1388720287105140cb76Geoff Lang
114e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Load the matrices
115e977efc43aab920b397c1388720287105140cb76Geoff Lang        glUniformMatrix4fv(mMVPMatrixLoc, 1, GL_FALSE, mvpMatrix.data);
116e977efc43aab920b397c1388720287105140cb76Geoff Lang    }
117e977efc43aab920b397c1388720287105140cb76Geoff Lang
118e977efc43aab920b397c1388720287105140cb76Geoff Lang    virtual void draw()
119e977efc43aab920b397c1388720287105140cb76Geoff Lang    {
120e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Set the viewport
121e977efc43aab920b397c1388720287105140cb76Geoff Lang        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
122e977efc43aab920b397c1388720287105140cb76Geoff Lang
123e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Clear the color buffer
124e977efc43aab920b397c1388720287105140cb76Geoff Lang        glClear(GL_COLOR_BUFFER_BIT);
125e977efc43aab920b397c1388720287105140cb76Geoff Lang
126e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Use the program object
127e977efc43aab920b397c1388720287105140cb76Geoff Lang        glUseProgram(mProgram);
128e977efc43aab920b397c1388720287105140cb76Geoff Lang
129e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Load the vertex position
130e977efc43aab920b397c1388720287105140cb76Geoff Lang        glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, mCube.positions.data());
131e977efc43aab920b397c1388720287105140cb76Geoff Lang        glEnableVertexAttribArray(mPositionLoc);
132e977efc43aab920b397c1388720287105140cb76Geoff Lang
133e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Load the texcoord data
134e977efc43aab920b397c1388720287105140cb76Geoff Lang        glVertexAttribPointer(mTexcoordLoc, 2, GL_FLOAT, GL_FALSE, 0, mCube.texcoords.data());
135e977efc43aab920b397c1388720287105140cb76Geoff Lang        glEnableVertexAttribArray(mTexcoordLoc);
136e977efc43aab920b397c1388720287105140cb76Geoff Lang
137e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Draw the cube
138e977efc43aab920b397c1388720287105140cb76Geoff Lang        glDrawElements(GL_TRIANGLES, mCube.indices.size(), GL_UNSIGNED_SHORT, mCube.indices.data());
139e977efc43aab920b397c1388720287105140cb76Geoff Lang    }
140e977efc43aab920b397c1388720287105140cb76Geoff Lang
141e977efc43aab920b397c1388720287105140cb76Geoff Lang    virtual void swap()
142e977efc43aab920b397c1388720287105140cb76Geoff Lang    {
143e977efc43aab920b397c1388720287105140cb76Geoff Lang        // Instead of letting the application call eglSwapBuffers, call eglPostSubBufferNV here instead
144e977efc43aab920b397c1388720287105140cb76Geoff Lang        size_t windowWidth = getWindow()->getWidth();
145e977efc43aab920b397c1388720287105140cb76Geoff Lang        size_t windowHeight = getWindow()->getHeight();
146f0955f1585d2f28acb11664f2d9eb3a1aa684577Geoff Lang        EGLDisplay display = getDisplay();
147e977efc43aab920b397c1388720287105140cb76Geoff Lang        EGLSurface surface = getSurface();
148e977efc43aab920b397c1388720287105140cb76Geoff Lang        mPostSubBufferNV(display, surface, 60, 60, windowWidth - 120, windowHeight - 120);
149e977efc43aab920b397c1388720287105140cb76Geoff Lang    }
150e977efc43aab920b397c1388720287105140cb76Geoff Lang
151e977efc43aab920b397c1388720287105140cb76Geoff Lang  private:
152e977efc43aab920b397c1388720287105140cb76Geoff Lang    // Handle to a program object
153e977efc43aab920b397c1388720287105140cb76Geoff Lang    GLuint mProgram;
154e977efc43aab920b397c1388720287105140cb76Geoff Lang
155e977efc43aab920b397c1388720287105140cb76Geoff Lang    // Attribute locations
156e977efc43aab920b397c1388720287105140cb76Geoff Lang    GLint mPositionLoc;
157e977efc43aab920b397c1388720287105140cb76Geoff Lang    GLint mTexcoordLoc;
158e977efc43aab920b397c1388720287105140cb76Geoff Lang
159e977efc43aab920b397c1388720287105140cb76Geoff Lang    // Uniform locations
160e977efc43aab920b397c1388720287105140cb76Geoff Lang    GLuint mMVPMatrixLoc;
161e977efc43aab920b397c1388720287105140cb76Geoff Lang
162e977efc43aab920b397c1388720287105140cb76Geoff Lang    // Current rotation
163e977efc43aab920b397c1388720287105140cb76Geoff Lang    float mRotation;
164e977efc43aab920b397c1388720287105140cb76Geoff Lang
165e977efc43aab920b397c1388720287105140cb76Geoff Lang    // Geometry data
166e977efc43aab920b397c1388720287105140cb76Geoff Lang    CubeGeometry mCube;
167e977efc43aab920b397c1388720287105140cb76Geoff Lang
168e977efc43aab920b397c1388720287105140cb76Geoff Lang    // eglPostSubBufferNV entry point
169e977efc43aab920b397c1388720287105140cb76Geoff Lang    PFNEGLPOSTSUBBUFFERNVPROC mPostSubBufferNV;
170e977efc43aab920b397c1388720287105140cb76Geoff Lang};
171e977efc43aab920b397c1388720287105140cb76Geoff Lang
172e977efc43aab920b397c1388720287105140cb76Geoff Langint main(int argc, char **argv)
173e977efc43aab920b397c1388720287105140cb76Geoff Lang{
174e977efc43aab920b397c1388720287105140cb76Geoff Lang    PostSubBufferSample app;
175e977efc43aab920b397c1388720287105140cb76Geoff Lang    return app.run();
176e977efc43aab920b397c1388720287105140cb76Geoff Lang}
177