void DynamicLighting::buildShaders() { Info("Building shaders / uniforms"); // set up the basic uniforms etc mLightSampler.reset(new Sampler()); mLightSamplerUniform.reset( new Uniform(Uniform::Uniform_sampler2D, "lightSampler")); mProgram->addUniform(mLightSamplerUniform); const int shaderTextMax = 10240; char shaderText[shaderTextMax]; //\TODO: consider eliminating the call to getActiveLightCount if possible snprintf(shaderText, shaderTextMax, lightingFragmentShaderText, getActiveLightCount()); std::shared_ptr<Shader> fragShader(new Shader(Shader::Fragment)); fragShader->setText(shaderText); fragShader->compile(); // build the vertex shader snprintf(shaderText, shaderTextMax, lightingVertexShaderText); std::shared_ptr<Shader> vertexShader(new Shader(Shader::Vertex)); vertexShader->setText(shaderText); vertexShader->compile(); // add the shaders to the program mProgram->addShader(vertexShader); mProgram->addShader(fragShader); }
SGLShaderProgram::SGLShaderProgram(std::string iVertPath, std::string iFragPath) : vertPath(iVertPath.c_str()), fragPath(iFragPath.c_str()) { programID = glCreateProgram(); SGLShader vertShader(iVertPath, GL_VERTEX_SHADER); SGLShader fragShader(iFragPath, GL_FRAGMENT_SHADER); this->attachShader(vertShader.shaderID); this->attachShader(fragShader.shaderID); this->linkProgram(); this->validateProgram(); }
void LightSources::loadShader() { // Standardshader QOpenGLShaderProgram* standardShaderProg = new QOpenGLShaderProgram(); QOpenGLShader vertShader(QOpenGLShader::Vertex); vertShader.compileSourceFile(":/shader/lightsource.vert"); standardShaderProg->addShader(&vertShader); QOpenGLShader fragShader(QOpenGLShader::Fragment); fragShader.compileSourceFile(":/shader/lightsource.frag"); standardShaderProg->addShader(&fragShader); standardShaderProg->link(); // Sonnenshader this->shaderProgram = standardShaderProg; glEnable(GL_TEXTURE_2D); }
QGLShaderProgram *MGLES2Renderer::compileShaderProgram(const QString &frag, const QString &vert) { const QString fragFilename = (frag.isEmpty()) ? defaultFragmentShader() : frag; QGLShader fragShader(QGLShader::Fragment, d_ptr->m_glContext); if (!fragShader.compileSourceFile(fragFilename)) { mWarning("MGLES2Renderer") << "failed to compile fragment shader" << fragFilename << '\n' << fragShader.log(); return 0; } const QString vertFilename = (vert.isEmpty()) ? defaultVertexShader() : vert; QGLShader vertShader(QGLShader::Vertex, d_ptr->m_glContext); if (!vertShader.compileSourceFile(vertFilename)) { mWarning("MGLES2Renderer") << "failed to compile vertex shader" << vertFilename << '\n' << vertShader.log(); return 0; } QGLShaderProgram *const program = new QGLShaderProgram(d_ptr->m_glContext); if (program->addShader(&fragShader) && program->addShader(&vertShader)) { // bind needed attribute arrays to specific indices -- TODO: What's this for exactly? program->bindAttributeLocation("vertex", M_ATTR_VERTEX); program->bindAttributeLocation("texCoord", M_ATTR_TCOORD); program->bindAttributeLocation("color", M_ATTR_VCOLOR); // TODO: default context implicit here, but not above? if (program->link() && program->bind()) { // Setup default texturing uniforms here so we dont need setup them in runtime const QByteArray prefix("texture"); GLint maxTexUnits = 0; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexUnits); for (int i = 0; i < maxTexUnits; ++i) { const int loc = program->uniformLocation(prefix + QByteArray::number(i)); if (loc >= 0) program->setUniformValue(loc, GLuint(i)); } } return program; } mWarning("MGLES2Renderer") << "failed to link shader program" << (fragFilename + ':' + vertFilename); delete program; return 0; }
bool ParticleScene::Init() { glClearColor(0.25f, 0.25f, 0.25f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //_camera = new Camera(glm::pi<float>() * 0.25f, 1280.0f / 720.0f, 0.1f, 1000.0f); _camera = new FlyCamera(); _camera->LookAt(glm::vec3(10.0f), glm::vec3(0.0f)); // Setup our particle emitter _emitter = new ParticleEmitter(); _emitter->Init(1000, 500, 0.5f, 2.0f, 1.0f, 5.0f, 1.0f, 0.1f, glm::vec4(1, 0, 0, 1), glm::vec4(1, 1, 0, 0.1f)); // Set up our shaders _program = new GL::Program(); GL::Shader vertShader(GL::ShaderType::VERTEX_SHADER, "./shaders/vertParticle.glsl"); GL::Shader fragShader(GL::ShaderType::FRAGMENT_SHADER, "./shaders/fragParticle.glsl"); _program->AddShader(vertShader); _program->AddShader(fragShader); _program->Link(); // Setup our particle textures Image fire1("textures/fire1.png"); Image fire2("textures/fire2.png"); Image fire3("textures/fire3.png"); // Upload the textures _texFire1 = fire1.Upload(); _texFire2 = fire2.Upload(); _texFire3 = fire3.Upload(); return true; }
// The address returned here will only be valid until next time this function is called. // The program is return bound. QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineShaderProg &prog) { for (int i = 0; i < cachedPrograms.size(); ++i) { QGLEngineShaderProg *cachedProg = cachedPrograms[i]; if (*cachedProg == prog) { // Move the program to the top of the list as a poor-man's cache algo cachedPrograms.move(i, 0); cachedProg->program->bind(); return cachedProg; } } QScopedPointer<QGLEngineShaderProg> newProg; do { QByteArray fragSource; // Insert the custom stage before the srcPixel shader to work around an ATI driver bug // where you cannot forward declare a function that takes a sampler as argument. if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) fragSource.append(prog.customStageSource); fragSource.append(qShaderSnippets[prog.mainFragShader]); fragSource.append(qShaderSnippets[prog.srcPixelFragShader]); if (prog.compositionFragShader) fragSource.append(qShaderSnippets[prog.compositionFragShader]); if (prog.maskFragShader) fragSource.append(qShaderSnippets[prog.maskFragShader]); QByteArray vertexSource; vertexSource.append(qShaderSnippets[prog.mainVertexShader]); vertexSource.append(qShaderSnippets[prog.positionVertexShader]); QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram); CachedShader shaderCache(fragSource, vertexSource); bool inCache = shaderCache.load(shaderProgram.data(), QGLContext::currentContext()); if (!inCache) { QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment)); QByteArray description; #if defined(QT_DEBUG) // Name the shader for easier debugging description.append("Fragment shader: main="); description.append(snippetNameStr(prog.mainFragShader)); description.append(", srcPixel="); description.append(snippetNameStr(prog.srcPixelFragShader)); if (prog.compositionFragShader) { description.append(", composition="); description.append(snippetNameStr(prog.compositionFragShader)); } if (prog.maskFragShader) { description.append(", mask="); description.append(snippetNameStr(prog.maskFragShader)); } fragShader->setObjectName(QString::fromLatin1(description)); #endif if (!fragShader->compileSourceCode(fragSource)) { qWarning() << "Warning:" << description << "failed to compile!"; break; } QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex)); #if defined(QT_DEBUG) // Name the shader for easier debugging description.clear(); description.append("Vertex shader: main="); description.append(snippetNameStr(prog.mainVertexShader)); description.append(", position="); description.append(snippetNameStr(prog.positionVertexShader)); vertexShader->setObjectName(QString::fromLatin1(description)); #endif if (!vertexShader->compileSourceCode(vertexSource)) { qWarning() << "Warning:" << description << "failed to compile!"; break; } shaders.append(vertexShader.data()); shaders.append(fragShader.data()); shaderProgram->addShader(vertexShader.take()); shaderProgram->addShader(fragShader.take()); // We have to bind the vertex attribute names before the program is linked: shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); if (prog.useTextureCoords) shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); if (prog.useOpacityAttribute) shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); if (prog.usePmvMatrixAttribute) { shaderProgram->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); shaderProgram->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); shaderProgram->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); } } newProg.reset(new QGLEngineShaderProg(prog)); newProg->program = shaderProgram.take(); newProg->program->link(); if (newProg->program->isLinked()) { if (!inCache) shaderCache.store(newProg->program, QGLContext::currentContext()); } else { QLatin1String none("none"); QLatin1String br("\n"); QString error; error = QLatin1String("Shader program failed to link,"); #if defined(QT_DEBUG) error += QLatin1String("\n Shaders Used:\n"); for (int i = 0; i < newProg->program->shaders().count(); ++i) { QGLShader *shader = newProg->program->shaders().at(i); error += QLatin1String(" ") + shader->objectName() + QLatin1String(": \n") + QLatin1String(shader->sourceCode()) + br; } #endif error += QLatin1String(" Error Log:\n") + QLatin1String(" ") + newProg->program->log(); qWarning() << error; break; } newProg->program->bind(); if (newProg->maskFragShader != QGLEngineSharedShaders::NoMaskFragmentShader) { GLuint location = newProg->program->uniformLocation("maskTexture"); newProg->program->setUniformValue(location, QT_MASK_TEXTURE_UNIT); } if (cachedPrograms.count() > 30) { // The cache is full, so delete the last 5 programs in the list. // These programs will be least used, as a program us bumped to // the top of the list when it's used. for (int i = 0; i < 5; ++i) { delete cachedPrograms.last(); cachedPrograms.removeLast(); } } cachedPrograms.insert(0, newProg.data()); } while (false); return newProg.take(); }
void InitOpenGL(HWND hWnd) { HDC hdc = GetDC(hWnd); try { // ピクセルフォーマットの設定 PIXELFORMATDESCRIPTOR pdf = { sizeof(PIXELFORMATDESCRIPTOR), 1, // version PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; int format = ChoosePixelFormat(hdc, &pdf); if (format == 0) throw ""; if (!SetPixelFormat(hdc, format, &pdf)) throw ""; // レンダリングコンテキスト作成 m_glrc = wglCreateContext(hdc); } catch (...) { ReleaseDC(hWnd, hdc); return; } wglMakeCurrent(hdc, m_glrc); GLenum err = glewInit(); if (err != GLEW_OK) { cerr << "failed to init GLEW!!:" << glewGetErrorString(err) << endl; return; } // init shader GLShaderUtils vertShader(GL_VERTEX_SHADER); GLShaderUtils fragShader(GL_FRAGMENT_SHADER); if (!vertShader.ReadShaderSource("shaders/simple.vert")) { cerr << "failed to read shaders/simple.vert" << endl; } if (!vertShader.CompileShader()) vertShader.PrintShaderInfoLog(); if (!fragShader.ReadShaderSource("shaders/simple.frag")) { cerr << "failed to read shaders/simple.frag" << endl; } if (!fragShader.CompileShader()) fragShader.PrintShaderInfoLog(); m_shader.Init(vertShader, fragShader); InitBuffer(); if (!m_shader.LinkProgram()) m_shader.PrintProgramInfoLog(); wglMakeCurrent(hdc, 0); ReleaseDC(hWnd, hdc); SendMessage(hWnd, WM_PAINT, NULL, NULL); }
bool SP3Scene::Init() { // Set our timer _time = 0.0f; glClearColor(0.25f, 0.25f, 0.25f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //_camera = new Camera(glm::pi<float>() * 0.25f, 1280.0f / 720.0f, 0.1f, 1000.0f); _camera = new FlyCamera(); _camera->LookAt(glm::vec3(50, 50, 50), glm::vec3(0.0f)); // Vertex information struct Vertex { glm::vec4 position; glm::vec4 colour; }; // Our vertex list Vertex* vertices = new Vertex[ROWS * COLS]; for (unsigned int r = 0; r < ROWS; r++) { for (unsigned int c = 0; c < COLS; c++) { vertices[r * COLS + c].position = glm::vec4((float)c, 0, (float)r, 1); glm::vec3 colour = glm::vec3(sinf((c / (float)(COLS - 1)) * (r / (float)(ROWS - 1)))); vertices[r * COLS + c].colour = glm::vec4(colour, 1); } } // Indices for the triangles GLuint* indices = new GLuint[(ROWS - 1) * (COLS - 1) * 6]; unsigned int index = 0; for (unsigned int r = 0; r < (ROWS - 1); r++) { for (unsigned int c = 0; c < (COLS - 1); c++) { // Triangle 1 indices[index++] = r * COLS + c; indices[index++] = (r + 1) * COLS + c; indices[index++] = (r + 1) * COLS + (c + 1); // Triangle 2 indices[index++] = r * COLS + c; indices[index++] = (r + 1) * COLS + (c + 1); indices[index++] = r * COLS + (c + 1); } } // Generate our vertex buffer and index buffer glGenBuffers(1, &_vbo); glGenBuffers(1, &_ibo); // Generate our vertex array glGenVertexArrays(1, &_vao); // Bind our vertex array glBindVertexArray(_vao); // VERTICES // Tell GL that our _vbo is an array buffer(vertex buffer) and bind it to the vertex array glBindBuffer(GL_ARRAY_BUFFER, _vbo); // Tell GL how big our selected array buffer(_vbo) is, where it is in memory(vertices) and how to handle it glBufferData(GL_ARRAY_BUFFER, (ROWS * COLS) * sizeof(Vertex), vertices, GL_STATIC_DRAW); // Tell GL the structure of our array buffer(_vbo) glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)sizeof(Vertex::position)); // INDICES // Tell GL that our _ibo is an element array buffer(index buffer) and bind it to the vertex array glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); // Tell GL how big our selected element array buffer(_ibo) is, where it is in memory(indices) and how to handle it glBufferData(GL_ELEMENT_ARRAY_BUFFER, (ROWS - 1) * (COLS - 1) * 6 * sizeof(GLuint), indices, GL_STATIC_DRAW); // Unbind our vertex array so that no further attempts to change a vertex array wont affect _vao glBindVertexArray(0); // Unbind our array buffer(vertex buffer) glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind our element array buffer(index buffer) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Cleanup our vertices and indicies delete[] vertices; delete[] indices; // Set up our shaders _program = new GL::Program(); GL::Shader vertShader(GL::ShaderType::VERTEX_SHADER, "./shaders/vertSP3.glsl"); GL::Shader fragShader(GL::ShaderType::FRAGMENT_SHADER, "./shaders/fragSP3.glsl"); _program->AddShader(vertShader); _program->AddShader(fragShader); _program->Link(); return true; }