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 Simple_VertexShader.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#include "geometry_utils.h"
20#include "Vector.h"
21#include "Matrix.h"
22
23class SimpleVertexShaderSample : public SampleApplication
24{
25  public:
26    SimpleVertexShaderSample::SimpleVertexShaderSample()
27        : SampleApplication("SimpleVertexShader", 1280, 720)
28    {
29    }
30
31    virtual bool initialize()
32    {
33        const std::string vs = SHADER_SOURCE
34        (
35            uniform mat4 u_mvpMatrix;
36            attribute vec4 a_position;
37            attribute vec2 a_texcoord;
38            varying vec2 v_texcoord;
39            void main()
40            {
41                gl_Position = u_mvpMatrix * a_position;
42                v_texcoord = a_texcoord;
43            }
44        );
45
46        const std::string fs = SHADER_SOURCE
47        (
48            precision mediump float;
49            varying vec2 v_texcoord;
50            void main()
51            {
52                gl_FragColor = vec4(v_texcoord.x, v_texcoord.y, 1.0, 1.0);
53            }
54        );
55
56        mProgram = CompileProgram(vs, fs);
57        if (!mProgram)
58        {
59            return false;
60        }
61
62        // Get the attribute locations
63        mPositionLoc = glGetAttribLocation(mProgram, "a_position");
64        mTexcoordLoc = glGetAttribLocation(mProgram, "a_texcoord");
65
66        // Get the uniform locations
67        mMVPMatrixLoc = glGetUniformLocation(mProgram, "u_mvpMatrix");
68
69        // Generate the geometry data
70        GenerateCubeGeometry(0.5f, &mCube);
71
72        // Set an initial rotation
73        mRotation = 45.0f;
74
75        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
76        glCullFace(GL_BACK);
77        glEnable(GL_CULL_FACE);
78
79        return true;
80    }
81
82    virtual void destroy()
83    {
84        glDeleteProgram(mProgram);
85    }
86
87    virtual void step(float dt, double totalTime)
88    {
89        mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);
90
91        Matrix4 perspectiveMatrix = Matrix4::perspective(60.0f, float(getWindow()->getWidth()) / getWindow()->getHeight(),
92                                                         1.0f, 20.0f);
93
94        Matrix4 modelMatrix = Matrix4::translate(Vector3(0.0f, 0.0f, -2.0f)) *
95                              Matrix4::rotate(mRotation, Vector3(1.0f, 0.0f, 1.0f));
96
97        Matrix4 viewMatrix = Matrix4::identity();
98
99        Matrix4 mvpMatrix = perspectiveMatrix * viewMatrix * modelMatrix;
100
101        // Load the matrices
102        glUniformMatrix4fv(mMVPMatrixLoc, 1, GL_FALSE, mvpMatrix.data);
103    }
104
105    virtual void draw()
106    {
107        // Set the viewport
108        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
109
110        // Clear the color buffer
111        glClear(GL_COLOR_BUFFER_BIT);
112
113        // Use the program object
114        glUseProgram(mProgram);
115
116        // Load the vertex position
117        glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, mCube.positions.data());
118        glEnableVertexAttribArray(mPositionLoc);
119
120        // Load the texcoord data
121        glVertexAttribPointer(mTexcoordLoc, 2, GL_FLOAT, GL_FALSE, 0, mCube.texcoords.data());
122        glEnableVertexAttribArray(mTexcoordLoc);
123
124        // Draw the cube
125        glDrawElements(GL_TRIANGLES, mCube.indices.size(), GL_UNSIGNED_SHORT, mCube.indices.data());
126    }
127
128  private:
129    // Handle to a program object
130    GLuint mProgram;
131
132    // Attribute locations
133    GLint mPositionLoc;
134    GLint mTexcoordLoc;
135
136    // Uniform locations
137    GLuint mMVPMatrixLoc;
138
139    // Current rotation
140    float mRotation;
141
142    // Geometry data
143    CubeGeometry mCube;
144};
145
146int main(int argc, char **argv)
147{
148    SimpleVertexShaderSample app;
149    return app.run();
150}
151