void FramebufferCompositorImpl::render_lightmap(SceneContext& /*sc*/, SceneGraph* /*sg*/) { OpenGLState state; state.bind_texture(m_lightmap->get_texture()); state.enable(GL_BLEND); state.set_blend_func(GL_DST_COLOR, GL_ZERO); // multiply the lightmap with the screen state.activate(); glBegin(GL_QUADS); { glTexCoord2i(0, 1); glVertex2i(0, 0); glTexCoord2i(1, 1); glVertex2i(m_viewport.width, 0); glTexCoord2i(1, 0); glVertex2i(m_viewport.width, m_viewport.height); glTexCoord2i(0, 0); glVertex2i(0, m_viewport.height); } glEnd(); }
void draw_particles() { glPushMatrix(); glMultMatrixf(get_modelview().matrix); OpenGLState state; state.bind_texture(surface->get_texture()); state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); state.enable(GL_BLEND); state.activate(); glBegin(GL_QUADS); for(ParticleSystem::Particles::iterator i = psys.begin(); i != psys.end(); ++i) { if (i->t != -1.0f) { float p = 1.0f - psys.get_progress(i->t); Color color(psys.get_color_start().r * p + psys.get_color_stop().r * (1.0f - p), psys.get_color_start().g * p + psys.get_color_stop().g * (1.0f - p), psys.get_color_start().b * p + psys.get_color_stop().b * (1.0f - p), psys.get_color_start().a * p + psys.get_color_stop().a * (1.0f - p)); // scale float scale = psys.get_size_start() + psys.get_progress(i->t) * (psys.get_size_stop() - psys.get_size_start()); float width = surface->get_width() * scale; float height = surface->get_height() * scale; // rotate float x_rot = width/2; float y_rot = height/2; if (i->angle != 0) { float s = sinf(math::pi * i->angle/180.0f); float c = cosf(math::pi * i->angle/180.0f); x_rot = (width/2) * c - (height/2) * s; y_rot = (width/2) * s + (height/2) * c; } glColor4f(color.r, color.g, color.b, color.a); glTexCoord2f(0, 0); glVertex2f(i->x - x_rot, i->y - y_rot); glTexCoord2f(1, 0); glVertex2f(i->x + y_rot, i->y - x_rot); glTexCoord2f(1, 1); glVertex2f(i->x + x_rot, i->y + y_rot); glTexCoord2f(0, 1); glVertex2f(i->x - y_rot, i->y + x_rot); } } glEnd(); glPopMatrix(); }
void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { PAddr texture_addr = config.config.GetPhysicalAddress(); const auto cached_texture = texture_cache.find(texture_addr); if (cached_texture != texture_cache.end()) { state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle; state.Apply(); } else { std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>(); new_texture->texture.Create(); state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.Apply(); // TODO: Need to choose filters that correspond to PICA once register is declared glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(config.config.wrap_s)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(config.config.wrap_t)); const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); new_texture->width = info.width; new_texture->height = info.height; new_texture->size = info.width * info.height * Pica::Regs::NibblesPerPixel(info.format); u8* texture_src_data = Memory::GetPhysicalPointer(texture_addr); std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { temp_texture_buffer_rgba[x + info.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, info.height - 1 - y, info); } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_texture_buffer_rgba.get()); texture_cache.emplace(texture_addr, std::move(new_texture)); } }
void prepare(TexturePtr screen_texture) { OpenGLState state; state.bind_texture(screen_texture); state.activate(); glBegin(GL_QUADS); glTexCoord2f(0,600); glVertex2f(0,0); glTexCoord2f(800,600); glVertex2f(800,0); glTexCoord2f(800, 0); glVertex2f(800, 600); glTexCoord2f(0, 0); glVertex2f(0,600); glEnd(); }
void render(unsigned int mask) { #if 0 Display::push_framebuffer(framebuffer); glClear(GL_COLOR_BUFFER_BIT); draw_particles(); Display::pop_framebuffer(); if (1) { OpenGLState state; glUseProgram(shader_program.get_handle()); shader_program.set_uniform1i("screen", 0); shader_program.set_uniform1i("particles", 1); state.bind_texture(tmp_texture, 0); state.bind_texture(framebuffer.get_texture(), 1); state.color(Color(1.0f, 1.0f, 1.0f, 1.0f)); state.activate(); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(0,0); glTexCoord2f(800,0); glVertex2f(800,0); glTexCoord2f(800,600); glVertex2f(800, 600); glTexCoord2f(0, 600); glVertex2f(0,600); glEnd(); glUseProgram(0); } #endif }
void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::DebugUtils::TextureInfo& info) { const auto cached_texture = texture_cache.find(info.physical_address); if (cached_texture != texture_cache.end()) { state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle; state.Apply(); } else { MICROPROFILE_SCOPE(OpenGL_TextureUpload); std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>(); new_texture->texture.Create(); state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.Apply(); glActiveTexture(GL_TEXTURE0 + texture_unit); u8* texture_src_data = Memory::GetPhysicalPointer(info.physical_address); new_texture->width = info.width; new_texture->height = info.height; new_texture->size = info.stride * info.height; new_texture->addr = info.physical_address; new_texture->hash = Common::ComputeHash64(texture_src_data, new_texture->size); std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { temp_texture_buffer_rgba[x + info.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, info.height - 1 - y, info); } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_texture_buffer_rgba.get()); texture_cache.emplace(info.physical_address, std::move(new_texture)); } }
void BasicCompositorImpl::render(SceneContext& sc, SceneGraph* sg, const GraphicContextState& gc_state) { // Resize Lightmap, only needed in the editor, FIXME: move this into a 'set_size()' call if (m_lightmap->get_width() != m_window.width /LIGHTMAP_DIV || m_lightmap->get_height() != m_window.height/LIGHTMAP_DIV) { m_lightmap = Surface::create(m_window.width / LIGHTMAP_DIV, m_window.height / LIGHTMAP_DIV); } if (sc.get_render_mask() & SceneContext::LIGHTMAPSCREEN) { // Render the lightmap to the framebuffers->lightmap glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glScalef(1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV, 1.0f); sc.light().render(); glPopMatrix(); if (sg) { glPushMatrix(); glScalef(1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV, 1.0f); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::LIGHTMAP); glPopMatrix(); } { // Copy lightmap to a texture OpenGLState state; state.bind_texture(m_lightmap->get_texture()); state.activate(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, // mipmap level 0, 0, // xoffset, yoffset 0, // x m_window.height - static_cast<GLsizei>(m_lightmap->get_height()), // y (OpenGL is upside down) static_cast<GLsizei>(m_lightmap->get_width()), static_cast<GLsizei>(m_lightmap->get_height())); } } if (sc.get_render_mask() & SceneContext::COLORMAP) { // Render the colormap to the framebuffers->screen glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); sc.color().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::COLORMAP); glPopMatrix(); } } if (sc.get_render_mask() & SceneContext::LIGHTMAP) { // Renders the lightmap to the screen OpenGLState state; state.bind_texture(m_lightmap->get_texture()); state.enable(GL_BLEND); state.set_blend_func(GL_DST_COLOR, GL_ZERO); state.activate(); glBegin(GL_QUADS); glTexCoord2f(m_lightmap->get_uv().left, m_lightmap->get_uv().bottom); glVertex2i(0, 0); glTexCoord2f(m_lightmap->get_uv().right, m_lightmap->get_uv().bottom); glVertex2i(m_viewport.width, 0); glTexCoord2f(m_lightmap->get_uv().right, m_lightmap->get_uv().top); glVertex2i(m_viewport.width, m_viewport.height); glTexCoord2f(m_lightmap->get_uv().left, m_lightmap->get_uv().top); glVertex2i(0, m_viewport.height); glEnd(); } if (sc.get_render_mask() & SceneContext::HIGHLIGHTMAP) { sc.highlight().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::HIGHLIGHTMAP); glPopMatrix(); } } if (sc.get_render_mask() & SceneContext::CONTROLMAP) { sc.control().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::CONTROLMAP); glPopMatrix(); } } // Clear all DrawingContexts sc.color().clear(); sc.light().clear(); sc.highlight().clear(); sc.control().clear(); }
void FramebufferCompositorImpl::render(SceneContext& sc, SceneGraph* sg, const GraphicContextState& gc_state) { if (sc.get_render_mask() & SceneContext::LIGHTMAPSCREEN) { // Render the lightmap to framebuffers->lightmap Display::push_framebuffer(m_lightmap); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0f, static_cast<float>(m_viewport.height - (m_viewport.height / LIGHTMAP_DIV)), 0.0f); glScalef(1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV); sc.light().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::LIGHTMAP); glPopMatrix(); } glPopMatrix(); Display::pop_framebuffer(); } { // Render the main screen Display::push_framebuffer(m_screen); if (sc.get_render_mask() & SceneContext::COLORMAP) { // Render the colormap to framebuffers->screen glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); sc.color().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::COLORMAP); glPopMatrix(); } } if (sc.get_render_mask() & SceneContext::LIGHTMAP) { // Renders the lightmap to the screen render_lightmap(sc, sg); } if (sc.get_render_mask() & SceneContext::HIGHLIGHTMAP) { sc.highlight().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::HIGHLIGHTMAP); glPopMatrix(); } } if (sc.get_render_mask() & SceneContext::CONTROLMAP) { sc.control().render(); if (sg) { glPushMatrix(); glMultMatrixf(gc_state.get_matrix().matrix); sg->render(SceneContext::CONTROLMAP); glPopMatrix(); } } Display::pop_framebuffer(); } if (1) { // Render the screen framebuffer to the actual screen OpenGLState state; state.bind_texture(m_screen->get_texture(), 0); state.activate(); glBegin(GL_QUADS); { glTexCoord2i(0, 1); glVertex2i(0, 0); glTexCoord2i(1, 1); glVertex2i(m_viewport.width, 0); glTexCoord2i(1, 0); glVertex2i(m_viewport.width, m_viewport.height); glTexCoord2i(0, 0); glVertex2i(0.0f, m_viewport.height); } glEnd(); } // Clear all DrawingContexts sc.color().clear(); sc.light().clear(); sc.highlight().clear(); sc.control().clear(); }
void VertexArrayDrawingRequest::draw(int start, int end) { assert(!vertices.empty()); assert(texcoords.empty() || int(texcoords.size()/2) == num_vertices()); assert(colors.empty() || int(colors.size()/4) == num_vertices()); OpenGLState state; glClear(GL_DEPTH_BUFFER_BIT); state.disable(GL_DEPTH_TEST); state.enable(GL_BLEND); state.set_blend_func(blend_sfactor, blend_dfactor); if (texture) { state.bind_texture(texture); } if (!colors.empty()) { state.enable_client_state(GL_COLOR_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, 0, &*colors.begin()); } else { state.disable_client_state(GL_COLOR_ARRAY); state.color(Color(1.0f, 1.0f, 1.0f)); } if (!texcoords.empty()) { state.enable_client_state(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, &*texcoords.begin()); } else { state.disable_client_state(GL_TEXTURE_COORD_ARRAY); } // FIXME: Might be worth to not use VertexArrays when we have a pretty small number of vertices state.disable_client_state(GL_NORMAL_ARRAY); state.enable_client_state(GL_VERTEX_ARRAY); glVertexPointer (3, GL_FLOAT, 0, &*vertices.begin()); state.activate(); glPushMatrix(); glMultMatrixf(modelview.matrix); glDrawArrays(mode, start, end); glPopMatrix(); }
/* * Render all states in the ShaderCache along with their renderables. This * is where the actual OpenGL rendering starts. */ void OpenGLRenderSystem::render(RenderStateFlags globalstate, const Matrix4& modelview, const Matrix4& projection, const Vector3& viewer) { glPushAttrib(GL_ALL_ATTRIB_BITS); // Set the projection and modelview matrices glMatrixMode(GL_PROJECTION); glLoadMatrixd(projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixd(modelview); // global settings that are not set in renderstates glFrontFace(GL_CW); glCullFace(GL_BACK); glPolygonOffset(-1, 1); // Set polygon stipple pattern from constant glPolygonStipple(POLYGON_STIPPLE_PATTERN); glEnableClientState(GL_VERTEX_ARRAY); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); if (GLEW_VERSION_1_3) { glActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0); } if (GLEW_ARB_shader_objects) { glUseProgramObjectARB(0); glDisableVertexAttribArrayARB(c_attr_TexCoord0); glDisableVertexAttribArrayARB(c_attr_Tangent); glDisableVertexAttribArrayARB(c_attr_Binormal); } if (globalstate & RENDER_TEXTURE_2D) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } // Construct default OpenGL state OpenGLState current; // Set up initial GL state. This MUST MATCH the defaults in the OpenGLState // object, otherwise required state changes may not occur. glLineStipple(current.m_linestipple_factor, current.m_linestipple_pattern); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisable(GL_BLEND); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glShadeModel(GL_FLAT); glDisable(GL_DEPTH_TEST); // RENDER_DEPTHWRITE defaults to 0 glDepthMask(GL_FALSE); // RENDER_MASKCOLOUR defaults to 0 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDisable(GL_ALPHA_TEST); glDisable(GL_LINE_STIPPLE); glDisable(GL_POLYGON_STIPPLE); glDisable(GL_POLYGON_OFFSET_LINE); glDisable(GL_POLYGON_OFFSET_FILL); // greebo: otherwise tiny gap lines between brushes are visible glBindTexture(GL_TEXTURE_2D, 0); glColor4f(1,1,1,1); glDepthFunc(current.getDepthFunc()); glAlphaFunc(GL_ALWAYS, 0); glLineWidth(1); glPointSize(1); glHint(GL_FOG_HINT, GL_NICEST); glDisable(GL_FOG); #if 0 std::size_t count = 0 ; for (OpenGLStates::iterator i = _state_sorted.begin(); i != _state_sorted.end(); ++i) { // Render the OpenGLShaderPass if (!i->second->empty()) { count++; } } rMessage() << "R1 " << count << " of " << _state_sorted.size() << "\n"; std::size_t curObject = 0; #endif // Iterate over the sorted mapping between OpenGLStates and their // OpenGLShaderPasses (containing the renderable geometry), and render the // contents of each bucket. Each pass is passed a reference to the "current" // state, which it can change. for (OpenGLStates::iterator i = _state_sorted.begin(); i != _state_sorted.end(); ++i) { // Render the OpenGLShaderPass if (!i->second->empty()) { #if 0 rMessage() << curObject << " " << (*i->second); curObject++; #endif i->second->render(current, globalstate, viewer, _time); } } glPopAttrib(); }