static void gst_gl_effects_twirl_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; GstGLFuncs *gl = context->gl_vtable; shader = gst_gl_effects_get_fragment_shader (effects, "twirl", twirl_fragment_source_gles2); if (!shader) return; #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_differencematte_diff (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (differencematte->shader[0]); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (differencematte->shader[0], "current", 0); gl->ActiveTexture (GL_TEXTURE1); gl->BindTexture (GL_TEXTURE_2D, differencematte->savedbgtexture); gst_gl_shader_set_uniform_1i (differencematte->shader[0], "saved", 1); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_sobel_callback_vconv (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader = NULL; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "vconv0", sep_sobel_vconv3_fragment_source_gles2, sep_sobel_vconv3_fragment_source_opengl))) { GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; #if GST_GL_HAVE_OPENGL if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "height", height); gst_gl_filter_draw_texture (filter, texture, width, height); } }
static void gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLFilter *filter = GST_GL_FILTER (data); GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "squeeze0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, (gchar *) "squeeze0", shader); if (USING_GLES2 (context) || USING_OPENGL3 (context)) { if (!gst_gl_shader_compile_with_default_v_and_check (shader, squeeze_fragment_source_gles2, &filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) { /* gst gl context error is already set */ GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("Failed to initialize squeeze shader, %s", gst_gl_context_get_error ()), (NULL)); return; } } #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { if (!gst_gl_shader_compile_and_check (shader, squeeze_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize squeeze shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } } #endif } #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); if (USING_OPENGL (context)) gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_differencematte_save_texture (gint width, gint height, guint texture, gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_filter_draw_texture (filter, texture, width, height); }
static gboolean gst_gl_deinterlace_greedyh_callback (GstGLFilter * filter, GstGLMemory * in_tex, gpointer user_data) { GstGLShader *shader; GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; GstGLFuncs *gl = context->gl_vtable; shader = gst_gl_deinterlace_get_fragment_shader (filter, "greedhy", greedyh_fragment_source); if (!shader) return FALSE; #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); if (G_LIKELY (deinterlace_filter->prev_tex != NULL)) { gl->ActiveTexture (GL_TEXTURE1); gst_gl_shader_set_uniform_1i (shader, "tex_prev", 1); gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (deinterlace_filter->prev_tex)); } gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (in_tex)); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "max_comb", 5.0f / 255.0f); gst_gl_shader_set_uniform_1f (shader, "motion_threshold", 25.0f / 255.0f); gst_gl_shader_set_uniform_1f (shader, "motion_sense", 30.0f / 255.0f); gst_gl_shader_set_uniform_1f (shader, "width", GST_VIDEO_INFO_WIDTH (&filter->out_info)); gst_gl_shader_set_uniform_1f (shader, "height", GST_VIDEO_INFO_HEIGHT (&filter->out_info)); gst_gl_filter_draw_fullscreen_quad (filter); /* we keep the previous buffer around so this is safe */ deinterlace_filter->prev_tex = in_tex; return TRUE; }
void gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "xray4"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "xray4", shader); } if (!gst_gl_shader_compile_and_check (shader, multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize multiply shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE2); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, effects->midtexture[2]); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1i (shader, "base", 2); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.5f); gst_gl_shader_set_uniform_1i (shader, "blend", 1); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_xray_step_two (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "xray1"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "xray1", shader); } if (!kernel_ready) { fill_gaussian_kernel (gauss_kernel, 7, 1.5); kernel_ready = TRUE; } if (!gst_gl_shader_compile_and_check (shader, hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize hconv7 shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1i (shader, "tex", 1); gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); gst_gl_shader_set_uniform_1f (shader, "width", width); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_square_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "square0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "square0", shader); } if (!gst_gl_shader_compile_and_check (shader, square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize square shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f); gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_xray_sobel_length (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_len"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_len", shader); } if (!gst_gl_shader_compile_and_check (shader, sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize seobel length shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1i (shader, "tex", 1); gst_gl_shader_set_uniform_1i (shader, "invert", TRUE); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void _draw_with_shader_cb (gint width, gint height, guint texture, gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = filter->context->gl_vtable; #if GST_GL_HAVE_OPENGL if (gst_gl_context_get_gl_api (filter->context) & GST_GL_API_OPENGL) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (filter->default_shader); gl->ActiveTexture (GL_TEXTURE1); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (filter->default_shader, "tex", 1); gst_gl_shader_set_uniform_1f (filter->default_shader, "width", width); gst_gl_shader_set_uniform_1f (filter->default_shader, "height", height); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void _callback_opengl (gint width, gint height, guint texture, gpointer stuff) { GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (stuff); GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = filter->context->gl_vtable; static GLfloat xrot = 0; static GLfloat yrot = 0; static GLfloat zrot = 0; /* *INDENT-OFF* */ const GLfloat v_vertices[] = { /*| Vertex | TexCoord |*/ /* front face */ 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 0.0, 1.0, /* back face */ -1.0, 1.0, 1.0, 0.0, 0.0, -1.0, -1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, /* right face */ -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 1.0, 0.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.0, 1.0, /* left face */ 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 1.0, 0.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 1.0, /* top face */ 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.0, 1.0, /* bottom face */ 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, }; /* *INDENT-ON* */ GLushort indices[] = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23 }; gl->Enable (GL_DEPTH_TEST); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->ClearColor (cube_filter->red, cube_filter->green, cube_filter->blue, 0.0); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl->MatrixMode (GL_PROJECTION); gluLookAt (0.0, 0.0, -6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); gl->MatrixMode (GL_MODELVIEW); gl->LoadIdentity (); // gl->Translatef (0.0f, 0.0f, -5.0f); gl->Rotatef (xrot, 1.0f, 0.0f, 0.0f); gl->Rotatef (yrot, 0.0f, 1.0f, 0.0f); gl->Rotatef (zrot, 0.0f, 0.0f, 1.0f); gl->ClientActiveTexture (GL_TEXTURE0); gl->EnableClientState (GL_TEXTURE_COORD_ARRAY); gl->EnableClientState (GL_VERTEX_ARRAY); gl->VertexPointer (3, GL_FLOAT, 5 * sizeof (float), v_vertices); gl->TexCoordPointer (2, GL_FLOAT, 5 * sizeof (float), &v_vertices[3]); gl->DrawElements (GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, indices); gl->DisableClientState (GL_TEXTURE_COORD_ARRAY); gl->DisableClientState (GL_VERTEX_ARRAY); gl->Disable (GL_DEPTH_TEST); xrot += 0.3f; yrot += 0.2f; zrot += 0.4f; }
void gst_gl_effects_luma_to_curve (GstGLEffects * effects, GstGLEffectsCurve curve, gint curve_index, gint width, gint height, GLuint texture) { GstGLShader *shader; GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "lumamap0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "lumamap0", shader); } if (!gst_gl_shader_compile_and_check (shader, luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize luma to curve shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); if (effects->curve[curve_index] == 0) { /* this parameters are needed to have a right, predictable, mapping */ gl->GenTextures (1, &effects->curve[curve_index]); gl->Enable (GL_TEXTURE_1D); gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); gl->TexImage1D (GL_TEXTURE_1D, 0, curve.bytes_per_pixel, curve.width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve.pixel_data); gl->Disable (GL_TEXTURE_1D); } gl->ActiveTexture (GL_TEXTURE2); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 2); gl->Disable (GL_TEXTURE_2D); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_1D); gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]); gst_gl_shader_set_uniform_1i (shader, "curve", 1); gl->Disable (GL_TEXTURE_1D); gst_gl_filter_draw_texture (filter, texture, width, height); }
//opengl scene, params: input texture (not the output filter->texture) static void gst_gl_deinterlace_callback (gint width, gint height, guint texture, gpointer stuff) { GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (stuff); GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; guint temp; GLfloat verts[] = { -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 }; GLfloat texcoords0[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; GLfloat texcoords1[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (deinterlace_filter->shader); if (G_UNLIKELY (deinterlace_filter->prev_tex == 0)) { gst_gl_context_gen_texture (GST_GL_BASE_FILTER (filter)->context, &deinterlace_filter->prev_tex, GST_VIDEO_INFO_FORMAT (&filter->out_info), GST_VIDEO_INFO_WIDTH (&filter->out_info), GST_VIDEO_INFO_HEIGHT (&filter->out_info)); } else { gl->ActiveTexture (GL_TEXTURE1); gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex_prev", 1); gl->BindTexture (GL_TEXTURE_2D, deinterlace_filter->prev_tex); } gl->ActiveTexture (GL_TEXTURE0); gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex", 0); gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb", 5.0f / 255.0f); gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold", 25.0f / 255.0f); gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense", 30.0f / 255.0f); gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "width", GST_VIDEO_INFO_WIDTH (&filter->out_info)); gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "height", GST_VIDEO_INFO_HEIGHT (&filter->out_info)); gl->ClientActiveTexture (GL_TEXTURE0); gl->EnableClientState (GL_TEXTURE_COORD_ARRAY); gl->EnableClientState (GL_VERTEX_ARRAY); gl->VertexPointer (2, GL_FLOAT, 0, &verts); gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords0); gl->ClientActiveTexture (GL_TEXTURE1); gl->EnableClientState (GL_TEXTURE_COORD_ARRAY); gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords1); gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4); gl->DisableClientState (GL_VERTEX_ARRAY); gl->DisableClientState (GL_TEXTURE_COORD_ARRAY); gl->ClientActiveTexture (GL_TEXTURE0); gl->DisableClientState (GL_TEXTURE_COORD_ARRAY); if (texture == filter->in_tex_id) { temp = filter->in_tex_id; filter->in_tex_id = deinterlace_filter->prev_tex; deinterlace_filter->prev_tex = temp; } else { deinterlace_filter->prev_tex = texture; } }