| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES Utilities |
| * ------------------------------------------------ |
| * |
| * Copyright 2014 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. |
| * |
| *//*! |
| * \file |
| * \brief SGLR shader program. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "sglrShaderProgram.hpp" |
| |
| namespace sglr |
| { |
| namespace pdec |
| { |
| |
| ShaderProgramDeclaration::ShaderProgramDeclaration (void) |
| : m_geometryDecl (rr::GEOMETRYSHADERINPUTTYPE_LAST, rr::GEOMETRYSHADEROUTPUTTYPE_LAST, 0, 0) |
| , m_vertexShaderSet (false) |
| , m_fragmentShaderSet (false) |
| , m_geometryShaderSet (false) |
| { |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexAttribute& v) |
| { |
| m_vertexAttributes.push_back(v); |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexToFragmentVarying& v) |
| { |
| m_vertexToFragmentVaryings.push_back(v); |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexToGeometryVarying& v) |
| { |
| m_vertexToGeometryVaryings.push_back(v); |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometryToFragmentVarying& v) |
| { |
| m_geometryToFragmentVaryings.push_back(v); |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const FragmentOutput& v) |
| { |
| m_fragmentOutputs.push_back(v); |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const Uniform& v) |
| { |
| m_uniforms.push_back(v); |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexSource& c) |
| { |
| DE_ASSERT(!m_vertexShaderSet); |
| m_vertexSource = c.source; |
| m_vertexShaderSet = true; |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const FragmentSource& c) |
| { |
| DE_ASSERT(!m_fragmentShaderSet); |
| m_fragmentSource = c.source; |
| m_fragmentShaderSet = true; |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometrySource& c) |
| { |
| DE_ASSERT(!m_geometryShaderSet); |
| m_geometrySource = c.source; |
| m_geometryShaderSet = true; |
| return *this; |
| } |
| |
| ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometryShaderDeclaration& c) |
| { |
| m_geometryDecl = c; |
| return *this; |
| } |
| |
| bool ShaderProgramDeclaration::valid (void) const |
| { |
| if (!m_vertexShaderSet || !m_fragmentShaderSet) |
| return false; |
| |
| if (m_fragmentOutputs.empty()) |
| return false; |
| |
| if (hasGeometryShader()) |
| { |
| if (m_geometryDecl.inputType == rr::GEOMETRYSHADERINPUTTYPE_LAST || |
| m_geometryDecl.outputType == rr::GEOMETRYSHADEROUTPUTTYPE_LAST) |
| return false; |
| } |
| else |
| { |
| if (m_geometryDecl.inputType != rr::GEOMETRYSHADERINPUTTYPE_LAST || |
| m_geometryDecl.outputType != rr::GEOMETRYSHADEROUTPUTTYPE_LAST || |
| m_geometryDecl.numOutputVertices != 0 || |
| m_geometryDecl.numInvocations != 0) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| } //pdec |
| |
| ShaderProgram::ShaderProgram (const pdec::ShaderProgramDeclaration& decl) |
| : rr::VertexShader (decl.getVertexInputCount(), decl.getVertexOutputCount()) |
| , rr::GeometryShader (decl.getGeometryInputCount(), |
| decl.getGeometryOutputCount(), |
| decl.m_geometryDecl.inputType, |
| decl.m_geometryDecl.outputType, |
| decl.m_geometryDecl.numOutputVertices, |
| decl.m_geometryDecl.numInvocations) |
| , rr::FragmentShader (decl.getFragmentInputCount(), decl.getFragmentOutputCount()) |
| , m_attributeNames (decl.getVertexInputCount()) |
| , m_uniforms (decl.m_uniforms.size()) |
| , m_vertSrc (decl.m_vertexSource) |
| , m_fragSrc (decl.m_fragmentSource) |
| , m_geomSrc (decl.hasGeometryShader() ? (decl.m_geometrySource) : ("")) |
| , m_hasGeometryShader (decl.hasGeometryShader()) |
| { |
| DE_ASSERT(decl.valid()); |
| |
| // Set up shader IO |
| |
| for (size_t ndx = 0; ndx < decl.m_vertexAttributes.size(); ++ndx) |
| { |
| this->rr::VertexShader::m_inputs[ndx].type = decl.m_vertexAttributes[ndx].type; |
| m_attributeNames[ndx] = decl.m_vertexAttributes[ndx].name; |
| } |
| |
| if (m_hasGeometryShader) |
| { |
| for (size_t ndx = 0; ndx < decl.m_vertexToGeometryVaryings.size(); ++ndx) |
| { |
| this->rr::VertexShader::m_outputs[ndx].type = decl.m_vertexToGeometryVaryings[ndx].type; |
| this->rr::VertexShader::m_outputs[ndx].flatshade = decl.m_vertexToGeometryVaryings[ndx].flatshade; |
| |
| this->rr::GeometryShader::m_inputs[ndx] = this->rr::VertexShader::m_outputs[ndx]; |
| } |
| for (size_t ndx = 0; ndx < decl.m_geometryToFragmentVaryings.size(); ++ndx) |
| { |
| this->rr::GeometryShader::m_outputs[ndx].type = decl.m_geometryToFragmentVaryings[ndx].type; |
| this->rr::GeometryShader::m_outputs[ndx].flatshade = decl.m_geometryToFragmentVaryings[ndx].flatshade; |
| |
| this->rr::FragmentShader::m_inputs[ndx] = this->rr::GeometryShader::m_outputs[ndx]; |
| } |
| } |
| else |
| { |
| for (size_t ndx = 0; ndx < decl.m_vertexToFragmentVaryings.size(); ++ndx) |
| { |
| this->rr::VertexShader::m_outputs[ndx].type = decl.m_vertexToFragmentVaryings[ndx].type; |
| this->rr::VertexShader::m_outputs[ndx].flatshade = decl.m_vertexToFragmentVaryings[ndx].flatshade; |
| |
| this->rr::FragmentShader::m_inputs[ndx] = this->rr::VertexShader::m_outputs[ndx]; |
| } |
| } |
| |
| for (size_t ndx = 0; ndx < decl.m_fragmentOutputs.size(); ++ndx) |
| this->rr::FragmentShader::m_outputs[ndx].type = decl.m_fragmentOutputs[ndx].type; |
| |
| // Set up uniforms |
| |
| for (size_t ndx = 0; ndx < decl.m_uniforms.size(); ++ndx) |
| { |
| this->m_uniforms[ndx].name = decl.m_uniforms[ndx].name; |
| this->m_uniforms[ndx].type = decl.m_uniforms[ndx].type; |
| } |
| } |
| |
| ShaderProgram::~ShaderProgram (void) |
| { |
| } |
| |
| const UniformSlot& ShaderProgram::getUniformByName (const char* name) const |
| { |
| DE_ASSERT(name); |
| |
| for (size_t ndx = 0; ndx < m_uniforms.size(); ++ndx) |
| if (m_uniforms[ndx].name == std::string(name)) |
| return m_uniforms[ndx]; |
| |
| DE_FATAL("Invalid uniform name, uniform not found."); |
| return m_uniforms[0]; |
| } |
| |
| void ShaderProgram::shadePrimitives (rr::GeometryEmitter& output, int verticesIn, const rr::PrimitivePacket* packets, const int numPackets, int invocationID) const |
| { |
| DE_UNREF(output); |
| DE_UNREF(verticesIn && packets && numPackets && invocationID); |
| |
| // Should never be called. |
| DE_ASSERT(DE_FALSE); |
| } |
| |
| } // sglr |