Trivial changes to add support for GL_ARB_point_sprite, which is a
subset of GL_NV_point_sprite (which was already supported).
This commit is contained in:
@@ -502,7 +502,7 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
|
|||||||
GL_POINT_SMOOTH);
|
GL_POINT_SMOOTH);
|
||||||
TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
|
TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
|
||||||
GL_POINT_SMOOTH);
|
GL_POINT_SMOOTH);
|
||||||
if (ctx->Extensions.NV_point_sprite) {
|
if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
|
||||||
TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
|
TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
|
||||||
GL_POINT_SPRITE_NV);
|
GL_POINT_SPRITE_NV);
|
||||||
}
|
}
|
||||||
@@ -998,7 +998,8 @@ _mesa_PopAttrib(void)
|
|||||||
_mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
|
_mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
|
||||||
point->Threshold);
|
point->Threshold);
|
||||||
}
|
}
|
||||||
if (ctx->Extensions.NV_point_sprite) {
|
if (ctx->Extensions.NV_point_sprite
|
||||||
|
|| ctx->Extensions.ARB_point_sprite) {
|
||||||
GLuint u;
|
GLuint u;
|
||||||
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
||||||
_mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
|
_mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
|
||||||
|
@@ -48,6 +48,12 @@
|
|||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK_EXTENSION2(EXT1, EXT2, CAP) \
|
||||||
|
if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \
|
||||||
|
_mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(0x%x)", \
|
||||||
|
state ? "Enable" : "Disable", CAP); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -834,7 +840,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state )
|
|||||||
|
|
||||||
/* GL_NV_point_sprite */
|
/* GL_NV_point_sprite */
|
||||||
case GL_POINT_SPRITE_NV:
|
case GL_POINT_SPRITE_NV:
|
||||||
CHECK_EXTENSION(NV_point_sprite, cap);
|
CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap);
|
||||||
if (ctx->Point.PointSprite == state)
|
if (ctx->Point.PointSprite == state)
|
||||||
return;
|
return;
|
||||||
FLUSH_VERTICES(ctx, _NEW_POINT);
|
FLUSH_VERTICES(ctx, _NEW_POINT);
|
||||||
|
@@ -48,6 +48,7 @@ static const struct {
|
|||||||
{ OFF, "GL_ARB_multitexture", F(ARB_multitexture) },
|
{ OFF, "GL_ARB_multitexture", F(ARB_multitexture) },
|
||||||
{ OFF, "GL_ARB_occlusion_query", F(ARB_occlusion_query) },
|
{ OFF, "GL_ARB_occlusion_query", F(ARB_occlusion_query) },
|
||||||
{ OFF, "GL_ARB_point_parameters", F(EXT_point_parameters) },
|
{ OFF, "GL_ARB_point_parameters", F(EXT_point_parameters) },
|
||||||
|
{ OFF, "GL_ARB_point_sprite", F(ARB_point_sprite) },
|
||||||
{ OFF, "GL_ARB_shadow", F(ARB_shadow) },
|
{ OFF, "GL_ARB_shadow", F(ARB_shadow) },
|
||||||
{ OFF, "GL_ARB_shadow_ambient", F(SGIX_shadow_ambient) },
|
{ OFF, "GL_ARB_shadow_ambient", F(SGIX_shadow_ambient) },
|
||||||
{ OFF, "GL_ARB_texture_border_clamp", F(ARB_texture_border_clamp) },
|
{ OFF, "GL_ARB_texture_border_clamp", F(ARB_texture_border_clamp) },
|
||||||
@@ -161,6 +162,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
|
|||||||
#if FEATURE_ARB_occlusion_query
|
#if FEATURE_ARB_occlusion_query
|
||||||
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
|
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
ctx->Extensions.ARB_point_sprite = GL_TRUE;
|
||||||
ctx->Extensions.ARB_shadow = GL_TRUE;
|
ctx->Extensions.ARB_shadow = GL_TRUE;
|
||||||
ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
|
ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
|
||||||
ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
|
ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
|
||||||
@@ -301,6 +303,7 @@ void
|
|||||||
_mesa_enable_1_5_extensions(GLcontext *ctx)
|
_mesa_enable_1_5_extensions(GLcontext *ctx)
|
||||||
{
|
{
|
||||||
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
|
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
|
||||||
|
ctx->Extensions.ARB_point_sprite = GL_TRUE;
|
||||||
ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
|
ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
|
||||||
ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
|
ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
|
||||||
ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
|
ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
|
||||||
|
@@ -59,34 +59,43 @@
|
|||||||
|
|
||||||
/* Check if named extension is enabled, if not generate error and return */
|
/* Check if named extension is enabled, if not generate error and return */
|
||||||
|
|
||||||
#define CHECK_EXTENSION_B(EXTNAME, PNAME) \
|
#define CHECK1(E1, str, PNAME) \
|
||||||
if (!ctx->Extensions.EXTNAME) { \
|
if (!ctx->Extensions.E1) { \
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, \
|
_mesa_error(ctx, GL_INVALID_VALUE, \
|
||||||
"glGetBooleanv(0x%x)", (int) PNAME); \
|
"glGet" str "v(0x%x)", (int) PNAME); \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK2(E1, E2, str, PNAME) \
|
||||||
|
if (!ctx->Extensions.E1 && !ctx->Extensions.E2) { \
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE, \
|
||||||
|
"glGet" str "v(0x%x)", (int) PNAME); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_EXTENSION_B(EXTNAME, PNAME) \
|
||||||
|
CHECK1(EXTNAME, "Boolean", PNAME )
|
||||||
|
|
||||||
#define CHECK_EXTENSION_I(EXTNAME, PNAME) \
|
#define CHECK_EXTENSION_I(EXTNAME, PNAME) \
|
||||||
if (!ctx->Extensions.EXTNAME) { \
|
CHECK1(EXTNAME, "Integer", PNAME )
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, \
|
|
||||||
"glGetIntegerv(0x%x)", (int) PNAME); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_EXTENSION_F(EXTNAME, PNAME) \
|
#define CHECK_EXTENSION_F(EXTNAME, PNAME) \
|
||||||
if (!ctx->Extensions.EXTNAME) { \
|
CHECK1(EXTNAME, "Float", PNAME )
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, \
|
|
||||||
"glGetFloatv(0x%x)", (int) PNAME); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_EXTENSION_D(EXTNAME, PNAME) \
|
#define CHECK_EXTENSION_D(EXTNAME, PNAME) \
|
||||||
if (!ctx->Extensions.EXTNAME) { \
|
CHECK1(EXTNAME, "Double", PNAME )
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, \
|
|
||||||
"glGetDoublev(0x%x)", (int) PNAME); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#define CHECK_EXTENSION2_B(EXT1, EXT2, PNAME) \
|
||||||
|
CHECK2(EXT1, EXT2, "Boolean", PNAME)
|
||||||
|
|
||||||
|
#define CHECK_EXTENSION2_I(EXT1, EXT2, PNAME) \
|
||||||
|
CHECK2(EXT1, EXT2, "Integer", PNAME)
|
||||||
|
|
||||||
|
#define CHECK_EXTENSION2_F(EXT1, EXT2, PNAME) \
|
||||||
|
CHECK2(EXT1, EXT2, "Float", PNAME)
|
||||||
|
|
||||||
|
#define CHECK_EXTENSION2_D(EXT1, EXT2, PNAME) \
|
||||||
|
CHECK2(EXT1, EXT2, "Double", PNAME)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1362,7 +1371,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
|
|||||||
|
|
||||||
/* GL_NV_point_sprite */
|
/* GL_NV_point_sprite */
|
||||||
case GL_POINT_SPRITE_NV:
|
case GL_POINT_SPRITE_NV:
|
||||||
CHECK_EXTENSION_B(NV_point_sprite, pname);
|
CHECK_EXTENSION2_B(NV_point_sprite, ARB_point_sprite, pname);
|
||||||
*params = ctx->Point.PointSprite;
|
*params = ctx->Point.PointSprite;
|
||||||
break;
|
break;
|
||||||
case GL_POINT_SPRITE_R_MODE_NV:
|
case GL_POINT_SPRITE_R_MODE_NV:
|
||||||
@@ -2903,11 +2912,11 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
|
|||||||
|
|
||||||
/* GL_NV_point_sprite */
|
/* GL_NV_point_sprite */
|
||||||
case GL_POINT_SPRITE_NV:
|
case GL_POINT_SPRITE_NV:
|
||||||
CHECK_EXTENSION_B(NV_point_sprite, pname);
|
CHECK_EXTENSION2_D(NV_point_sprite, ARB_point_sprite, pname);
|
||||||
*params = (GLdouble) ctx->Point.PointSprite;
|
*params = (GLdouble) ctx->Point.PointSprite;
|
||||||
break;
|
break;
|
||||||
case GL_POINT_SPRITE_R_MODE_NV:
|
case GL_POINT_SPRITE_R_MODE_NV:
|
||||||
CHECK_EXTENSION_B(NV_point_sprite, pname);
|
CHECK_EXTENSION_D(NV_point_sprite, pname);
|
||||||
*params = (GLdouble) ctx->Point.SpriteRMode;
|
*params = (GLdouble) ctx->Point.SpriteRMode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -4418,7 +4427,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
|
|||||||
|
|
||||||
/* GL_NV_point_sprite */
|
/* GL_NV_point_sprite */
|
||||||
case GL_POINT_SPRITE_NV:
|
case GL_POINT_SPRITE_NV:
|
||||||
CHECK_EXTENSION_F(NV_point_sprite, pname);
|
CHECK_EXTENSION2_F(NV_point_sprite, ARB_point_sprite, pname);
|
||||||
*params = (GLfloat) ctx->Point.PointSprite;
|
*params = (GLfloat) ctx->Point.PointSprite;
|
||||||
break;
|
break;
|
||||||
case GL_POINT_SPRITE_R_MODE_NV:
|
case GL_POINT_SPRITE_R_MODE_NV:
|
||||||
@@ -5971,7 +5980,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
|
|||||||
|
|
||||||
/* GL_NV_point_sprite */
|
/* GL_NV_point_sprite */
|
||||||
case GL_POINT_SPRITE_NV:
|
case GL_POINT_SPRITE_NV:
|
||||||
CHECK_EXTENSION_I(NV_point_sprite, pname);
|
CHECK_EXTENSION2_I(NV_point_sprite, ARB_point_sprite, pname);
|
||||||
*params = (GLint) ctx->Point.PointSprite;
|
*params = (GLint) ctx->Point.PointSprite;
|
||||||
break;
|
break;
|
||||||
case GL_POINT_SPRITE_R_MODE_NV:
|
case GL_POINT_SPRITE_R_MODE_NV:
|
||||||
@@ -6421,6 +6430,7 @@ _mesa_GetString( GLenum name )
|
|||||||
ctx->Extensions.EXT_stencil_wrap &&
|
ctx->Extensions.EXT_stencil_wrap &&
|
||||||
ctx->Extensions.SGIS_generate_mipmap) {
|
ctx->Extensions.SGIS_generate_mipmap) {
|
||||||
if (ctx->Extensions.ARB_occlusion_query &&
|
if (ctx->Extensions.ARB_occlusion_query &&
|
||||||
|
ctx->Extensions.ARB_point_sprite &&
|
||||||
ctx->Extensions.ARB_vertex_buffer_object &&
|
ctx->Extensions.ARB_vertex_buffer_object &&
|
||||||
ctx->Extensions.ARB_texture_non_power_of_two &&
|
ctx->Extensions.ARB_texture_non_power_of_two &&
|
||||||
ctx->Extensions.EXT_shadow_funcs) {
|
ctx->Extensions.EXT_shadow_funcs) {
|
||||||
|
@@ -559,7 +559,7 @@ struct gl_enable_attrib {
|
|||||||
GLboolean VertexProgram;
|
GLboolean VertexProgram;
|
||||||
GLboolean VertexProgramPointSize;
|
GLboolean VertexProgramPointSize;
|
||||||
GLboolean VertexProgramTwoSide;
|
GLboolean VertexProgramTwoSide;
|
||||||
/* GL_NV_point_sprite */
|
/* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
GLboolean PointSprite;
|
GLboolean PointSprite;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -846,9 +846,9 @@ struct gl_point_attrib {
|
|||||||
GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
|
GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
|
||||||
GLfloat Threshold; /**< GL_EXT_point_parameters */
|
GLfloat Threshold; /**< GL_EXT_point_parameters */
|
||||||
GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
|
GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
|
||||||
GLboolean PointSprite; /**< GL_NV_point_sprite */
|
GLboolean PointSprite; /**< GL_NV_point_sprite / GL_NV_point_sprite */
|
||||||
GLboolean CoordReplace[MAX_TEXTURE_UNITS]; /**< GL_NV_point_sprite */
|
GLboolean CoordReplace[MAX_TEXTURE_UNITS]; /**< GL_NV_point_sprite / GL_NV_point_sprite */
|
||||||
GLenum SpriteRMode; /**< GL_NV_point_sprite */
|
GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1739,6 +1739,7 @@ struct gl_extensions
|
|||||||
GLboolean ARB_multisample;
|
GLboolean ARB_multisample;
|
||||||
GLboolean ARB_multitexture;
|
GLboolean ARB_multitexture;
|
||||||
GLboolean ARB_occlusion_query;
|
GLboolean ARB_occlusion_query;
|
||||||
|
GLboolean ARB_point_sprite;
|
||||||
GLboolean ARB_shadow;
|
GLboolean ARB_shadow;
|
||||||
GLboolean ARB_texture_border_clamp;
|
GLboolean ARB_texture_border_clamp;
|
||||||
GLboolean ARB_texture_compression;
|
GLboolean ARB_texture_compression;
|
||||||
|
@@ -207,6 +207,10 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_POINT_SPRITE_R_MODE_NV:
|
case GL_POINT_SPRITE_R_MODE_NV:
|
||||||
|
/* This is one area where ARB_point_sprite and NV_point_sprite
|
||||||
|
* differ. In ARB_point_sprite the POINT_SPRITE_R_MODE is
|
||||||
|
* always ZERO. NV_point_sprite adds the S and R modes.
|
||||||
|
*/
|
||||||
if (ctx->Extensions.NV_point_sprite) {
|
if (ctx->Extensions.NV_point_sprite) {
|
||||||
GLenum value = (GLenum) params[0];
|
GLenum value = (GLenum) params[0];
|
||||||
if (value != GL_ZERO && value != GL_S && value != GL_R) {
|
if (value != GL_ZERO && value != GL_S && value != GL_R) {
|
||||||
@@ -260,9 +264,9 @@ void _mesa_init_point( GLcontext * ctx )
|
|||||||
ctx->Point.MinSize = 0.0;
|
ctx->Point.MinSize = 0.0;
|
||||||
ctx->Point.MaxSize = ctx->Const.MaxPointSize;
|
ctx->Point.MaxSize = ctx->Const.MaxPointSize;
|
||||||
ctx->Point.Threshold = 1.0;
|
ctx->Point.Threshold = 1.0;
|
||||||
ctx->Point.PointSprite = GL_FALSE; /* GL_NV_point_sprite */
|
ctx->Point.PointSprite = GL_FALSE; /* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite */
|
ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */
|
||||||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
|
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
|
||||||
ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_NV_point_sprite */
|
ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -534,8 +534,9 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (target == GL_POINT_SPRITE_NV) {
|
else if (target == GL_POINT_SPRITE_NV) {
|
||||||
/* GL_NV_point_sprite */
|
/* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
if (!ctx->Extensions.NV_point_sprite) {
|
if (!ctx->Extensions.NV_point_sprite
|
||||||
|
&& !ctx->Extensions.ARB_point_sprite) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -806,8 +807,9 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (target == GL_POINT_SPRITE_NV) {
|
else if (target == GL_POINT_SPRITE_NV) {
|
||||||
/* GL_NV_point_sprite */
|
/* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
if (!ctx->Extensions.NV_point_sprite) {
|
if (!ctx->Extensions.NV_point_sprite
|
||||||
|
&& !ctx->Extensions.ARB_point_sprite) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1020,8 +1022,9 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (target == GL_POINT_SPRITE_NV) {
|
else if (target == GL_POINT_SPRITE_NV) {
|
||||||
/* GL_NV_point_sprite */
|
/* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
if (!ctx->Extensions.NV_point_sprite) {
|
if (!ctx->Extensions.NV_point_sprite
|
||||||
|
&& !ctx->Extensions.ARB_point_sprite) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -199,7 +199,7 @@ _swrast_choose_point( GLcontext *ctx )
|
|||||||
|
|
||||||
if (ctx->RenderMode==GL_RENDER) {
|
if (ctx->RenderMode==GL_RENDER) {
|
||||||
if (ctx->Point.PointSprite) {
|
if (ctx->Point.PointSprite) {
|
||||||
/* GL_NV_point_sprite */
|
/* GL_ARB_point_sprite / GL_NV_point_sprite */
|
||||||
/* XXX this might not be good enough */
|
/* XXX this might not be good enough */
|
||||||
if (ctx->Point._Attenuated)
|
if (ctx->Point._Attenuated)
|
||||||
USE(atten_sprite_point);
|
USE(atten_sprite_point);
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
* SPECULAR = do separate specular color
|
* SPECULAR = do separate specular color
|
||||||
* LARGE = do points with diameter > 1 pixel
|
* LARGE = do points with diameter > 1 pixel
|
||||||
* ATTENUATE = compute point size attenuation
|
* ATTENUATE = compute point size attenuation
|
||||||
* SPRITE = GL_NV_point_sprite
|
* SPRITE = GL_ARB_point_sprite / GL_NV_point_sprite
|
||||||
*
|
*
|
||||||
* Notes: LARGE and ATTENUATE are exclusive of each other.
|
* Notes: LARGE and ATTENUATE are exclusive of each other.
|
||||||
* TEXTURE requires RGBA
|
* TEXTURE requires RGBA
|
||||||
|
Reference in New Issue
Block a user