void GLGSRender::begin() { rsx::thread::begin(); init_buffers(); std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now(); bool color_mask_b = rsx::method_registers.color_mask_b(); bool color_mask_g = rsx::method_registers.color_mask_g(); bool color_mask_r = rsx::method_registers.color_mask_r(); bool color_mask_a = rsx::method_registers.color_mask_a(); __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); __glcheck glDepthMask(rsx::method_registers.depth_write_enabled()); __glcheck glStencilMask(rsx::method_registers.stencil_mask()); if (__glcheck enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST)) { __glcheck glDepthFunc(comparison_op(rsx::method_registers.depth_func())); __glcheck glDepthMask(rsx::method_registers.depth_write_enabled()); } if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT))) { __glcheck glDepthBoundsEXT(rsx::method_registers.depth_bounds_min(), rsx::method_registers.depth_bounds_max()); } __glcheck glDepthRange(rsx::method_registers.clip_min(), rsx::method_registers.clip_max()); __glcheck enable(rsx::method_registers.dither_enabled(), GL_DITHER); if (__glcheck enable(rsx::method_registers.blend_enabled(), GL_BLEND)) { __glcheck glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()), blend_factor(rsx::method_registers.blend_func_dfactor_rgb()), blend_factor(rsx::method_registers.blend_func_sfactor_a()), blend_factor(rsx::method_registers.blend_func_dfactor_a())); if (rsx::method_registers.surface_color() == rsx::surface_color_format::w16z16y16x16) //TODO: check another color formats { u16 blend_color_r = rsx::method_registers.blend_color_16b_r(); u16 blend_color_g = rsx::method_registers.blend_color_16b_g(); u16 blend_color_b = rsx::method_registers.blend_color_16b_b(); u16 blend_color_a = rsx::method_registers.blend_color_16b_a(); __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); } else { u8 blend_color_r = rsx::method_registers.blend_color_8b_r(); u8 blend_color_g = rsx::method_registers.blend_color_8b_g(); u8 blend_color_b = rsx::method_registers.blend_color_8b_b(); u8 blend_color_a = rsx::method_registers.blend_color_8b_a(); __glcheck glBlendColor(blend_color_r / 255.f, blend_color_g / 255.f, blend_color_b / 255.f, blend_color_a / 255.f); } __glcheck glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()), blend_equation(rsx::method_registers.blend_equation_a())); } if (__glcheck enable(rsx::method_registers.stencil_test_enabled(), GL_STENCIL_TEST)) { __glcheck glStencilFunc(comparison_op(rsx::method_registers.stencil_func()), rsx::method_registers.stencil_func_ref(), rsx::method_registers.stencil_func_mask()); __glcheck glStencilOp(stencil_op(rsx::method_registers.stencil_op_fail()), stencil_op(rsx::method_registers.stencil_op_zfail()), stencil_op(rsx::method_registers.stencil_op_zpass())); if (rsx::method_registers.two_sided_stencil_test_enabled()) { __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers.back_stencil_mask()); __glcheck glStencilFuncSeparate(GL_BACK, comparison_op(rsx::method_registers.back_stencil_func()), rsx::method_registers.back_stencil_func_ref(), rsx::method_registers.back_stencil_func_mask()); __glcheck glStencilOpSeparate(GL_BACK, stencil_op(rsx::method_registers.back_stencil_op_fail()), stencil_op(rsx::method_registers.back_stencil_op_zfail()), stencil_op(rsx::method_registers.back_stencil_op_zpass())); } } __glcheck enable(rsx::method_registers.blend_enabled_surface_1(), GL_BLEND, 1); __glcheck enable(rsx::method_registers.blend_enabled_surface_2(), GL_BLEND, 2); __glcheck enable(rsx::method_registers.blend_enabled_surface_3(), GL_BLEND, 3); if (__glcheck enable(rsx::method_registers.logic_op_enabled(), GL_COLOR_LOGIC_OP)) { __glcheck glLogicOp(logic_op(rsx::method_registers.logic_operation())); } __glcheck glLineWidth(rsx::method_registers.line_width()); __glcheck enable(rsx::method_registers.line_smooth_enabled(), GL_LINE_SMOOTH); //TODO //NV4097_SET_ANISO_SPREAD __glcheck enable(rsx::method_registers.poly_offset_point_enabled(), GL_POLYGON_OFFSET_POINT); __glcheck enable(rsx::method_registers.poly_offset_line_enabled(), GL_POLYGON_OFFSET_LINE); __glcheck enable(rsx::method_registers.poly_offset_fill_enabled(), GL_POLYGON_OFFSET_FILL); __glcheck glPolygonOffset(rsx::method_registers.poly_offset_scale(), rsx::method_registers.poly_offset_bias()); //NV4097_SET_SPECULAR_ENABLE //NV4097_SET_TWO_SIDE_LIGHT_EN //NV4097_SET_FLAT_SHADE_OP //NV4097_SET_EDGE_FLAG auto set_clip_plane_control = [&](int index, rsx::user_clip_plane_op control) { int value = 0; int location; if (m_program->uniforms.has_location("uc_m" + std::to_string(index), &location)) { switch (control) { default: LOG_ERROR(RSX, "bad clip plane control (0x%x)", (u8)control); case rsx::user_clip_plane_op::disable: value = 0; break; case rsx::user_clip_plane_op::greater_or_equal: value = 1; break; case rsx::user_clip_plane_op::less_than: value = -1; break; } __glcheck m_program->uniforms[location] = value; } __glcheck enable(value, GL_CLIP_DISTANCE0 + index); }; load_program(); set_clip_plane_control(0, rsx::method_registers.clip_plane_0_enabled()); set_clip_plane_control(1, rsx::method_registers.clip_plane_1_enabled()); set_clip_plane_control(2, rsx::method_registers.clip_plane_2_enabled()); set_clip_plane_control(3, rsx::method_registers.clip_plane_3_enabled()); set_clip_plane_control(4, rsx::method_registers.clip_plane_4_enabled()); set_clip_plane_control(5, rsx::method_registers.clip_plane_5_enabled()); if (__glcheck enable(rsx::method_registers.cull_face_enabled(), GL_CULL_FACE)) { __glcheck glCullFace(cull_face(rsx::method_registers.cull_face_mode())); } __glcheck glFrontFace(front_face(rsx::method_registers.front_face_mode())); __glcheck enable(rsx::method_registers.poly_smooth_enabled(), GL_POLYGON_SMOOTH); //NV4097_SET_COLOR_KEY_COLOR //NV4097_SET_SHADER_CONTROL //NV4097_SET_ZMIN_MAX_CONTROL //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count(); m_draw_calls++; }
/* Set up display */ void display(void) { glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //glColor4f(0.48627451, 0.223529412, 0.815686275, 1.0); glMatrixMode(GL_MODELVIEW); // Draw Glass glFrontFace(GL_CCW); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glass(1); glTranslatef(0,0.4,0); glCullFace(GL_FRONT); donut(1); glCullFace(GL_BACK); glTranslatef(0,-0.4,0); // Draw Table glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); table(); // Draw Reflections glClear(GL_DEPTH_BUFFER_BIT); glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glScalef(1, 1, -1); glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glCullFace(GL_FRONT); glass(1); glTranslatef(0,.4,0); glCullFace(GL_BACK); donut(1); glCullFace(GL_FRONT); glTranslatef(0,-.4,0); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glCullFace(GL_BACK); // Alpha Blend Table glClear(GL_DEPTH_BUFFER_BIT); glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glEnable(GL_BLEND); glBlendColor(1,1,1,0.4); glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); table(); glDisable(GL_BLEND); // Draw Shadow glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glEnable(GL_BLEND); glColor4f(0,0,0, 0.7); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glMatrixMode(GL_MODELVIEW); glPushMatrix(); shadowTransform(light0_position, tablePlane); glMultMatrixf((GLfloat *) shadowMatrix); glPolygonOffset(-1.0, -1.0); glEnable(GL_POLYGON_OFFSET_FILL); glass(0); glTranslatef(0,.4,0); glCullFace(GL_BACK); donut(0); glCullFace(GL_FRONT); glTranslatef(0,-.4,0); glDisable(GL_POLYGON_OFFSET_FILL); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glutSwapBuffers(); }
void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { glBlendColor(red, green, blue, alpha); }
void GLGSRender::begin() { rsx::thread::begin(); if (skip_frame) return; if (conditional_render_enabled && conditional_render_test_failed) return; init_buffers(); if (!framebuffer_status_valid) return; std::chrono::time_point<steady_clock> then = steady_clock::now(); bool color_mask_b = rsx::method_registers.color_mask_b(); bool color_mask_g = rsx::method_registers.color_mask_g(); bool color_mask_r = rsx::method_registers.color_mask_r(); bool color_mask_a = rsx::method_registers.color_mask_a(); gl_state.color_mask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); gl_state.depth_mask(rsx::method_registers.depth_write_enabled()); gl_state.stencil_mask(rsx::method_registers.stencil_mask()); if (gl_state.enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST)) { gl_state.depth_func(comparison_op(rsx::method_registers.depth_func())); float range_near = rsx::method_registers.clip_min(); float range_far = rsx::method_registers.clip_max(); if (g_cfg.video.strict_rendering_mode) gl_state.depth_range(range_near, range_far); else { //Workaround to preserve depth precision but respect z direction //Ni no Kuni sets a very restricted z range (0.9x - 1.) and depth reads / tests are broken if (range_near <= range_far) gl_state.depth_range(0.f, 1.f); else gl_state.depth_range(1.f, 0.f); } } if (glDepthBoundsEXT && (gl_state.enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT))) { gl_state.depth_bounds(rsx::method_registers.depth_bounds_min(), rsx::method_registers.depth_bounds_max()); } gl_state.enable(rsx::method_registers.dither_enabled(), GL_DITHER); if (gl_state.enable(rsx::method_registers.blend_enabled(), GL_BLEND)) { glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()), blend_factor(rsx::method_registers.blend_func_dfactor_rgb()), blend_factor(rsx::method_registers.blend_func_sfactor_a()), blend_factor(rsx::method_registers.blend_func_dfactor_a())); auto blend_colors = rsx::get_constant_blend_colors(); glBlendColor(blend_colors[0], blend_colors[1], blend_colors[2], blend_colors[3]); glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()), blend_equation(rsx::method_registers.blend_equation_a())); } if (gl_state.enable(rsx::method_registers.stencil_test_enabled(), GL_STENCIL_TEST)) { glStencilFunc(comparison_op(rsx::method_registers.stencil_func()), rsx::method_registers.stencil_func_ref(), rsx::method_registers.stencil_func_mask()); glStencilOp(stencil_op(rsx::method_registers.stencil_op_fail()), stencil_op(rsx::method_registers.stencil_op_zfail()), stencil_op(rsx::method_registers.stencil_op_zpass())); if (rsx::method_registers.two_sided_stencil_test_enabled()) { glStencilMaskSeparate(GL_BACK, rsx::method_registers.back_stencil_mask()); glStencilFuncSeparate(GL_BACK, comparison_op(rsx::method_registers.back_stencil_func()), rsx::method_registers.back_stencil_func_ref(), rsx::method_registers.back_stencil_func_mask()); glStencilOpSeparate(GL_BACK, stencil_op(rsx::method_registers.back_stencil_op_fail()), stencil_op(rsx::method_registers.back_stencil_op_zfail()), stencil_op(rsx::method_registers.back_stencil_op_zpass())); } } gl_state.enablei(rsx::method_registers.blend_enabled_surface_1(), GL_BLEND, 1); gl_state.enablei(rsx::method_registers.blend_enabled_surface_2(), GL_BLEND, 2); gl_state.enablei(rsx::method_registers.blend_enabled_surface_3(), GL_BLEND, 3); if (gl_state.enable(rsx::method_registers.logic_op_enabled(), GL_COLOR_LOGIC_OP)) { gl_state.logic_op(logic_op(rsx::method_registers.logic_operation())); } gl_state.line_width(rsx::method_registers.line_width()); gl_state.enable(rsx::method_registers.line_smooth_enabled(), GL_LINE_SMOOTH); gl_state.enable(rsx::method_registers.poly_offset_point_enabled(), GL_POLYGON_OFFSET_POINT); gl_state.enable(rsx::method_registers.poly_offset_line_enabled(), GL_POLYGON_OFFSET_LINE); gl_state.enable(rsx::method_registers.poly_offset_fill_enabled(), GL_POLYGON_OFFSET_FILL); gl_state.polygon_offset(rsx::method_registers.poly_offset_scale(), rsx::method_registers.poly_offset_bias()); if (gl_state.enable(rsx::method_registers.cull_face_enabled(), GL_CULL_FACE)) { gl_state.cull_face(cull_face(rsx::method_registers.cull_face_mode())); } gl_state.front_face(front_face(rsx::method_registers.front_face_mode())); //TODO //NV4097_SET_ANISO_SPREAD //NV4097_SET_SPECULAR_ENABLE //NV4097_SET_TWO_SIDE_LIGHT_EN //NV4097_SET_FLAT_SHADE_OP //NV4097_SET_EDGE_FLAG //NV4097_SET_COLOR_KEY_COLOR //NV4097_SET_SHADER_CONTROL //NV4097_SET_ZMIN_MAX_CONTROL //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE std::chrono::time_point<steady_clock> now = steady_clock::now(); m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count(); }
/*------------------------------------------------------------------------- -------------------------------------------------------------------------*/ void FilterBox::Draw(float f) { if(!bValid) return; glPolygonMode( GL_FRONT_AND_BACK, GL_FILL); CGbool bRes; bRes = cgValidateTechnique(cgTechnique); if(!bRes) { bValid = false; const char * pszErrors = NULL; fprintf(stderr, "Validation of FilterRect failed"); fprintf(stderr, "CgFx Parse error : %s", pszErrors); const char *listing = cgGetLastListing(cgContext); return; } // // intermediate stage : bluring horizontal // glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[1]); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0,0,bufw,bufh); cgGLSetupSampler(srcSampler, textureID[0]); cgSetPassState(cgPassFilterH); FULLSCRQUAD(); glPopAttrib(); // // intermediate stage : bluring vertical // glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0,0,bufw,bufh); cgGLSetupSampler(srcSampler, textureID[1]); cgSetPassState(cgPassFilterV); FULLSCRQUAD(); glPopAttrib(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // // Final stage : Blend the final texture to the screen // cgGLSetupSampler(tempSampler, textureID[0]); cgSetPassState(cgPassBlend); glBlendColor(f,f,f,f); float xoffset = -1.0f + 2.0f*(float)posx/(float)vpw; float yoffset = -1.0f + 2.0f*(float)posy/(float)vph; float xoffset2 = xoffset + 2.0f*(float)width/(float)vpw; float yoffset2 = yoffset + 2.0f*(float)height/(float)vph; glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex4f(xoffset, yoffset, 0,1); glTexCoord2f(1,0); glVertex4f(xoffset2, yoffset,0,1); glTexCoord2f(1,1); glVertex4f(xoffset2, yoffset2,0,1); glTexCoord2f(0,1); glVertex4f(xoffset, yoffset2,0,1); glEnd(); cgResetPassState(cgPassBlend); }
static void _cg_pipeline_flush_common_gl_state(cg_device_t *dev, cg_pipeline_t *pipeline, unsigned long pipelines_difference, unsigned long *layer_differences, bool with_color_attrib) { cg_pipeline_flush_layer_state_t state; if (pipelines_difference & CG_PIPELINE_STATE_BLEND) { cg_pipeline_t *authority = _cg_pipeline_get_authority(pipeline, CG_PIPELINE_STATE_BLEND); cg_pipeline_blend_state_t *blend_state = &authority->big_state->blend_state; if (blend_factor_uses_constant(blend_state->blend_src_factor_rgb) || blend_factor_uses_constant(blend_state->blend_src_factor_alpha) || blend_factor_uses_constant(blend_state->blend_dst_factor_rgb) || blend_factor_uses_constant(blend_state->blend_dst_factor_alpha)) { float red = blend_state->blend_constant.red; float green = blend_state->blend_constant.green; float blue = blend_state->blend_constant.blue; float alpha = blend_state->blend_constant.alpha; GE(dev, glBlendColor(red, green, blue, alpha)); } if (dev->glBlendEquationSeparate && blend_state->blend_equation_rgb != blend_state->blend_equation_alpha) GE(dev, glBlendEquationSeparate(blend_state->blend_equation_rgb, blend_state->blend_equation_alpha)); else GE(dev, glBlendEquation(blend_state->blend_equation_rgb)); if (dev->glBlendFuncSeparate && (blend_state->blend_src_factor_rgb != blend_state->blend_src_factor_alpha || (blend_state->blend_dst_factor_rgb != blend_state->blend_dst_factor_alpha))) GE(dev, glBlendFuncSeparate(blend_state->blend_src_factor_rgb, blend_state->blend_dst_factor_rgb, blend_state->blend_src_factor_alpha, blend_state->blend_dst_factor_alpha)); else GE(dev, glBlendFunc(blend_state->blend_src_factor_rgb, blend_state->blend_dst_factor_rgb)); } if (pipelines_difference & CG_PIPELINE_STATE_DEPTH) { cg_pipeline_t *authority = _cg_pipeline_get_authority(pipeline, CG_PIPELINE_STATE_DEPTH); cg_depth_state_t *depth_state = &authority->big_state->depth_state; flush_depth_state(dev, depth_state); } if (pipelines_difference & CG_PIPELINE_STATE_LOGIC_OPS) { cg_pipeline_t *authority = _cg_pipeline_get_authority(pipeline, CG_PIPELINE_STATE_LOGIC_OPS); cg_pipeline_logic_ops_state_t *logic_ops_state = &authority->big_state->logic_ops_state; cg_color_mask_t color_mask = logic_ops_state->color_mask; if (dev->current_draw_buffer) color_mask &= dev->current_draw_buffer->color_mask; GE(dev, glColorMask(!!(color_mask & CG_COLOR_MASK_RED), !!(color_mask & CG_COLOR_MASK_GREEN), !!(color_mask & CG_COLOR_MASK_BLUE), !!(color_mask & CG_COLOR_MASK_ALPHA))); dev->current_gl_color_mask = color_mask; } if (pipelines_difference & CG_PIPELINE_STATE_CULL_FACE) { cg_pipeline_t *authority = _cg_pipeline_get_authority(pipeline, CG_PIPELINE_STATE_CULL_FACE); cg_pipeline_cull_face_state_t *cull_face_state = &authority->big_state->cull_face_state; if (cull_face_state->mode == CG_PIPELINE_CULL_FACE_MODE_NONE) GE(dev, glDisable(GL_CULL_FACE)); else { bool invert_winding; GE(dev, glEnable(GL_CULL_FACE)); switch (cull_face_state->mode) { case CG_PIPELINE_CULL_FACE_MODE_NONE: c_assert_not_reached(); case CG_PIPELINE_CULL_FACE_MODE_FRONT: GE(dev, glCullFace(GL_FRONT)); break; case CG_PIPELINE_CULL_FACE_MODE_BACK: GE(dev, glCullFace(GL_BACK)); break; case CG_PIPELINE_CULL_FACE_MODE_BOTH: GE(dev, glCullFace(GL_FRONT_AND_BACK)); break; } /* If we are painting to an offscreen framebuffer then we need to invert the winding of the front face because everything is painted upside down */ invert_winding = cg_is_offscreen(dev->current_draw_buffer); switch (cull_face_state->front_winding) { case CG_WINDING_CLOCKWISE: GE(dev, glFrontFace(invert_winding ? GL_CCW : GL_CW)); break; case CG_WINDING_COUNTER_CLOCKWISE: GE(dev, glFrontFace(invert_winding ? GL_CW : GL_CCW)); break; } } } #ifdef CG_HAS_GL_SUPPORT if (_cg_has_private_feature(dev, CG_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE) && (pipelines_difference & CG_PIPELINE_STATE_PER_VERTEX_POINT_SIZE)) { unsigned long state = CG_PIPELINE_STATE_PER_VERTEX_POINT_SIZE; cg_pipeline_t *authority = _cg_pipeline_get_authority(pipeline, state); if (authority->big_state->per_vertex_point_size) GE(dev, glEnable(GL_PROGRAM_POINT_SIZE)); else GE(dev, glDisable(GL_PROGRAM_POINT_SIZE)); } #endif if (pipeline->real_blend_enable != dev->gl_blend_enable_cache) { if (pipeline->real_blend_enable) GE(dev, glEnable(GL_BLEND)); else GE(dev, glDisable(GL_BLEND)); /* XXX: we shouldn't update any other blend state if blending * is disabled! */ dev->gl_blend_enable_cache = pipeline->real_blend_enable; } state.dev = dev; state.i = 0; state.layer_differences = layer_differences; _cg_pipeline_foreach_layer_internal( pipeline, flush_layers_common_gl_state_cb, &state); }
QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); primaryFBO->release(); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); QOpenGLFramebufferObject* destFBO = toTexture ? Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject() : NULL; if (_isEmpty) { // copy the primary to the screen if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO); } else { maybeBind(destFBO); glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glColor3f(1.0f, 1.0f, 1.0f); renderFullscreenQuad(); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); maybeRelease(destFBO); } } else if (_renderMode == ADD_MODE) { maybeBind(destFBO); _addProgram->bind(); renderFullscreenQuad(); _addProgram->release(); maybeRelease(destFBO); } else if (_renderMode == DIFFUSE_ADD_MODE) { // diffuse into the secondary/tertiary (alternating between frames) QOpenGLFramebufferObject* oldDiffusedFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); QOpenGLFramebufferObject* newDiffusedFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); if (_isOddFrame) { qSwap(oldDiffusedFBO, newDiffusedFBO); } newDiffusedFBO->bind(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); _diffuseProgram->bind(); QSize size = Application::getInstance()->getGLWidget()->size(); _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); renderFullscreenQuad(); _diffuseProgram->release(); newDiffusedFBO->release(); // add diffused texture to the primary glBindTexture(GL_TEXTURE_2D, newDiffusedFBO->texture()); if (toTexture) { destFBO = oldDiffusedFBO; } maybeBind(destFBO); _addSeparateProgram->bind(); renderFullscreenQuad(); _addSeparateProgram->release(); maybeRelease(destFBO); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); } else { // _renderMode == BLUR_ADD_MODE || _renderMode == BLUR_PERSIST_ADD_MODE // render the primary to the secondary with the horizontal blur QOpenGLFramebufferObject* secondaryFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); secondaryFBO->bind(); _horizontalBlurProgram->bind(); renderFullscreenQuad(); _horizontalBlurProgram->release(); secondaryFBO->release(); if (_renderMode == BLUR_ADD_MODE) { // render the secondary to the screen with the vertical blur glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); if (toTexture) { destFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); } maybeBind(destFBO); _verticalBlurAddProgram->bind(); renderFullscreenQuad(); _verticalBlurAddProgram->release(); maybeRelease(destFBO); } else { // _renderMode == BLUR_PERSIST_ADD_MODE // render the secondary to the tertiary with horizontal blur and persistence QOpenGLFramebufferObject* tertiaryFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); tertiaryFBO->bind(); glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_CONSTANT_ALPHA, GL_CONSTANT_ALPHA); const float PERSISTENCE_SMOOTHING = 0.9f; glBlendColor(0.0f, 0.0f, 0.0f, PERSISTENCE_SMOOTHING); glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); _verticalBlurProgram->bind(); renderFullscreenQuad(); _verticalBlurProgram->release(); glBlendColor(0.0f, 0.0f, 0.0f, 0.0f); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glDisable(GL_BLEND); // now add the tertiary to the primary buffer tertiaryFBO->release(); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tertiaryFBO->texture()); maybeBind(destFBO); _addSeparateProgram->bind(); renderFullscreenQuad(); _addSeparateProgram->release(); maybeRelease(destFBO); } glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); } glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glEnable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindTexture(GL_TEXTURE_2D, 0); return destFBO; }
void C4FoWRegion::Render(const C4TargetFacet *pOnScreen) { #ifndef USE_CONSOLE // Update FoW at interesting location pFoW->Update(Region, pPlayer); // On screen? No need to set up frame buffer - simply shortcut if (pOnScreen) { pFoW->Render(this, pOnScreen, pPlayer); return; } // Set up shader. If this one doesn't work, we're really in trouble. C4Shader *pShader = pFoW->GetFramebufShader(); assert(pShader); if (!pShader) return; // Create & bind the frame buffer pDraw->StorePrimaryClipper(); if(!BindFramebuf()) { pDraw->RestorePrimaryClipper(); return; } assert(pSurface && hFrameBufDraw); if (!pSurface || !hFrameBufDraw) return; // Set up a clean context glViewport(0, 0, getSurface()->Wdt, getSurface()->Hgt); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, getSurface()->Wdt, getSurface()->Hgt, 0); // Clear texture contents assert(getSurface()->Hgt % 2 == 0); glScissor(0, getSurface()->Hgt / 2, getSurface()->Wdt, getSurface()->Hgt / 2); glClearColor(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 0.0f); glEnable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT); // clear lower half of texture glScissor(0, 0, getSurface()->Wdt, getSurface()->Hgt / 2); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); // Render FoW to frame buffer object glBlendFunc(GL_ONE, GL_ONE); pFoW->Render(this, NULL, pPlayer); // Copy over the old state if (OldRegion.Wdt > 0) { // How much the borders have moved int dx0 = Region.x - OldRegion.x, dy0 = Region.y - OldRegion.y, dx1 = Region.x + Region.Wdt - OldRegion.x - OldRegion.Wdt, dy1 = Region.y + Region.Hgt - OldRegion.y - OldRegion.Hgt; // Source and target rect coordinates (landscape coordinate system) int sx0 = Max(0, dx0), sy0 = Max(0, dy0), sx1 = OldRegion.Wdt - Max(0, -dx1), sy1 = OldRegion.Hgt - Max(0, -dy1), tx0 = Max(0, -dx0), ty0 = Max(0, -dy0), tx1 = Region.Wdt - Max(0, dx1), ty1 = Region.Hgt - Max(0, dy1); // Quad coordinates float squad[8] = { float(sx0), float(sy0), float(sx0), float(sy1), float(sx1), float(sy1), float(sx1), float(sy0) }; int tquad[8] = { sx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, }; // Transform into texture coordinates for (int i = 0; i < 4; i++) { squad[i*2] = squad[i*2] / getBackSurface()->Wdt; squad[i*2+1] = 1.0 - squad[i*2+1] / getBackSurface()->Hgt; } // Copy using shader C4ShaderCall Call(pShader); Call.Start(); if (Call.AllocTexUnit(0)) glBindTexture(GL_TEXTURE_2D, getBackSurface()->textures[0].texName); glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR); float normalBlend = 1.0f / 4.0f, // Normals change quickly brightBlend = 1.0f / 16.0f; // Intensity more slowly glBlendColor(0.0f,normalBlend,normalBlend,brightBlend); glBegin(GL_QUADS); for (int i = 0; i < 4; i++) { glTexCoord2f(squad[i*2], squad[i*2+1]); glVertex2i(tquad[i*2], tquad[i*2+1]); } glEnd(); Call.Finish(); } // Done! glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glMatrixMode(GL_PROJECTION); glPopMatrix(); pDraw->RestorePrimaryClipper(); glCheck(); OldRegion = Region; #endif }
void GlowEffect::begin(float intensity) { // store the current intensity and add the new amount _intensityStack.push(_intensity); glBlendColor(0.0f, 0.0f, 0.0f, _intensity += intensity); _isEmpty &= (_intensity == 0.0f); }
virtual void render(double currentTime) { int i, j; static const GLfloat orange[] = { 0.6f, 0.4f, 0.1f, 1.0f }; static const GLfloat one = 1.0f; static const GLenum blend_func[] = { GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE, GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR, GL_SRC1_ALPHA, GL_ONE_MINUS_SRC1_ALPHA }; static const int num_blend_funcs = sizeof(blend_func) / sizeof(blend_func[0]); static const float x_scale = 20.0f / float(num_blend_funcs); static const float y_scale = 16.0f / float(num_blend_funcs); const float t = (float)currentTime; glViewport(0, 0, info.windowWidth, info.windowHeight); glClearBufferfv(GL_COLOR, 0, orange); glClearBufferfv(GL_DEPTH, 0, &one); glUseProgram(program); vmath::mat4 proj_matrix = vmath::perspective(50.0f, (float)info.windowWidth / (float)info.windowHeight, 0.1f, 1000.0f); glUniformMatrix4fv(proj_location, 1, GL_FALSE, proj_matrix); glEnable(GL_BLEND); glBlendColor(0.2f, 0.5f, 0.7f, 0.5f); for (j = 0; j < num_blend_funcs; j++) { for (i = 0; i < num_blend_funcs; i++) { vmath::mat4 mv_matrix = vmath::translate(9.5f - x_scale * float(i), 7.5f - y_scale * float(j), -18.0f) * vmath::rotate(t * -45.0f, 0.0f, 1.0f, 0.0f) * vmath::rotate(t * -21.0f, 1.0f, 0.0f, 0.0f); glUniformMatrix4fv(mv_location, 1, GL_FALSE, mv_matrix); glBlendFunc(blend_func[i], blend_func[j]); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); } } }
void OpenGLState::Apply() const { // Culling if (cull.enabled != cur_state.cull.enabled) { if (cull.enabled) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } } if (cull.mode != cur_state.cull.mode) { glCullFace(cull.mode); } if (cull.front_face != cur_state.cull.front_face) { glFrontFace(cull.front_face); } // Depth test if (depth.test_enabled != cur_state.depth.test_enabled) { if (depth.test_enabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } if (depth.test_func != cur_state.depth.test_func) { glDepthFunc(depth.test_func); } // Depth mask if (depth.write_mask != cur_state.depth.write_mask) { glDepthMask(depth.write_mask); } // Color mask if (color_mask.red_enabled != cur_state.color_mask.red_enabled || color_mask.green_enabled != cur_state.color_mask.green_enabled || color_mask.blue_enabled != cur_state.color_mask.blue_enabled || color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) { glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled); } // Stencil test if (stencil.test_enabled != cur_state.stencil.test_enabled) { if (stencil.test_enabled) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } } if (stencil.test_func != cur_state.stencil.test_func || stencil.test_ref != cur_state.stencil.test_ref || stencil.test_mask != cur_state.stencil.test_mask) { glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); } if (stencil.action_depth_fail != cur_state.stencil.action_depth_fail || stencil.action_depth_pass != cur_state.stencil.action_depth_pass || stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) { glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); } // Stencil mask if (stencil.write_mask != cur_state.stencil.write_mask) { glStencilMask(stencil.write_mask); } // Blending if (blend.enabled != cur_state.blend.enabled) { if (blend.enabled) { glEnable(GL_BLEND); cur_state.logic_op = GL_COPY; glLogicOp(cur_state.logic_op); glDisable(GL_COLOR_LOGIC_OP); } else { glDisable(GL_BLEND); glEnable(GL_COLOR_LOGIC_OP); } } if (blend.color.red != cur_state.blend.color.red || blend.color.green != cur_state.blend.color.green || blend.color.blue != cur_state.blend.color.blue || blend.color.alpha != cur_state.blend.color.alpha) { glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); } if (blend.src_rgb_func != cur_state.blend.src_rgb_func || blend.dst_rgb_func != cur_state.blend.dst_rgb_func || blend.src_a_func != cur_state.blend.src_a_func || blend.dst_a_func != cur_state.blend.dst_a_func) { glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); } if (blend.rgb_equation != cur_state.blend.rgb_equation || blend.a_equation != cur_state.blend.a_equation) { glBlendEquationSeparate(blend.rgb_equation, blend.a_equation); } if (logic_op != cur_state.logic_op) { glLogicOp(logic_op); } // Textures for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); } if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { glBindSampler(i, texture_units[i].sampler); } } // Lighting LUTs for (unsigned i = 0; i < ARRAY_SIZE(lighting_luts); ++i) { if (lighting_luts[i].texture_1d != cur_state.lighting_luts[i].texture_1d) { glActiveTexture(GL_TEXTURE3 + i); glBindTexture(GL_TEXTURE_1D, lighting_luts[i].texture_1d); } } // Fog LUT if (fog_lut.texture_1d != cur_state.fog_lut.texture_1d) { glActiveTexture(GL_TEXTURE9); glBindTexture(GL_TEXTURE_1D, fog_lut.texture_1d); } // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); } if (draw.draw_framebuffer != cur_state.draw.draw_framebuffer) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer); } // Vertex array if (draw.vertex_array != cur_state.draw.vertex_array) { glBindVertexArray(draw.vertex_array); } // Vertex buffer if (draw.vertex_buffer != cur_state.draw.vertex_buffer) { glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer); } // Uniform buffer if (draw.uniform_buffer != cur_state.draw.uniform_buffer) { glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer); } // Shader program if (draw.shader_program != cur_state.draw.shader_program) { glUseProgram(draw.shader_program); } cur_state = *this; }
/** * Run the whole suite of blend tests * Not a full factorial test, that would take too long. * Tests all add blending permutations. * Tests about 1/3 of subtract blending. * Skips most max and min tests. */ bool run_all_factor_sets(void) { bool pass = true; int gl_version = piglit_get_gl_version(); int counter = 0; /* Number of tests we have done. */ int step; int op, opa; int sf, sfa, df, dfa; unsigned num_src_factors_sep, num_dst_factors_sep; unsigned num_operators_rgb, num_operators_a; /* Find out what kind of GL blending capability we have. */ have_sep_func = false; have_blend_equation = false; have_blend_equation_sep = false; have_blend_color = false; if (gl_version >= 14) { have_blend_equation = true; if (piglit_is_extension_supported( "GL_EXT_blend_func_separate")) { have_sep_func = true; } if (piglit_is_extension_supported("GL_EXT_blend_color")) { have_blend_color = true; } } else if (piglit_is_extension_supported("GL_EXT_blend_subtract") && piglit_is_extension_supported("GL_EXT_blend_min_max")) { have_blend_equation = true; } if (gl_version >= 20) { have_blend_equation_sep = true; } else if (piglit_is_extension_supported( "GL_EXT_blend_equation_separate")) { have_blend_equation_sep = true; } if (have_blend_color) { /* Just one blend color setting for all tests */ /* A bright, semi-transparent blue */ glBlendColor(constant_color[0], constant_color[1], constant_color[2], constant_color[3]); } if (have_sep_func) { num_src_factors_sep = ARRAY_SIZE(src_factors); num_dst_factors_sep = ARRAY_SIZE(dst_factors); } else { num_src_factors_sep = 1; num_dst_factors_sep = 1; } if (have_blend_equation) { num_operators_rgb = ARRAY_SIZE(operators); num_operators_a = ARRAY_SIZE(operators); } else { num_operators_rgb = 1; /* just ADD */ num_operators_a = 1; /* just ADD */ } for (op = 0; op < num_operators_rgb; ++op) { for (opa = 0; opa < num_operators_a; ++opa) { if (operators[op] == GL_FUNC_ADD && operators[opa] == GL_FUNC_ADD) { /* test _all_ blend term combinations */ step = 1; } else if (operators[op] == GL_MIN || operators[op] == GL_MAX || operators[opa] == GL_MIN || operators[opa] == GL_MAX) { /* blend terms are N/A so only */ /* do one iteration of loops */ step = HUGE_STEP; } else { /* subtract modes: */ /*do every 3rd blend term for speed */ step = 3; } for (sf = 0; sf < ARRAY_SIZE(src_factors); sf += step) { for (sfa = 0; sfa < num_src_factors_sep; sfa += step) { for (df = 0; df < ARRAY_SIZE(dst_factors); df += step) { for (dfa = 0; dfa < num_dst_factors_sep; dfa += step) { pass &= proc_factors( sf, sfa, df, dfa, &counter, op, opa); } } } } } } printf("\nRan %i tests.\n", counter); return pass; } /* run_all_factor_sets */
void init() { text_shader = shader_load( "text.vert", "text.frag" ); font_manager = font_manager_new( 512, 512, LCD_FILTERING_ON ); buffer = text_buffer_new( ); vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 yellow = {{1.0, 1.0, 0.0, 1.0}}; vec4 grey = {{0.5, 0.5, 0.5, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; //char *f_normal = match_description("Vera:size=50"); char *f_normal = match_description("Arial"); char *f_bold = match_description("Arial", true); //char *f_bold = match_description("sans\\-serif:size=24"); char *f_italic = match_description("sans\\-serif", false, true); //char *f_italic = match_description("SimSun", false, true); //char *f_japanese = match_description("Droid Sans:size=18:lang=ja"); //char *f_japanese = match_description("sans-serif:size=18:lang=zh"); //char *f_japanese = match_description("sans\\-serif:size=18:lang=zh\\-CN"); //char *f_japanese = match_description("FZLanTingHeiS\\-UL\\-GB:size=18:lang=zh\\-CN"); //ok //char *f_japanese = match_description("FZLanTingHeiS\\-UL\\-GB"); //ok //char *f_japanese = match_description("Yu Gothic UI Semibold"); //ok //char *f_japanese = match_description("jj:size=18"); //ok //char *f_japanese = match_description("Brush Script MT"); //ok char *f_japanese = match_description("Microsoft JhengHei UI"); //ok //char *f_japanese = match_description("华文隶书:size=28:lang=zh\\-CN"); //no char *f_math = match_description("DejaVu Sans"); printf("init. f_normal: %s f_bold: %s f_italic: %s f_japanese: %s f_math: %s\n" , f_normal, f_bold, f_italic, f_japanese, f_math); //printf("init. f_japanese: %s\n" , f_japanese); //exit(0); markup_t normal = { .family = f_normal, .size = 20.0, .bold = 0, .italic = 0, .spacing = 0.0, .gamma = 2., .foreground_color = white, .background_color = none, .outline = 0, .outline_color = white, .underline = 0, .underline_color = white, .overline = 0, .overline_color = white, .strikethrough = 0, .strikethrough_color = white, .font = 0, }; markup_t highlight = normal; highlight.background_color = grey; markup_t reverse = normal; reverse.foreground_color = black; reverse.background_color = white; reverse.gamma = 1.0; markup_t overline = normal; overline.overline = 1; markup_t underline = normal; underline.underline = 1; markup_t small = normal; small.size = 10.0; markup_t big = normal; big.size = 48.0; big.italic = 1; big.foreground_color = yellow; markup_t bold = normal; bold.bold = 1; bold.family = f_bold; markup_t italic = normal; italic.italic = 1; italic.family = f_italic; markup_t japanese = normal; japanese.family = f_japanese; //markup_t japanese = normal; japanese.family = "C:/Windows/Fonts/simsun.ttc"; //markup_t japanese = normal; japanese.family = "c:/qtproject/opengl/freetype-gl/fonts/fireflysung.ttf"; japanese.size = 25.0; markup_t math = normal; math.family = f_math; #if 1 normal.font = font_manager_get_from_markup( font_manager, &normal ); highlight.font = font_manager_get_from_markup( font_manager, &highlight ); reverse.font = font_manager_get_from_markup( font_manager, &reverse ); overline.font = font_manager_get_from_markup( font_manager, &overline ); underline.font = font_manager_get_from_markup( font_manager, &underline ); small.font = font_manager_get_from_markup( font_manager, &small ); big.font = font_manager_get_from_markup( font_manager, &big ); bold.font = font_manager_get_from_markup( font_manager, &bold ); italic.font = font_manager_get_from_markup( font_manager, &italic ); japanese.font = font_manager_get_from_markup( font_manager, &japanese ); math.font = font_manager_get_from_markup( font_manager, &math ); #else japanese.font = font_manager_get_from_markup( font_manager, &japanese ); #endif vec2 pen = {{20, 200}}; #if 1 text_buffer_printf( buffer, &pen, &underline, "The", &normal, " Quick", &big, " brown ", &reverse, " fox \n", &italic, "jumps over ", &bold, "the lazy ", &normal, "dog.\n", &small, "Now is the time for all good men " "to come to the aid of the party.\n", &italic, "Ég get etið gler án þess að meiða mig.\n", &japanese, "aaa张私はガラスを食べられます。 それは私を傷つけません\n", &math, "ℕ ⊆ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ", NULL ); #else text_buffer_printf( buffer, &pen, &japanese, "Brush Script MT张私はガラスを食べられます。 それは私を傷つけません\n", NULL ); #endif glGenTextures( 1, &font_manager->atlas->id ); glBindTexture( GL_TEXTURE_2D, font_manager->atlas->id ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, font_manager->atlas->width, font_manager->atlas->height, 0, GL_RGB, GL_UNSIGNED_BYTE, font_manager->atlas->data ); printf("init font_manager->atlas->width: %d font_manager->atlas->height: %d\n" , font_manager->atlas->width, font_manager->atlas->height); text_buffer_align( buffer, &pen, ALIGN_CENTER ); vec4 bounds = text_buffer_get_bounds( buffer, &pen ); float left = bounds.left; float right = bounds.left + bounds.width; float top = bounds.top; float bottom = bounds.top - bounds.height; bounds_shader = shader_load( "v3f-c4f.vert", "v3f-c4f.frag" ); lines_buffer = vertex_buffer_new( "vertex:3f,color:4f" ); vertex_t vertices[] = { { left - 10, top, 0, 0,0,0,1}, // top {right + 10, top, 0, 0,0,0,1}, { left - 10, bottom, 0, 0,0,0,1}, // bottom {right + 10, bottom, 0, 0,0,0,1}, { left, top + 10, 0, 0,0,0,1}, // left { left, bottom - 10, 0, 0,0,0,1}, { right, top + 10, 0, 0,0,0,1}, // right { right, bottom - 10, 0, 0,0,0,1} }; GLuint indices[] = { 0,1,2,3,4,5,6,7 }; vertex_buffer_push_back( lines_buffer, vertices, 8, indices, 8); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); } // ---------------------------------------------------------------- display --- void display( GLFWwindow* window ) { glClearColor(0.40,0.40,0.45,1.00); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glColor4f(1.00,1.00,1.00,1.00); glUseProgram( text_shader ); { glUniformMatrix4fv( glGetUniformLocation( text_shader, "model" ), 1, 0, model.data); glUniformMatrix4fv( glGetUniformLocation( text_shader, "view" ), 1, 0, view.data); glUniformMatrix4fv( glGetUniformLocation( text_shader, "projection" ), 1, 0, projection.data); glUniform1i( glGetUniformLocation( text_shader, "tex" ), 0 ); glUniform3f( glGetUniformLocation( text_shader, "pixel" ), 1.0f/font_manager->atlas->width, 1.0f/font_manager->atlas->height, (float)font_manager->atlas->depth ); glEnable( GL_BLEND ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, font_manager->atlas->id ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBlendColor( 1, 1, 1, 1 ); vertex_buffer_render( buffer->buffer, GL_TRIANGLES ); glBindTexture( GL_TEXTURE_2D, 0 ); glBlendColor( 0, 0, 0, 0 ); glUseProgram( 0 ); } glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); glBlendColor( 1.0, 1.0, 1.0, 1.0 ); glUseProgram( bounds_shader ); { glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "model" ), 1, 0, model.data); glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "view" ), 1, 0, view.data); glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "projection" ), 1, 0, projection.data); vertex_buffer_render( lines_buffer, GL_LINES ); } glfwSwapBuffers( window ); }
void GLGSRender::begin() { rsx::thread::begin(); if (!load_program()) { //no program - no drawing return; } init_buffers(); u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; bool color_mask_b = !!(color_mask & 0xff); bool color_mask_g = !!((color_mask >> 8) & 0xff); bool color_mask_r = !!((color_mask >> 16) & 0xff); bool color_mask_a = !!((color_mask >> 24) & 0xff); __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); if (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) { __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); } if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))) { __glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]); } __glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]); __glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); if (!!rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]) { //TODO: NV4097_SET_ALPHA_REF must be converted to f32 //glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF])); } if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) { u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; u16 sfactor_rgb = sfactor; u16 sfactor_a = sfactor >> 16; u16 dfactor_rgb = dfactor; u16 dfactor_a = dfactor >> 16; __glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a); if (m_surface.color_format == rsx::surface_color_format::w16z16y16x16) //TODO: check another color formats { u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2]; u16 blend_color_r = blend_color; u16 blend_color_g = blend_color >> 16; u16 blend_color_b = blend_color2; u16 blend_color_a = blend_color2 >> 16; __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); }
/////////////////////////////////////////////////////////////////////////////// // runOne: Run a single test case /////////////////////////////////////////////////////////////////////////////// void BlendFuncTest::runOne(BlendFuncResult& r, Window& w) { GLUtils::useScreenCoords(drawingSize + 2, drawingSize + 2); static GLenum srcFactors[] = { GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA_SATURATE, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA }; static GLenum dstFactors[] = { GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA }; static GLenum operators[] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX }; // Hack: Make driver tests on incorrect hardware feasible // We want to be able to perform meaningful tests // even when the blend unit of a GPU simply doesn't have // sufficient precision. float rgbTolerance = 1.0; float alphaTolerance = 1.0; const char* s = getenv("GLEAN_BLEND_RGB_TOLERANCE"); if (s) { rgbTolerance = atof(s); env->log << "Note: RGB tolerance changed to " << rgbTolerance << "\n"; } s = getenv("GLEAN_BLEND_ALPHA_TOLERANCE"); if (s) { alphaTolerance = atof(s); env->log << "Note: Alpha tolerance changed to " << alphaTolerance << "\n"; } unsigned numSrcFactorsSep, numDstFactorsSep; unsigned numOperatorsRGB, numOperatorsA; BlendFuncResult::PartialResult p; bool allPassed = true; unsigned testNo, testStride; // test for features, get function pointers if (GLUtils::getVersion() >= 1.4 || GLUtils::haveExtension("GL_EXT_blend_func_separate")) { haveSepFunc = true; } if (GLUtils::getVersion() >= 1.4 || GLUtils::haveExtension("GL_EXT_blend_color")) { haveBlendColor = true; } if (GLUtils::getVersion() >= 1.4) { haveBlendEquation = true; } else if (GLUtils::haveExtension("GL_EXT_blend_subtract") && GLUtils::haveExtension("GL_EXT_blend_min_max")) { haveBlendEquation = true; } if (GLUtils::getVersion() >= 2.0) { haveBlendEquationSep = true; } else if (GLUtils::haveExtension("GL_EXT_blend_equation_separate")) { haveBlendEquationSep = true; } if (haveBlendColor) { // Just one blend color setting for all tests p.constColor[0] = 0.25; p.constColor[1] = 0.0; p.constColor[2] = 1.0; p.constColor[3] = 0.75; glBlendColor(p.constColor[0], p.constColor[1], p.constColor[2], p.constColor[3]); } if (haveSepFunc) { numSrcFactorsSep = ELEMENTS(srcFactors); numDstFactorsSep = ELEMENTS(dstFactors); } else { numSrcFactorsSep = 1; numDstFactorsSep = 1; } if (haveBlendEquation) { numOperatorsRGB = ELEMENTS(operators); numOperatorsA = ELEMENTS(operators); } else { numOperatorsRGB = 1; // just ADD numOperatorsA = 1; // just ADD } // If quick mode, run fewer tests if (env->options.quick) { testStride = 53; // a prime number assert(ELEMENTS(srcFactors) % testStride); assert(ELEMENTS(dstFactors) % testStride); assert(ELEMENTS(operators) % testStride); } else { testStride = 1; } testNo = testStride - 1; #if 0 // use this to test a single combination: p.srcRGB = p.srcA = GL_SRC_ALPHA; p.dstRGB = p.dstA = GL_ONE_MINUS_SRC_ALPHA; p.opRGB = GL_FUNC_ADD; p.opA = GL_FUNC_ADD; allPassed = runCombo(r, w, p, *env); #else for (unsigned int op = 0; op < numOperatorsRGB; ++op) { p.opRGB = operators[op]; for (unsigned int opa = 0; opa < numOperatorsA; ++opa) { p.opA = operators[opa]; unsigned int step; if (p.opRGB == GL_FUNC_ADD && p.opA == GL_FUNC_ADD) { // test _all_ blend term combinations step = 1; } else if (p.opRGB == GL_MIN || p.opRGB == GL_MAX || p.opA == GL_MIN || p.opA == GL_MAX) { // blend terms are N/A so only do one iteration of loops step = HUGE_STEP; } else { // subtract modes: do every 3rd blend term for speed step = 3; } for (unsigned int sf = 0; sf < ELEMENTS(srcFactors); sf += step) { for (unsigned int sfa = 0; sfa < numSrcFactorsSep; sfa += step) { for (unsigned int df = 0; df < ELEMENTS(dstFactors); df += step) { for (unsigned int dfa = 0; dfa < numDstFactorsSep; dfa += step) { if (haveSepFunc) { p.srcRGB = srcFactors[sf]; p.srcA = srcFactors[sfa]; p.dstRGB = dstFactors[df]; p.dstA = dstFactors[dfa]; } else { p.srcRGB = p.srcA = srcFactors[sf]; p.dstRGB = p.dstA = dstFactors[df]; } // skip test if it depends on non-existant alpha channel if ((r.config->a == 0) && (needsDstAlpha(p.srcRGB) || needsDstAlpha(p.srcA) || needsDstAlpha(p.dstRGB) || needsDstAlpha(p.dstA))) continue; // skip test if blend color used, but not supported. if (!haveBlendColor && (needsBlendColor(p.srcRGB) || needsBlendColor(p.srcA) || needsBlendColor(p.dstRGB) || needsBlendColor(p.dstA))) continue; // skip all but every testStride-th test ++testNo; if (testNo == testStride || step >= HUGE_STEP) { testNo = 0; } else { continue; } if (!runCombo(r, w, p, *env, rgbTolerance, alphaTolerance)) { allPassed = false; } } } } } } } #endif r.pass = allPassed; } // BlendFuncTest::runOne
void GlowEffect::end() { // restore the saved intensity glBlendColor(0.0f, 0.0f, 0.0f, _intensity = _intensityStack.pop()); }
void GLGSRender::ExecCMD() { if(!LoadProgram()) { ConLog.Error("LoadProgram failed."); Emu.Pause(); return; } if(!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format) { ConLog.Warning("New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); last_width = RSXThread::m_width; last_height = RSXThread::m_height; last_depth_format = m_surface_depth_format; m_fbo.Create(); checkForGlError("m_fbo.Create"); m_fbo.Bind(); m_rbo.Create(4 + 1); checkForGlError("m_rbo.Create"); for(int i=0; i<4; ++i) { m_rbo.Bind(i); m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_RGBA)"); } m_rbo.Bind(4); switch(m_surface_depth_format) { case 1: m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); break; case 2: m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); break; default: ConLog.Error("Bad depth format! (%d)", m_surface_depth_format); assert(0); break; } for(int i=0; i<4; ++i) { m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); checkForGlError(wxString::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); } m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); if(m_surface_depth_format == 2) { m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); } } if(!m_set_surface_clip_horizontal) { m_surface_clip_x = 0; m_surface_clip_w = RSXThread::m_width; } if(!m_set_surface_clip_vertical) { m_surface_clip_y = 0; m_surface_clip_h = RSXThread::m_height; } m_fbo.Bind(); if(Ini.GSDumpDepthBuffer.GetValue()) WriteDepthBuffer(); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; switch(m_surface_colour_target) { case 0x0: break; case 0x1: glDrawBuffer(draw_buffers[0]); break; case 0x2: glDrawBuffer(draw_buffers[1]); break; case 0x13: glDrawBuffers(2, draw_buffers); break; case 0x17: glDrawBuffers(3, draw_buffers); break; case 0x1f: glDrawBuffers(4, draw_buffers); break; default: ConLog.Error("Bad surface colour target: %d", m_surface_colour_target); break; } if(m_set_color_mask) { glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); checkForGlError("glColorMask"); } if(m_set_viewport_horizontal && m_set_viewport_vertical) { glViewport(m_viewport_x, RSXThread::m_height-m_viewport_y-m_viewport_h, m_viewport_w, m_viewport_h); checkForGlError("glViewport"); } if(m_set_scissor_horizontal && m_set_scissor_vertical) { glScissor(m_scissor_x, RSXThread::m_height-m_scissor_y-m_scissor_h, m_scissor_w, m_scissor_h); checkForGlError("glScissor"); } if(m_clear_surface_mask) { GLbitfield f = 0; if (m_clear_surface_mask & 0x1) { glClearDepth(m_clear_surface_z / (float)0xffffff); f |= GL_DEPTH_BUFFER_BIT; } if (m_clear_surface_mask & 0x2) { glClearStencil(m_clear_surface_s); f |= GL_STENCIL_BUFFER_BIT; } if (m_clear_surface_mask & 0xF0) { glClearColor( m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); f |= GL_COLOR_BUFFER_BIT; } glClear(f); } if(m_set_front_polygon_mode) { glPolygonMode(GL_FRONT, m_front_polygon_mode); checkForGlError("glPolygonMode"); } Enable(m_depth_test_enable, GL_DEPTH_TEST); Enable(m_set_alpha_test, GL_ALPHA_TEST); Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); Enable(m_set_blend, GL_BLEND); Enable(m_set_logic_op, GL_LOGIC_OP); Enable(m_set_cull_face_enable, GL_CULL_FACE); Enable(m_set_dither, GL_DITHER); Enable(m_set_stencil_test, GL_STENCIL_TEST); Enable(m_set_line_smooth, GL_LINE_SMOOTH); Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); //Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); //Requires OpenGL 3.1+ if(m_set_clip_plane) { Enable(m_clip_plane_0, GL_CLIP_PLANE0); Enable(m_clip_plane_1, GL_CLIP_PLANE1); Enable(m_clip_plane_2, GL_CLIP_PLANE2); Enable(m_clip_plane_3, GL_CLIP_PLANE3); Enable(m_clip_plane_4, GL_CLIP_PLANE4); Enable(m_clip_plane_5, GL_CLIP_PLANE5); checkForGlError("m_set_clip_plane"); } checkForGlError("glEnable"); if(m_set_two_sided_stencil_test_enable) { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOpSeparate"); } if(m_set_stencil_mask) { glStencilMaskSeparate(GL_FRONT, m_stencil_mask); checkForGlError("glStencilMaskSeparate"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFuncSeparate"); } if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) { glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); checkForGlError("glStencilOpSeparate(GL_BACK)"); } if(m_set_back_stencil_mask) { glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); checkForGlError("glStencilMaskSeparate(GL_BACK)"); } if(m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) { glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); checkForGlError("glStencilFuncSeparate(GL_BACK)"); } } else { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOp"); } if(m_set_stencil_mask) { glStencilMask(m_stencil_mask); checkForGlError("glStencilMask"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFunc"); } } if(m_set_shade_mode) { glShadeModel(m_shade_mode); checkForGlError("glShadeModel"); } if(m_set_depth_mask) { glDepthMask(m_depth_mask); checkForGlError("glDepthMask"); } if(m_set_depth_func) { glDepthFunc(m_depth_func); //ConLog.Warning("glDepthFunc(0x%x)", m_depth_func); checkForGlError("glDepthFunc"); } if(m_set_depth_bounds) { //ConLog.Warning("glDepthBounds(%f, %f)", m_depth_bounds_min, m_depth_bounds_max); glDepthBounds(m_depth_bounds_min, m_depth_bounds_max); checkForGlError("glDepthBounds"); } if(m_set_clip) { //ConLog.Warning("glDepthRangef(%f, %f)", m_clip_min, m_clip_max); glDepthRangef(m_clip_min, m_clip_max); checkForGlError("glDepthRangef"); } if(m_set_line_width) { glLineWidth(m_line_width / 255.f); checkForGlError("glLineWidth"); } if(m_set_blend_equation) { glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); checkForGlError("glBlendEquationSeparate"); } if(m_set_blend_sfactor && m_set_blend_dfactor) { glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); checkForGlError("glBlendFuncSeparate"); } if(m_set_blend_color) { glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); checkForGlError("glBlendColor"); } if(m_set_cull_face) { glCullFace(m_cull_face); checkForGlError("glCullFace"); } if(m_set_alpha_func && m_set_alpha_ref) { glAlphaFunc(m_alpha_func, m_alpha_ref); checkForGlError("glAlphaFunc"); } if(m_set_fog_mode) { glFogi(GL_FOG_MODE, m_fog_mode); checkForGlError("glFogi(GL_FOG_MODE)"); } if(m_set_fog_params) { glFogf(GL_FOG_START, m_fog_param0); checkForGlError("glFogf(GL_FOG_START)"); glFogf(GL_FOG_END, m_fog_param1); checkForGlError("glFogf(GL_FOG_END)"); } if(m_set_restart_index) { ConLog.Warning("m_set_restart_index requires glPrimitiveRestartIndex()"); //glPrimitiveRestartIndex(m_restart_index); //Requires OpenGL 3.1+ //checkForGlError("glPrimitiveRestartIndex"); } if(m_indexed_array.m_count && m_draw_array_count) { ConLog.Warning("m_indexed_array.m_count && draw_array_count"); } for(u32 i=0; i<m_textures_count; ++i) { if(!m_textures[i].IsEnabled()) continue; glActiveTexture(GL_TEXTURE0 + i); checkForGlError("glActiveTexture"); m_gl_textures[i].Create(); m_gl_textures[i].Bind(); checkForGlError(wxString::Format("m_gl_textures[%d].Bind", i)); m_program.SetTex(i); m_gl_textures[i].Init(m_textures[i]); checkForGlError(wxString::Format("m_gl_textures[%d].Init", i)); } m_vao.Bind(); if(m_indexed_array.m_count) { LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); } EnableVertexData(m_indexed_array.m_count ? true : false); InitVertexData(); InitFragmentData(); if(m_indexed_array.m_count) { switch(m_indexed_array.m_type) { case 0: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); checkForGlError("glDrawElements #4"); break; case 1: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); checkForGlError("glDrawElements #2"); break; default: ConLog.Error("Bad indexed array type (%d)", m_indexed_array.m_type); break; } DisableVertexData(); m_indexed_array.Reset(); } if(m_draw_array_count) { //ConLog.Warning("glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count); glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count); checkForGlError("glDrawArrays"); DisableVertexData(); } if(Ini.GSDumpColorBuffers.GetValue()) WriteBuffers(); }
void processFn(struct fnargs* args) { switch (args->fn) { case glfnUNDEFINED: abort(); // bad glfn break; case glfnActiveTexture: glActiveTexture((GLenum)args->a0); break; case glfnAttachShader: glAttachShader((GLint)args->a0, (GLint)args->a1); break; case glfnBindAttribLocation: glBindAttribLocation((GLint)args->a0, (GLint)args->a1, (GLchar*)args->a2); free((void*)args->a2); break; case glfnBindBuffer: glBindBuffer((GLenum)args->a0, (GLuint)args->a1); break; case glfnBindFramebuffer: glBindFramebuffer((GLenum)args->a0, (GLint)args->a1); break; case glfnBindRenderbuffer: glBindRenderbuffer((GLenum)args->a0, (GLint)args->a1); break; case glfnBindTexture: glBindTexture((GLenum)args->a0, (GLint)args->a1); break; case glfnBlendColor: glBlendColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnBlendEquation: glBlendEquation((GLenum)args->a0); break; case glfnBlendEquationSeparate: glBlendEquationSeparate((GLenum)args->a0, (GLenum)args->a1); break; case glfnBlendFunc: glBlendFunc((GLenum)args->a0, (GLenum)args->a1); break; case glfnBlendFuncSeparate: glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3); break; case glfnBufferData: glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2, (GLenum)args->a3); break; case glfnBufferSubData: glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)args->a3); break; case glfnCheckFramebufferStatus: ret = glCheckFramebufferStatus((GLenum)args->a0); break; case glfnClear: glClear((GLenum)args->a0); break; case glfnClearColor: glClearColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnClearDepthf: glClearDepthf(*(GLfloat*)&args->a0); break; case glfnClearStencil: glClearStencil((GLint)args->a0); break; case glfnColorMask: glColorMask((GLboolean)args->a0, (GLboolean)args->a1, (GLboolean)args->a2, (GLboolean)args->a3); break; case glfnCompileShader: glCompileShader((GLint)args->a0); break; case glfnCompressedTexImage2D: glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)args->a7); break; case glfnCompressedTexSubImage2D: glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)args->a8); break; case glfnCopyTexImage2D: glCopyTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7); break; case glfnCopyTexSubImage2D: glCopyTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7); break; case glfnCreateProgram: ret = glCreateProgram(); break; case glfnCreateShader: ret = glCreateShader((GLenum)args->a0); break; case glfnCullFace: glCullFace((GLenum)args->a0); break; case glfnDeleteBuffer: glDeleteBuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteFramebuffer: glDeleteFramebuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteProgram: glDeleteProgram((GLint)args->a0); break; case glfnDeleteRenderbuffer: glDeleteRenderbuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteShader: glDeleteShader((GLint)args->a0); break; case glfnDeleteTexture: glDeleteTextures(1, (const GLuint*)(&args->a0)); break; case glfnDepthFunc: glDepthFunc((GLenum)args->a0); break; case glfnDepthMask: glDepthMask((GLboolean)args->a0); break; case glfnDepthRangef: glDepthRangef(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1); break; case glfnDetachShader: glDetachShader((GLint)args->a0, (GLint)args->a1); break; case glfnDisable: glDisable((GLenum)args->a0); break; case glfnDisableVertexAttribArray: glDisableVertexAttribArray((GLint)args->a0); break; case glfnDrawArrays: glDrawArrays((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2); break; case glfnDrawElements: glDrawElements((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (void*)args->a3); break; case glfnEnable: glEnable((GLenum)args->a0); break; case glfnEnableVertexAttribArray: glEnableVertexAttribArray((GLint)args->a0); break; case glfnFinish: glFinish(); break; case glfnFlush: glFlush(); break; case glfnFramebufferRenderbuffer: glFramebufferRenderbuffer((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3); break; case glfnFramebufferTexture2D: glFramebufferTexture2D((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4); break; case glfnFrontFace: glFrontFace((GLenum)args->a0); break; case glfnGenBuffer: glGenBuffers(1, (GLuint*)&ret); break; case glfnGenFramebuffer: glGenFramebuffers(1, (GLuint*)&ret); break; case glfnGenRenderbuffer: glGenRenderbuffers(1, (GLuint*)&ret); break; case glfnGenTexture: glGenTextures(1, (GLuint*)&ret); break; case glfnGenerateMipmap: glGenerateMipmap((GLenum)args->a0); break; case glfnGetActiveAttrib: glGetActiveAttrib( (GLuint)args->a0, (GLuint)args->a1, (GLsizei)args->a2, NULL, (GLint*)args->a4, (GLenum*)args->a5, (GLchar*)args->a6); break; case glfnGetActiveUniform: glGetActiveUniform( (GLuint)args->a0, (GLuint)args->a1, (GLsizei)args->a2, NULL, (GLint*)args->a4, (GLenum*)args->a5, (GLchar*)args->a6); break; case glfnGetAttachedShaders: glGetAttachedShaders((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)args->a2, (GLuint*)args->a3); break; case glfnGetAttribLocation: ret = glGetAttribLocation((GLint)args->a0, (GLchar*)args->a1); free((void*)args->a1); break; case glfnGetBooleanv: glGetBooleanv((GLenum)args->a0, (GLboolean*)args->a1); break; case glfnGetBufferParameteri: glGetBufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetFloatv: glGetFloatv((GLenum)args->a0, (GLfloat*)args->a1); break; case glfnGetIntegerv: glGetIntegerv((GLenum)args->a0, (GLint*)args->a1); break; case glfnGetError: ret = glGetError(); break; case glfnGetFramebufferAttachmentParameteriv: glGetFramebufferAttachmentParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint*)&ret); break; case glfnGetProgramiv: glGetProgramiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetProgramInfoLog: glGetProgramInfoLog((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)args->a2, (GLchar*)args->a3); break; case glfnGetRenderbufferParameteriv: glGetRenderbufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetShaderiv: glGetShaderiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetShaderInfoLog: glGetShaderInfoLog((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)args->a2, (GLchar*)args->a3); break; case glfnGetShaderPrecisionFormat: glGetShaderPrecisionFormat((GLenum)args->a0, (GLenum)args->a1, (GLint*)args->a2, (GLint*)args->a3); break; case glfnGetShaderSource: glGetShaderSource((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)args->a2, (GLchar*)args->a3); break; case glfnGetString: ret = (uintptr_t)glGetString((GLenum)args->a0); break; case glfnGetTexParameterfv: glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)args->a2); break; case glfnGetTexParameteriv: glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)args->a2); break; case glfnGetUniformfv: glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)args->a2); break; case glfnGetUniformiv: glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)args->a2); break; case glfnGetUniformLocation: ret = glGetUniformLocation((GLint)args->a0, (GLchar*)args->a1); free((void*)args->a1); break; case glfnGetVertexAttribfv: glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)args->a2); break; case glfnGetVertexAttribiv: glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)args->a2); break; case glfnHint: glHint((GLenum)args->a0, (GLenum)args->a1); break; case glfnIsBuffer: ret = glIsBuffer((GLint)args->a0); break; case glfnIsEnabled: ret = glIsEnabled((GLenum)args->a0); break; case glfnIsFramebuffer: ret = glIsFramebuffer((GLint)args->a0); break; case glfnIsProgram: ret = glIsProgram((GLint)args->a0); break; case glfnIsRenderbuffer: ret = glIsRenderbuffer((GLint)args->a0); break; case glfnIsShader: ret = glIsShader((GLint)args->a0); break; case glfnIsTexture: ret = glIsTexture((GLint)args->a0); break; case glfnLineWidth: glLineWidth(*(GLfloat*)&args->a0); break; case glfnLinkProgram: glLinkProgram((GLint)args->a0); break; case glfnPixelStorei: glPixelStorei((GLenum)args->a0, (GLint)args->a1); break; case glfnPolygonOffset: glPolygonOffset(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1); break; case glfnReadPixels: glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)args->a6); break; case glfnReleaseShaderCompiler: glReleaseShaderCompiler(); break; case glfnRenderbufferStorage: glRenderbufferStorage((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnSampleCoverage: glSampleCoverage(*(GLfloat*)&args->a0, (GLboolean)args->a1); break; case glfnScissor: glScissor((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnShaderSource: #if defined(os_ios) || defined(os_osx) glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar *const *)args->a2, NULL); #else glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar **)args->a2, NULL); #endif free(*(void**)args->a2); free((void*)args->a2); break; case glfnStencilFunc: glStencilFunc((GLenum)args->a0, (GLint)args->a1, (GLuint)args->a2); break; case glfnStencilFuncSeparate: glStencilFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLuint)args->a3); break; case glfnStencilMask: glStencilMask((GLuint)args->a0); break; case glfnStencilMaskSeparate: glStencilMaskSeparate((GLenum)args->a0, (GLuint)args->a1); break; case glfnStencilOp: glStencilOp((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2); break; case glfnStencilOpSeparate: glStencilOpSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3); break; case glfnTexImage2D: glTexImage2D( (GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLsizei)args->a3, (GLsizei)args->a4, 0, // border (GLenum)args->a5, (GLenum)args->a6, (const GLvoid*)args->a7); break; case glfnTexSubImage2D: glTexSubImage2D( (GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLsizei)args->a4, (GLsizei)args->a5, (GLenum)args->a6, (GLenum)args->a7, (const GLvoid*)args->a8); break; case glfnTexParameterf: glTexParameterf((GLenum)args->a0, (GLenum)args->a1, *(GLfloat*)&args->a2); break; case glfnTexParameterfv: glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)args->a2); break; case glfnTexParameteri: glTexParameteri((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2); break; case glfnTexParameteriv: glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)args->a2); break; case glfnUniform1f: glUniform1f((GLint)args->a0, *(GLfloat*)&args->a1); break; case glfnUniform1fv: glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform1i: glUniform1i((GLint)args->a0, (GLint)args->a1); break; case glfnUniform1iv: glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform2f: glUniform2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2); break; case glfnUniform2fv: glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform2i: glUniform2i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2); break; case glfnUniform2iv: glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform3f: glUniform3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnUniform3fv: glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform3i: glUniform3i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnUniform3iv: glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform4f: glUniform4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4); break; case glfnUniform4fv: glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniform4i: glUniform4i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4); break; case glfnUniform4iv: glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2); break; case glfnUniformMatrix2fv: glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)args->a2); break; case glfnUniformMatrix3fv: glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)args->a2); break; case glfnUniformMatrix4fv: glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)args->a2); break; case glfnUseProgram: glUseProgram((GLint)args->a0); break; case glfnValidateProgram: glValidateProgram((GLint)args->a0); break; case glfnVertexAttrib1f: glVertexAttrib1f((GLint)args->a0, *(GLfloat*)&args->a1); break; case glfnVertexAttrib1fv: glVertexAttrib1fv((GLint)args->a0, (GLfloat*)args->a1); break; case glfnVertexAttrib2f: glVertexAttrib2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2); break; case glfnVertexAttrib2fv: glVertexAttrib2fv((GLint)args->a0, (GLfloat*)args->a1); break; case glfnVertexAttrib3f: glVertexAttrib3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnVertexAttrib3fv: glVertexAttrib3fv((GLint)args->a0, (GLfloat*)args->a1); break; case glfnVertexAttrib4f: glVertexAttrib4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4); break; case glfnVertexAttrib4fv: glVertexAttrib4fv((GLint)args->a0, (GLfloat*)args->a1); break; case glfnVertexAttribPointer: glVertexAttribPointer((GLuint)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLboolean)args->a3, (GLsizei)args->a4, (const GLvoid*)args->a5); break; case glfnViewport: glViewport((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; } }