15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//            Based on Simple_VertexShader.c from
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Book:      OpenGL(R) ES 2.0 Programming Guide
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ISBN-10:   0321502795
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ISBN-13:   9780321502797
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Publisher: Addison-Wesley Professional
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLs:      http://safari.informit.com/9780321563835
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//            http://www.opengles-book.com
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "SampleApplication.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "shader_utils.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "texture_utils.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "geometry_utils.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Vector.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Matrix.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SimpleVertexShaderSample : public SampleApplication
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  public:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleVertexShaderSample::SimpleVertexShaderSample()
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : SampleApplication("SimpleVertexShader", 1280, 720)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool initialize()
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const std::string vs = SHADER_SOURCE
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            uniform mat4 u_mvpMatrix;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            attribute vec4 a_position;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            attribute vec2 a_texcoord;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            varying vec2 v_texcoord;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            void main()
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gl_Position = u_mvpMatrix * a_position;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                v_texcoord = a_texcoord;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::string fs = SHADER_SOURCE
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            precision mediump float;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            varying vec2 v_texcoord;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            void main()
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gl_FragColor = vec4(v_texcoord.x, v_texcoord.y, 1.0, 1.0);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mProgram = CompileProgram(vs, fs);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!mProgram)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return false;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Get the attribute locations
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mPositionLoc = glGetAttribLocation(mProgram, "a_position");
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mTexcoordLoc = glGetAttribLocation(mProgram, "a_texcoord");
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Get the uniform locations
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mMVPMatrixLoc = glGetUniformLocation(mProgram, "u_mvpMatrix");
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Generate the geometry data
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GenerateCubeGeometry(0.5f, &mCube);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Set an initial rotation
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mRotation = 45.0f;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glCullFace(GL_BACK);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glEnable(GL_CULL_FACE);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void destroy()
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glDeleteProgram(mProgram);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void step(float dt, double totalTime)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Matrix4 perspectiveMatrix = Matrix4::perspective(60.0f, float(getWindow()->getWidth()) / getWindow()->getHeight(),
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         1.0f, 20.0f);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Matrix4 modelMatrix = Matrix4::translate(Vector3(0.0f, 0.0f, -2.0f)) *
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              Matrix4::rotate(mRotation, Vector3(1.0f, 0.0f, 1.0f));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Matrix4 viewMatrix = Matrix4::identity();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Matrix4 mvpMatrix = perspectiveMatrix * viewMatrix * modelMatrix;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Load the matrices
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glUniformMatrix4fv(mMVPMatrixLoc, 1, GL_FALSE, mvpMatrix.data);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void draw()
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Set the viewport
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Clear the color buffer
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glClear(GL_COLOR_BUFFER_BIT);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Use the program object
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glUseProgram(mProgram);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Load the vertex position
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, mCube.positions.data());
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glEnableVertexAttribArray(mPositionLoc);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Load the texcoord data
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glVertexAttribPointer(mTexcoordLoc, 2, GL_FLOAT, GL_FALSE, 0, mCube.texcoords.data());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glEnableVertexAttribArray(mTexcoordLoc);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Draw the cube
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glDrawElements(GL_TRIANGLES, mCube.indices.size(), GL_UNSIGNED_SHORT, mCube.indices.data());
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Handle to a program object
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint mProgram;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Attribute locations
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint mPositionLoc;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint mTexcoordLoc;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Uniform locations
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint mMVPMatrixLoc;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Current rotation
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float mRotation;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Geometry data
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CubeGeometry mCube;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleVertexShaderSample app;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return app.run();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)