示例#1
0
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++;
}
示例#2
0
文件: shadow.c 项目: whosteen/shadow
/* 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();
}
示例#3
0
void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
   glBlendColor(red, green, blue, alpha);
}
示例#4
0
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();
}
示例#5
0
/*-------------------------------------------------------------------------

  -------------------------------------------------------------------------*/
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);
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#8
0
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
}
示例#9
0
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);
}
示例#10
0
    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);
            }
        }
    }
示例#11
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;
}
示例#12
0
/**
 * 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 */
示例#13
0
文件: markup.cpp 项目: ginozh/my_wmm
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 );
}
示例#14
0
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);
		}
示例#15
0
///////////////////////////////////////////////////////////////////////////////
// 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
示例#16
0
void GlowEffect::end() {
    // restore the saved intensity
    glBlendColor(0.0f, 0.0f, 0.0f, _intensity = _intensityStack.pop());
}
示例#17
0
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();
}
示例#18
0
文件: work.c 项目: handong890/mobile
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;
	}
}