void drawGround() { if (groundQuads == 0) return; ShaderBase *shader; if (!nullOrDisposed(bitmaps[BM_A1])) { /* Animated tileset */ TilemapVXShader &tmShader = shState->shaders().tilemapVX; tmShader.bind(); tmShader.setAniOffset(aniOffset); shader = &tmShader; } else { /* Static tileset */ shader = &shState->shaders().simple; shader->bind(); } shader->setTexSize(Vec2i(atlas.width, atlas.height)); shader->applyViewportProj(); shader->setTranslation(dispPos); TEX::bind(atlas.tex); GLMeta::vaoBind(vao); gl.DrawElements(GL_TRIANGLES, groundQuads*6, _GL_INDEX_TYPE, 0); GLMeta::vaoUnbind(vao); }
void setTranslation(Position replicaPos, ShaderBase &shader) { Vec2i repOff = getReplicaOffset(replicaPos); repOff += dispPos; shader.setTranslation(repOff); }
//// //// //// //// //// //// //// //// Compile functions //// //// //// //// //// //// //// //// bool Shader::compile(ShaderBase& shader, const char** code, int l) { if(!supported()) return 0; int glType[4] = { 0, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER }; // Preprocessor stuff int version = 0; char** temp = new char*[l]; const char** parts = new const char*[l+1]; for(int i=0; i<l; ++i) { temp[i] = 0; if(preprocess(code[i], shader.m_type, version, temp[i])) { parts[i+1] = temp[i]; } else parts[i+1] = code[i]; } // Automatic code char header[1024]; parts[0] = header; if(version>0) sprintf(header, "#version %d\n", version); else header[0] = 0; // Add extra defines here switch(shader.m_type) { // Deprecated shader type defines case 1: strcat(header, "#define VERTEX_SHADER\n"); break; case 2: strcat(header, "#define FRAGMENT_SHADER\n"); break; case 3: strcat(header, "#define GEOMETRY_SHADER\n"); break; } // Create and compile shader unsigned int s = glCreateShader( glType[shader.m_type] ); glShaderSource(s, l+1, parts, NULL); glCompileShader(s); //Success? shader.m_shader = s; shader.m_compiled = queryShader(s, GL_COMPILE_STATUS); if(!shader.m_compiled) { printf("Shader failed to compile\n"); char buf[10000]; printf("-----------\n%s\n-----------\n", shader.log(buf,10000)); } GL_CHECK_ERROR; // clean up for(int i=0; i<l; ++i) if(temp[i]) delete [] temp[i]; delete [] parts; delete [] temp; return shader.m_compiled; }
void GLRenderer::renderMaterialShader(RenderState& rstate, RenderData* render_data, Material *curr_material) { if (Material::ShaderType::BEING_GENERATED == curr_material->shader_type()) { return; } //Skip the material whose texture is not ready with some exceptions if (!checkTextureReady(curr_material)) return; ShaderManager* shader_manager = rstate.shader_manager; Transform* const t = render_data->owner_object()->transform(); if (t == nullptr) return; rstate.uniforms.u_model = t->getModelMatrix(); rstate.uniforms.u_mv = rstate.uniforms.u_view * rstate.uniforms.u_model; rstate.uniforms.u_mv_it = glm::inverseTranspose(rstate.uniforms.u_mv); rstate.uniforms.u_mvp = rstate.uniforms.u_proj * rstate.uniforms.u_mv; rstate.uniforms.u_right = rstate.render_mask & RenderData::RenderMaskBit::Right; if(use_multiview && !rstate.shadow_map){ rstate.uniforms.u_view_[0] = rstate.scene->main_camera_rig()->left_camera()->getViewMatrix(); rstate.uniforms.u_view_[1] = rstate.scene->main_camera_rig()->right_camera()->getViewMatrix(); rstate.uniforms.u_mv_[0] = rstate.uniforms.u_view_[0] * rstate.uniforms.u_model; rstate.uniforms.u_mv_[1] = rstate.uniforms.u_view_[1] * rstate.uniforms.u_model; rstate.uniforms.u_mv_it_[0] = glm::inverseTranspose(rstate.uniforms.u_mv_[0]); rstate.uniforms.u_mv_it_[1] = glm::inverseTranspose(rstate.uniforms.u_mv_[1]); rstate.uniforms.u_mvp_[0] = rstate.uniforms.u_proj * rstate.uniforms.u_mv_[0]; rstate.uniforms.u_mvp_[1] = rstate.uniforms.u_proj * rstate.uniforms.u_mv_[1]; } Mesh* mesh = render_data->mesh(); GLuint programId = -1; ShaderBase* shader = NULL; try { //TODO: Improve this logic to avoid a big "switch case" if (rstate.material_override != nullptr) curr_material = rstate.material_override; switch (curr_material->shader_type()) { case Material::ShaderType::UNLIT_HORIZONTAL_STEREO_SHADER: shader = shader_manager->getUnlitHorizontalStereoShader(); break; case Material::ShaderType::UNLIT_VERTICAL_STEREO_SHADER: shader = shader_manager->getUnlitVerticalStereoShader(); break; case Material::ShaderType::OES_SHADER: shader = shader_manager->getOESShader(); break; case Material::ShaderType::OES_HORIZONTAL_STEREO_SHADER: shader = shader_manager->getOESHorizontalStereoShader(); break; case Material::ShaderType::OES_VERTICAL_STEREO_SHADER: shader = shader_manager->getOESVerticalStereoShader(); break; case Material::ShaderType::CUBEMAP_SHADER: shader = shader_manager->getCubemapShader(); break; case Material::ShaderType::CUBEMAP_REFLECTION_SHADER: if(use_multiview){ rstate.uniforms.u_view_inv_[0] = glm::inverse(rstate.uniforms.u_view_[0]); rstate.uniforms.u_view_inv_[1] = glm::inverse(rstate.uniforms.u_view_[1]); } else rstate.uniforms.u_view_inv = glm::inverse(rstate.uniforms.u_view); shader = shader_manager->getCubemapReflectionShader(); break; case Material::ShaderType::TEXTURE_SHADER: shader = shader_manager->getTextureShader(); break; case Material::ShaderType::EXTERNAL_RENDERER_SHADER: shader = shader_manager->getExternalRendererShader(); break; case Material::ShaderType::ASSIMP_SHADER: shader = shader_manager->getAssimpShader(); break; case Material::ShaderType::LIGHTMAP_SHADER: shader = shader_manager->getLightMapShader(); break; case Material::ShaderType::UNLIT_FBO_SHADER: shader = shader_manager->getUnlitFboShader(); break; default: shader = shader_manager->getCustomShader(curr_material->shader_type()); break; } if (shader == NULL) { LOGE("Rendering error: GVRRenderData shader cannot be determined\n"); shader_manager->getErrorShader()->render(&rstate, render_data, curr_material); return; } if ((render_data->draw_mode() == GL_LINE_STRIP) || (render_data->draw_mode() == GL_LINES) || (render_data->draw_mode() == GL_LINE_LOOP)) { if (curr_material->hasUniform("line_width")) { float lineWidth = curr_material->getFloat("line_width"); glLineWidth(lineWidth); } else { glLineWidth(1.0f); } } shader->render(&rstate, render_data, curr_material); } catch (const std::string &error) { LOGE( "Error detected in Renderer::renderRenderData; name : %s, error : %s", render_data->owner_object()->name().c_str(), error.c_str()); shader_manager->getErrorShader()->render(&rstate, render_data, curr_material); } programId = shader->getProgramId(); //there is no program associated with EXTERNAL_RENDERER_SHADER if (-1 != programId) { glBindVertexArray(mesh->getVAOId(programId)); if (mesh->indices().size() > 0) { glDrawElements(render_data->draw_mode(), mesh->indices().size(), GL_UNSIGNED_SHORT, 0); } else { glDrawArrays(render_data->draw_mode(), 0, mesh->vertices().size()); } glBindVertexArray(0); } checkGlError("renderMesh::renderMaterialShader"); }
void pushSetViewport(ShaderBase &shader) const { glState.viewport.pushSet(IntRect(0, 0, gl.width, gl.height)); shader.applyViewportProj(); }
void bindTexture(ShaderBase &shader) { TEX::bind(gl.tex); shader.setTexSize(Vec2i(gl.width, gl.height)); }
void bindAtlas(ShaderBase &shader) { TEX::bind(atlas.gl.tex); shader.setTexSize(atlas.size); }
void redrawBaseTex() { if (nullOrDisposed(windowskin)) return; if (base.tex.tex == TEX::ID(0)) return; FBO::bind(base.tex.fbo); /* Clear texture */ glState.clearColor.pushSet(Vec4()); FBO::clear(); glState.clearColor.pop(); glState.viewport.pushSet(IntRect(0, 0, base.tex.width, base.tex.height)); glState.blend.pushSet(false); ShaderBase *shader; if (backOpacity < 255 || tone->hasEffect()) { PlaneShader &planeShader = shState->shaders().plane; planeShader.bind(); planeShader.setColor(Vec4()); planeShader.setFlash(Vec4()); planeShader.setTone(tone->norm); planeShader.setOpacity(backOpacity.norm); shader = &planeShader; } else { shader = &shState->shaders().simple; shader->bind(); } windowskin->bindTex(*shader); TEX::setSmooth(true); shader->setTranslation(Vec2i()); shader->applyViewportProj(); /* Draw stretched layer */ base.vert.draw(0, 1); glState.blend.set(true); glState.blendMode.pushSet(BlendKeepDestAlpha); /* Draw tiled layer */ base.vert.draw(1, base.bgTileQuads); glState.blendMode.set(BlendNormal); /* If we used plane shader before, switch to simple */ if (shader != &shState->shaders().simple) { shader = &shState->shaders().simple; shader->bind(); shader->setTranslation(Vec2i()); shader->applyViewportProj(); windowskin->bindTex(*shader); } base.vert.draw(1+base.bgTileQuads, base.borderQuads); TEX::setSmooth(false); glState.blendMode.pop(); glState.blend.pop(); glState.viewport.pop(); }