void neb::gfx::environ::two::render(sp::shared_ptr<neb::gfx::context::base> context) { /** * prepare rendering environment and then call the drawable */ //GLUTPP_DEBUG_1_FUNCTION; auto drawable = drawable_.lock(); if(!drawable) return; //auto self = sp::dynamic_pointer_cast<neb::gfx::context::base>(shared_from_this()); auto app = neb::app::base::global(); /** wrong for color maybe! */ //glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); //glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // get program choice from drawable /** @todo replace with 'environ' which determines program and camera types and accepts certian types of drawables */ auto p = app->use_program(neb::program_name::e::TEXT); drawable->draw(context, p); }
/** * \brief Removes the last shader program passed to push_shader. */ void bear::visual::gl_screen::pop_shader() { if ( m_shader.empty() ) { claw::logger << claw::log_warning << "There is no shader to pop." << std::endl; return; } m_shader.pop_back(); typedef std::vector<shader_program>::const_reverse_iterator iterator_type; bool valid_found(false); for ( iterator_type it = m_shader.rbegin(); !valid_found && (it != m_shader.rend()); ++it ) if ( it->is_valid() ) { use_program( *it ); valid_found = true; } if ( !valid_found ) glUseProgram( 0 ); } // gl_screen::pop_shader()
/** * \brief Sets the shader program to apply for the next render commands. * \param p The program to apply. */ void bear::visual::gl_screen::push_shader( const shader_program& p ) { m_shader.push_back( p ); if ( p.is_valid() ) use_program( p ); } // gl_screen::push_shader()
void asdf_multiplat_t::render_debug() { LOG_IF(CheckGLError(), "Error before drawing spritebatch debug information"); auto passthrough = Content.shaders["passthrough"]; passthrough->use_program(); passthrough->world_matrix = glm::mat4(); passthrough->view_matrix = glm::mat4(); passthrough->projection_matrix = spritebatch->spritebatch_shader->projection_matrix; passthrough->update_wvp_uniform(); glUniform4f(passthrough->uniforms["Color"], 0.0f, 0.2f, 1.0f, 1.0f); glDisable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(1.2f); //glBegin(GL_POLYGON); //glColor4f(0.5f, 0.3f, 1.0f, 1.0f); //glVertex2f(-1, 1); //glVertex2f(1, 1); //glVertex2f(1, -1); //glVertex2f(-1, -1); //glEnd(); //glBegin(GL_POLYGON); //glColor4f(0.3f, 0.1f, 0.3f, 1.0f); //glVertex2f(-0.5f, 0.5f); //glVertex2f(0.5f, 0.5f); //glVertex2f(0.5f, -0.5f); //glVertex2f(-0.5f, -0.5f); //glEnd(); main_view->render_debug(); glUseProgram(0); }
static glw_program_t * load_program(glw_root_t *gr, const struct glw_backend_texture *t0, const struct glw_backend_texture *t1, float blur, int flags, glw_program_args_t *gpa, render_state_t *rs, const glw_render_job_t *rj) { glw_program_t *gp; glw_backend_root_t *gbr = &gr->gr_be; if(unlikely(gpa != NULL)) { rs->t0 = NULL; rs->t1 = NULL; if(unlikely(t1 != NULL)) { if(gpa->gpa_load_texture != NULL) { // Program has specialized code to load textures, run it gpa->gpa_load_texture(gr, gpa->gpa_prog, gpa->gpa_aux, t1, 1); } else { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, t1->textures[0]); glActiveTexture(GL_TEXTURE0); } } if(t0 != NULL) { if(gpa->gpa_load_texture != NULL) { // Program has specialized code to load textures, run it gpa->gpa_load_texture(gr, gpa->gpa_prog, gpa->gpa_aux, t0, 0); } else { glBindTexture(GL_TEXTURE_2D, t0->textures[0]); } } use_program(gbr, gpa->gpa_prog); if(gpa->gpa_load_uniforms != NULL) gpa->gpa_load_uniforms(gr, gpa->gpa_prog, gpa->gpa_aux, rj); return gpa->gpa_prog; } if(t0 == NULL) { if(t1 != NULL) { gp = gbr->gbr_renderer_flat_stencil; if(rs->t0 != t1) { glBindTexture(GL_TEXTURE_2D, t1->textures[0]); rs->t0 = t1; } else { rs->texload_skips++; } } else { gp = gbr->gbr_renderer_flat; } } else { const int doblur = blur > 0.05 || flags & GLW_RENDER_BLUR_ATTRIBUTE; if(t1 != NULL) { gp = doblur ? gbr->gbr_renderer_tex_stencil_blur : gbr->gbr_renderer_tex_stencil; if(rs->t1 != t1) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, t1->textures[0]); glActiveTexture(GL_TEXTURE0); rs->t1 = t1; } else { rs->texload_skips++; } } else if(doblur) { gp = gbr->gbr_renderer_tex_blur; } else if(!flags) { gp = gbr->gbr_renderer_tex_simple; } else { gp = gbr->gbr_renderer_tex; } if(rs->t0 != t0) { glBindTexture(GL_TEXTURE_2D, t0->textures[0]); rs->t0 = t0; } else { rs->texload_skips++; } } use_program(gbr, gp); return gp; }
void spritebatch_t::render_batch(shared_ptr<texture_t> const& texture) { size_t numBatchedSprites = 0; sprite_vertex_t spriteVertices[9001]; unsigned short spriteIndices[9001]; //todo: refactor this for (sprite_t const& sprite : sprite_map[texture]) { vec2 up(0.0f, 1.0f); vec2 right(1.0f, 0.0f); up = rotate(up, -sprite.rotation); right = rotate(right, -sprite.rotation); size_t vertNum = numBatchedSprites * 4; float hwidth = sprite.src_rect.width / 2.0f; float hheight = sprite.src_rect.height / 2.0f; float spritehwidth = hwidth * sprite.scale[0]; float spritehheight = hheight * sprite.scale[1]; ///FIXME precision float minX = sprite.src_rect.x / double(texture->get_width()); float minY = sprite.src_rect.y / double(texture->get_height()); float maxX = (sprite.src_rect.x + sprite.src_rect.width) / double(texture->get_width()); float maxY = (sprite.src_rect.y + sprite.src_rect.height) / double(texture->get_height()); /* 0 _________ 1 * | /| * | / | * | / | * | / | * |/________| * 2 3 */ //v0 - top left spriteVertices[vertNum].position = sprite.position + right*(-spritehwidth) + up*(spritehheight); spriteVertices[vertNum].tex_coord = vec2(minX, maxY); spriteVertices[vertNum].color = sprite.color; //v1 - top right spriteVertices[vertNum + 1].position = sprite.position + right*(spritehwidth)+up*(spritehheight); spriteVertices[vertNum + 1].tex_coord = vec2(maxX, maxY); spriteVertices[vertNum + 1].color = sprite.color; //v2 - bottom left spriteVertices[vertNum + 2].position = sprite.position + right*(-spritehwidth) + up*(-spritehheight); spriteVertices[vertNum + 2].tex_coord = vec2(minX, minY); spriteVertices[vertNum + 2].color = sprite.color; //v3- bottom right spriteVertices[vertNum + 3].position = sprite.position + right*(spritehwidth)+up*(-spritehheight); spriteVertices[vertNum + 3].tex_coord = vec2(maxX, minY); spriteVertices[vertNum + 3].color = sprite.color; size_t indexNum = numBatchedSprites * 6; spriteIndices[indexNum + 0] = vertNum + 0; spriteIndices[indexNum + 1] = vertNum + 1; spriteIndices[indexNum + 2] = vertNum + 2; spriteIndices[indexNum + 3] = vertNum + 2; spriteIndices[indexNum + 4] = vertNum + 1; spriteIndices[indexNum + 5] = vertNum + 3; //--- DEBUG --- //todo: refactor if (debugging_sprites) { LOG_IF(CheckGLError(), "Error before drawing spritebatch debug information"); auto passthrough = Content.shaders["passthrough"]; passthrough->use_program(); passthrough->world_matrix = spritebatch_shader->world_matrix; passthrough->view_matrix = spritebatch_shader->view_matrix; passthrough->projection_matrix = spritebatch_shader->projection_matrix; passthrough->update_wvp_uniform(); glUniform4f(passthrough->uniforms["Color"], 1.0f, 0.0f, 0.0f, 1.0f); glDisable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(6.0f); glBegin(GL_POLYGON); glTexCoord2f(0.01f, 0.99f); glVertex2f(spriteVertices[vertNum + 0].position.x, spriteVertices[vertNum + 2].position.y); //BOTTOM LEFT glTexCoord2f(0.01f, 0.01f); glVertex2f(spriteVertices[vertNum + 1].position.x, spriteVertices[vertNum + 1].position.y); //TOP LEFT glTexCoord2f(0.99f, 0.01f); glVertex2f(spriteVertices[vertNum + 2].position.x, spriteVertices[vertNum + 0].position.y); //TOP RIGHT glTexCoord2f(0.99f, 0.99f); glVertex2f(spriteVertices[vertNum + 3].position.x, spriteVertices[vertNum + 3].position.y); //BOTTOM RIGHT glEnd(); spritebatch_shader->use_program(); LOG_IF(CheckGLError(), "Error drawing spritebatch debug information"); } //--- numBatchedSprites++; } //bind/push the index data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, numBatchedSprites * 6 * sizeof(short), reinterpret_cast<void*>(spriteIndices), GL_STREAM_DRAW); //bind the vbo and push the vertex data glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, numBatchedSprites * 4 * sizeof(sprite_vertex_t), reinterpret_cast<void*>(spriteVertices), GL_STREAM_DRAW); //enable position, texCoord, color glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); //set up vertex attrib size / types. stride is just the total size of the vertex GLsizei stride = sizeof(sprite_vertex_t); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, 0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<void*>(sizeof(glm::vec2)) ); //MUST STILL PROVIDE OFFSET glVertexAttribPointer(2, 4, GL_FLOAT, GL_TRUE, stride, reinterpret_cast<void*>(sizeof(glm::vec2) * 2) ); LOG_IF(CheckGLError(), "Error after setting up spritebatch vertex attributes"); //set openGL state glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture->get_textureID()); //bind the texture. Sampler is set in End() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_CULL_FACE); glDrawElements(GL_TRIANGLES, numBatchedSprites * 6, GL_UNSIGNED_SHORT, 0); if (debugging_sprites) { Content.shaders["passthrough"]->use_program(); glUniform4f(Content.shaders["passthrough"]->uniforms["Color"], 0.0f, 0.0f, 1.0f, 1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(2.0f); glDrawElements(GL_TRIANGLES, numBatchedSprites * 6, GL_UNSIGNED_SHORT, 0); } //reset opengl state //glEnable(GL_CULL_FACE); glBindTexture(GL_TEXTURE_2D, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); LOG_IF(CheckGLError(), "Error after drawing spritebatch polygons"); ASSERT(!CheckGLError(), ""); }
static auto use(program_name prg) noexcept { return use_program(prg); }
void ready_for_rendering() { use_program(program); }