static void Init(void) { if (!ShadersSupported()) exit(1); vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText); fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText); program = LinkShaders(vertShader, fragShader); glUseProgram(program); SetUniformValues(program, Uniforms); PrintUniforms(Uniforms); assert(glGetError() == 0); glClearColor(0.4f, 0.4f, 0.8f, 0.0f); printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); assert(glIsProgram(program)); assert(glIsShader(fragShader)); assert(glIsShader(vertShader)); glColor3f(1, 0, 0); }
static void Init(void) { if (!ShadersSupported()) exit(1); vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); program = LinkShaders(vertShader, fragShader); glUseProgram(program); SetUniformValues(program, Uniforms); PrintUniforms(Uniforms); assert(glGetError() == 0); glClearColor(0.4f, 0.4f, 0.8f, 0.0f); glEnable(GL_DEPTH_TEST); glColor3f(1, 0, 0); }
ptr<ShaderSource> GlslGeneratorInstance::Generate() { // first stage: register all nodes RegisterNode(rootNode); // заголовок файла switch(glslVersion) { case GlslVersions::opengl33: text << "#version 330\n"; break; case GlslVersions::webgl: // version numbers in WebGL are not supported text << "#extension GL_OES_standard_derivatives : enable\n" "#extension GL_EXT_draw_buffers : enable\n" "#ifdef GL_ES\n" "precision highp float;\n" "#endif\n"; break; default: THROW("Unknown GLSL version"); } // вывести атрибуты в качестве входных переменных, если это вершинный шейдер if(shaderType == ShaderTypes::vertex) { const char* prefixStr; switch(glslVersion) { case GlslVersions::opengl33: prefixStr = "in "; break; case GlslVersions::webgl: prefixStr = "attribute "; break; default: THROW("Unknown GLSL version"); } std::sort(attributes.begin(), attributes.end()); for(size_t i = 0; i < attributes.size(); ++i) { AttributeNode* node = attributes[i]; text << prefixStr; DataType valueType = node->GetValueType(); // hack for lack of supporting integer attributes in WebGL // change them to float if(glslVersion == GlslVersions::webgl) valueType = EnforceFloatDataType(valueType); PrintDataType(valueType); text << " a" << node->GetElementIndex() << ";\n"; } } // print transformed nodes if(!transformedNodes.empty()) { if(shaderType != ShaderTypes::pixel) THROW("Only pixel shader may have transformed nodes"); const char* prefixStr; switch(glslVersion) { case GlslVersions::opengl33: prefixStr = "in "; break; case GlslVersions::webgl: prefixStr = "varying "; break; default: THROW("Unknown GLSL version"); } for(size_t i = 0; i < transformedNodes.size(); ++i) { TransformedNode* node = transformedNodes[i]; text << prefixStr; PrintDataType(node->GetValueType()); text << " v" << node->GetSemantic() << ";\n"; } } // print interpolate nodes if(!interpolateNodes.empty()) { if(shaderType != ShaderTypes::vertex) THROW("Only vertex shader may have interpolate nodes"); const char* prefixStr; switch(glslVersion) { case GlslVersions::opengl33: prefixStr = "out "; break; case GlslVersions::webgl: prefixStr = "varying "; break; default: THROW("Unknown GLSL version"); } for(size_t i = 0; i < interpolateNodes.size(); ++i) { InterpolateNode* node = interpolateNodes[i]; text << prefixStr; PrintDataType(node->GetValueType()); text << " v" << node->GetSemantic() << ";\n"; } } // вывести пиксельные переменные, если это пиксельный шейдер, и это нужно if(shaderType == ShaderTypes::pixel && glslVersion == GlslVersions::opengl33) { for(int i = 0; i < fragmentTargetsCount; ++i) { text << "out "; PrintDataType(DataTypes::_vec4); text << " r" << i << ";\n"; } } // print uniforms PrintUniforms(); // samplers for(size_t i = 0; i < samplers.size(); ++i) { SamplerNode* samplerNode = samplers[i]; // строка, описывающая основной тип семпла const char* valueTypeStr; switch(samplerNode->GetValueType()) { case DataTypes::_float: case DataTypes::_vec2: case DataTypes::_vec3: case DataTypes::_vec4: valueTypeStr = ""; break; case DataTypes::_uint: case DataTypes::_uvec2: case DataTypes::_uvec3: case DataTypes::_uvec4: valueTypeStr = glslVersion == GlslVersions::webgl ? "i" : "u"; break; case DataTypes::_int: case DataTypes::_ivec2: case DataTypes::_ivec3: case DataTypes::_ivec4: valueTypeStr = "i"; break; default: THROW("Invalid sampler value type"); } // строка, описывающая размерность const char* dimensionStr; switch(samplerNode->GetCoordType()) { case SamplerNode::_1D: dimensionStr = "1D"; break; case SamplerNode::_2D: dimensionStr = "2D"; break; case SamplerNode::_3D: dimensionStr = "3D"; break; case SamplerNode::_Cube: dimensionStr = "Cube"; break; default: THROW("Invalid sampler coord type"); } // вывести семплер int slot = samplerNode->GetSlot(); text << "uniform " << valueTypeStr << "sampler" << dimensionStr << ' ' << samplerPrefix << slot << ";\n"; } //** заголовок функции шейдера text << "void main()\n{\n"; // shader code for(size_t i = 0; i < nodeInits.size(); ++i) PrintNodeInit(i); // завершение шейдера text << "}\n"; // make list of uniform variable bindings GlShaderBindings::UniformBindings uniformBindings; if(!supportUniformBuffers) { uniformBindings.resize(uniforms.size()); for(size_t i = 0; i < uniforms.size(); ++i) { UniformNode* node = uniforms[i].second; GlShaderBindings::UniformBinding& uniformBinding = uniformBindings[i]; uniformBinding.dataType = node->GetValueType(); uniformBinding.count = node->GetCount(); uniformBinding.slot = uniforms[i].first->GetSlot(); uniformBinding.offset = node->GetOffset(); std::ostringstream ss; ss << uniformPrefix << uniformBinding.slot << '_' << uniformBinding.offset; uniformBinding.name = ss.str(); } } // make list of uniform block bindings GlShaderBindings::Bindings uniformBlockBindings; if(supportUniformBuffers) { uniformBlockBindings.resize(uniforms.size()); for(size_t i = 0; i < uniforms.size(); ++i) { int slot = uniforms[i].first->GetSlot(); char name[16]; sprintf(name, "%s%d", uniformBufferPrefix, slot); uniformBlockBindings[i].first = name; uniformBlockBindings[i].second = slot; } // remove duplicates std::sort(uniformBlockBindings.begin(), uniformBlockBindings.end()); uniformBlockBindings.resize(std::unique(uniformBlockBindings.begin(), uniformBlockBindings.end()) - uniformBlockBindings.begin()); } // сформировать список привязок семплеров GlShaderBindings::Bindings samplerBindings(samplers.size()); for(size_t i = 0; i < samplers.size(); ++i) { int slot = samplers[i]->GetSlot(); char name[16]; sprintf(name, "%s%d", samplerPrefix, slot); samplerBindings[i].first = name; samplerBindings[i].second = slot; } // сформировать список привязок атрибутов GlShaderBindings::Bindings attributeBindings(attributes.size()); for(size_t i = 0; i < attributes.size(); ++i) { int index = attributes[i]->GetElementIndex(); char name[16]; sprintf(name, "a%d", index); attributeBindings[i].first = name; attributeBindings[i].second = index; } // make a target variables list GlShaderBindings::Bindings targetBindings; switch(glslVersion) { case GlslVersions::opengl33: targetBindings.resize(fragmentTargetsCount); for(int i = 0; i < fragmentTargetsCount; ++i) { char name[16]; sprintf(name, "r%d", i); targetBindings[i].first = name; targetBindings[i].second = i; } break; case GlslVersions::webgl: // no bindings needed, because of use of gl_FragColor/gl_FragData break; } return NEW(GlslSource( Strings::String2File(text.str()), NEW(GlShaderBindings(uniformBindings, uniformBlockBindings, samplerBindings, attributeBindings, targetBindings, dualFragmentTarget)) )); }
static void init(void) { static const char *fragShaderText = "void main() {\n" " gl_FragColor = gl_Color;\n" "}\n"; static const char *vertShaderText = "void main() {\n" " gl_FrontColor = gl_Color;\n" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" "}\n"; static const char *geoShaderText = "#version 120\n" "#extension GL_ARB_geometry_shader4 : enable\n" "void main()\n" "{\n" " for(int i = 0; i < gl_VerticesIn; ++i)\n" " {\n" " gl_FrontColor = gl_FrontColorIn[i];\n" " gl_Position = gl_PositionIn[i];\n" " EmitVertex();\n" " }\n" "}\n"; if (!ShadersSupported()) exit(1); if (!glutExtensionSupported("GL_ARB_geometry_shader4")) { printf("This demo requires GL_ARB_geometry_shader4\n"); exit(1); } menu_init(); fragShader = glCreateShader(GL_FRAGMENT_SHADER); load_and_compile_shader(fragShader, fragShaderText); vertShader = glCreateShader(GL_VERTEX_SHADER); load_and_compile_shader(vertShader, vertShaderText); geoShader = glCreateShader(GL_GEOMETRY_SHADER_ARB); if (filename) read_shader(geoShader, filename); else load_and_compile_shader(geoShader, geoShaderText); program = glCreateProgram(); glAttachShader(program, vertShader); glAttachShader(program, geoShader); glAttachShader(program, fragShader); glProgramParameteriARB(program, GL_GEOMETRY_INPUT_TYPE_ARB, GL_LINES_ADJACENCY_ARB); glProgramParameteriARB(program, GL_GEOMETRY_OUTPUT_TYPE_ARB, GL_LINE_STRIP); { int temp; glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB,&temp); glProgramParameteriARB(program,GL_GEOMETRY_VERTICES_OUT_ARB,temp); } glLinkProgram(program); check_link(program); glUseProgram(program); SetUniformValues(program, Uniforms); PrintUniforms(Uniforms); assert(glGetError() == 0); glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_COLOR_ARRAY ); glVertexPointer( 3, GL_FLOAT, sizeof(vertices[0]), vertices ); glColorPointer( 4, GL_FLOAT, sizeof(color[0]), color ); }
ptr<ShaderSource> Hlsl11GeneratorInstance::Generate() { // first stage: register all nodes RegisterNode(rootNode); // find out if we need instance id for(size_t i = 0; i < nodeInits.size(); ++i) { Node* node = nodeInits[i]; if(node->GetType() == Node::typeOperation) { OperationNode* operationNode = fast_cast<OperationNode*>(node); if(operationNode->GetOperation() == OperationNode::operationGetInstanceID) needInstanceID = true; } } // выборы в зависимости от типа шейдера const char* mainFunctionName; const char* inputTypeName; const char* inputName; const char* outputTypeName; const char* outputName; const char* profile; switch(shaderType) { case ShaderTypes::vertex: mainFunctionName = "VS"; inputTypeName = "A"; inputName = "a"; outputTypeName = "V"; outputName = "v"; profile = "vs_4_0"; break; case ShaderTypes::pixel: mainFunctionName = "PS"; inputTypeName = "V"; inputName = "v"; outputTypeName = "R"; outputName = "r"; profile = "ps_4_0"; break; default: THROW("Unknown shader type"); } // вывести атрибуты, если вершинный шейдер if(shaderType == ShaderTypes::vertex) { text << "struct A\n{\n"; struct IndexSorter { bool operator()(AttributeNode* a, AttributeNode* b) const { return a->GetElementIndex() < b->GetElementIndex(); } }; std::sort(attributes.begin(), attributes.end(), IndexSorter()); for(size_t i = 0; i < attributes.size(); ++i) { AttributeNode* node = attributes[i]; text << '\t'; PrintDataType(node->GetValueType()); int index = node->GetElementIndex(); text << " a" << index << " : " << Dx11System::GetSemanticString(index) << ";\n"; } text << "};\n"; } // print transformed nodes if(shaderType == ShaderTypes::pixel) { text << "struct V\n{\n"; struct SemanticSorter { bool operator()(TransformedNode* a, TransformedNode* b) const { return a->GetSemantic() < b->GetSemantic(); } }; std::sort(transformedNodes.begin(), transformedNodes.end(), SemanticSorter()); for(size_t i = 0; i < transformedNodes.size(); ++i) { TransformedNode* node = transformedNodes[i]; text << '\t'; PrintDataType(node->GetValueType()); int semantic = node->GetSemantic(); text << " v" << semantic << " : " << Dx11System::GetSemanticString(semantic) << ";\n"; } text << "};\n"; } // print interpolate nodes if(shaderType == ShaderTypes::vertex) { text << "struct V\n{\n"; struct SemanticSorter { bool operator()(InterpolateNode* a, InterpolateNode* b) const { return a->GetSemantic() < b->GetSemantic(); } }; std::sort(interpolateNodes.begin(), interpolateNodes.end(), SemanticSorter()); for(size_t i = 0; i < interpolateNodes.size(); ++i) { InterpolateNode* node = interpolateNodes[i]; text << '\t'; PrintDataType(node->GetValueType()); int semantic = node->GetSemantic(); text << " v" << semantic << " : " << Dx11System::GetSemanticString(semantic) << ";\n"; } // вывести SV_Position text << "\tfloat4 vTP : SV_Position;\n"; text << "};\n"; } // вывести пиксельные переменные, если это пиксельный шейдер if(shaderType == ShaderTypes::pixel) { text << "struct R\n{\n"; for(int i = 0; i < fragmentTargetsCount; ++i) { text << '\t'; PrintDataType(DataTypes::_vec4); text << " r" << i << " : SV_Target" << i << ";\n"; } text << "};\n"; } // вывести uniform-буферы PrintUniforms(); // семплеры struct SamplerSlotSorter { bool operator()(SamplerNode* a, SamplerNode* b) const { return a->GetSlot() < b->GetSlot(); } }; std::sort(samplers.begin(), samplers.end(), SamplerSlotSorter()); for(size_t i = 0; i < samplers.size(); ++i) { SamplerNode* samplerNode = samplers[i]; const char* textureStr; switch(samplerNode->GetCoordType()) { case SamplerNode::_1D: textureStr = "Texture1D"; break; case SamplerNode::_2D: textureStr = "Texture2D"; break; case SamplerNode::_3D: textureStr = "Texture3D"; break; case SamplerNode::_Cube: textureStr = "TextureCube"; break; default: THROW("Invalid sampler coord type"); } // текстура text << textureStr << '<'; PrintDataType(samplerNode->GetValueType()); int slot = samplerNode->GetSlot(); text << "> t" << slot << " : register(t" << slot << ");\n"; // семплер text << "SamplerState s" << slot << " : register(s" << slot << ");\n"; } //** заголовок функции шейдера text << outputTypeName << ' ' << mainFunctionName << '(' << inputTypeName << ' ' << inputName; // если шейдер использует instance ID, добавить аргумент if(needInstanceID) text << ", uint sI : SV_InstanceID"; // завершить заголовок text << ")\n{\n\t" << outputTypeName << ' ' << outputName << ";\n"; // shader code for(size_t i = 0; i < nodeInits.size(); ++i) PrintNodeInit(i); // завершение шейдера text << "\treturn " << outputName << ";\n}\n"; // получить маски ресурсов int uniformBuffersMask = 0; for(size_t i = 0; i < uniforms.size(); ++i) uniformBuffersMask |= 1 << uniforms[i].first->GetSlot(); int samplersMask = 0; for(size_t i = 0; i < samplers.size(); ++i) samplersMask |= 1 << samplers[i]->GetSlot(); Dx11ShaderResources resources(uniformBuffersMask, samplersMask); return NEW(Hlsl11Source(Strings::String2File(text.str()), mainFunctionName, profile, resources)); }