1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <GLES3/gl3.h>
19 
20 #include <string>
21 
22 class Model;
23 class Renderer;
24 
25 /*!
26  * A class representing a simple shader program. It consists of vertex and fragment components. The
27  * input attributes are a position (as a Vector3) and a uv (as a Vector2). It also takes a uniform
28  * to be used as the entire model/view/projection matrix. The shader expects a single texture for
29  * fragment shading, and does no other lighting calculations (thus no uniforms for lights or normal
30  * attributes).
31  */
32 class Shader {
33 public:
34     friend Renderer;
35     /*!
36      * Loads a shader given the full sourcecode and names for necessary attributes and uniforms to
37      * link to. Returns a valid shader on success or null on failure. Shader resources are
38      * automatically cleaned up on destruction.
39      *
40      * @param vertexSource The full source code for your vertex program
41      * @param fragmentSource The full source code of your fragment program
42      * @param positionAttributeName The name of the position attribute in your vertex program
43      * @param uvAttributeName The name of the uv coordinate attribute in your vertex program
44      * @param projectionMatrixUniformName The name of your model/view/projection matrix uniform
45      * @return a valid Shader on success, otherwise null.
46      */
47     static Shader *loadShader(const std::string &vertexSource, const std::string &fragmentSource,
48                               const std::string &positionAttributeName,
49                               const std::string &uvAttributeName,
50                               const std::string &projectionMatrixUniformName);
51 
~Shader()52     inline ~Shader() {
53         if (program_) {
54             glDeleteProgram(program_);
55             program_ = 0;
56         }
57     }
58 
59     /*!
60      * Prepares the shader for use, call this before executing any draw commands
61      */
62     void activate() const;
63 
64     /*!
65      * Cleans up the shader after use, call this after executing any draw commands
66      */
67     void deactivate() const;
68 
69     /*!
70      * Renders a single model
71      * @param model a model to render
72      */
73     void drawModel(const Model &model) const;
74 
75     /*!
76      * Sets the model/view/projection matrix in the shader.
77      * @param projectionMatrix sixteen floats, column major, defining an OpenGL projection matrix.
78      */
79     void setProjectionMatrix(float *projectionMatrix) const;
80 
81 private:
82     /*!
83      * Helper function to load a shader of a given type
84      * @param shaderType The OpenGL shader type. Should either be GL_VERTEX_SHADER or
85      * GL_FRAGMENT_SHADER
86      * @param shaderSource The full source of the shader
87      * @return the id of the shader, as returned by glCreateShader, or 0 in the case of an error
88      */
89     static GLuint loadShader(GLenum shaderType, const std::string &shaderSource);
90 
91     /*!
92      * Constructs a new instance of a shader. Use @a loadShader
93      * @param program the GL program id of the shader
94      * @param position the attribute location of the position
95      * @param uv the attribute location of the uv coordinates
96      * @param projectionMatrix the uniform location of the projection matrix
97      */
Shader(GLuint program,GLint position,GLint uv,GLint projectionMatrix)98     constexpr Shader(GLuint program, GLint position, GLint uv, GLint projectionMatrix)
99           : program_(program), position_(position), uv_(uv), projectionMatrix_(projectionMatrix) {}
100 
101     GLuint program_;
102     GLint position_;
103     GLint uv_;
104     GLint projectionMatrix_;
105 };
106