/* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include class Model; class Renderer; /*! * A class representing a simple shader program. It consists of vertex and fragment components. The * input attributes are a position (as a Vector3) and a uv (as a Vector2). It also takes a uniform * to be used as the entire model/view/projection matrix. The shader expects a single texture for * fragment shading, and does no other lighting calculations (thus no uniforms for lights or normal * attributes). */ class Shader { public: friend Renderer; /*! * Loads a shader given the full sourcecode and names for necessary attributes and uniforms to * link to. Returns a valid shader on success or null on failure. Shader resources are * automatically cleaned up on destruction. * * @param vertexSource The full source code for your vertex program * @param fragmentSource The full source code of your fragment program * @param positionAttributeName The name of the position attribute in your vertex program * @param uvAttributeName The name of the uv coordinate attribute in your vertex program * @param projectionMatrixUniformName The name of your model/view/projection matrix uniform * @return a valid Shader on success, otherwise null. */ static Shader *loadShader(const std::string &vertexSource, const std::string &fragmentSource, const std::string &positionAttributeName, const std::string &uvAttributeName, const std::string &projectionMatrixUniformName); inline ~Shader() { if (program_) { glDeleteProgram(program_); program_ = 0; } } /*! * Prepares the shader for use, call this before executing any draw commands */ void activate() const; /*! * Cleans up the shader after use, call this after executing any draw commands */ void deactivate() const; /*! * Renders a single model * @param model a model to render */ void drawModel(const Model &model) const; /*! * Sets the model/view/projection matrix in the shader. * @param projectionMatrix sixteen floats, column major, defining an OpenGL projection matrix. */ void setProjectionMatrix(float *projectionMatrix) const; private: /*! * Helper function to load a shader of a given type * @param shaderType The OpenGL shader type. Should either be GL_VERTEX_SHADER or * GL_FRAGMENT_SHADER * @param shaderSource The full source of the shader * @return the id of the shader, as returned by glCreateShader, or 0 in the case of an error */ static GLuint loadShader(GLenum shaderType, const std::string &shaderSource); /*! * Constructs a new instance of a shader. Use @a loadShader * @param program the GL program id of the shader * @param position the attribute location of the position * @param uv the attribute location of the uv coordinates * @param projectionMatrix the uniform location of the projection matrix */ constexpr Shader(GLuint program, GLint position, GLint uv, GLint projectionMatrix) : program_(program), position_(position), uv_(uv), projectionMatrix_(projectionMatrix) {} GLuint program_; GLint position_; GLint uv_; GLint projectionMatrix_; };