1bf215546Sopenharmony_ci/** 2bf215546Sopenharmony_ci * \file points.c 3bf215546Sopenharmony_ci * Point operations. 4bf215546Sopenharmony_ci */ 5bf215546Sopenharmony_ci 6bf215546Sopenharmony_ci/* 7bf215546Sopenharmony_ci * Mesa 3-D graphics library 8bf215546Sopenharmony_ci * 9bf215546Sopenharmony_ci * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 12bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 13bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 14bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 16bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 19bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 20bf215546Sopenharmony_ci * 21bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 28bf215546Sopenharmony_ci */ 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "glheader.h" 32bf215546Sopenharmony_ci#include "context.h" 33bf215546Sopenharmony_ci#include "macros.h" 34bf215546Sopenharmony_ci#include "points.h" 35bf215546Sopenharmony_ci#include "mtypes.h" 36bf215546Sopenharmony_ci#include "api_exec_decl.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistatic void 40bf215546Sopenharmony_ciupdate_point_size_set(struct gl_context *ctx) 41bf215546Sopenharmony_ci{ 42bf215546Sopenharmony_ci float size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); 43bf215546Sopenharmony_ci ctx->PointSizeIsSet = (size == 1.0 && ctx->Point.Size == 1.0) || ctx->Point._Attenuated; 44bf215546Sopenharmony_ci} 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci/** 47bf215546Sopenharmony_ci * Set current point size. 48bf215546Sopenharmony_ci * \param size point diameter in pixels 49bf215546Sopenharmony_ci * \sa glPointSize(). 50bf215546Sopenharmony_ci */ 51bf215546Sopenharmony_cistatic ALWAYS_INLINE void 52bf215546Sopenharmony_cipoint_size(struct gl_context *ctx, GLfloat size, bool no_error) 53bf215546Sopenharmony_ci{ 54bf215546Sopenharmony_ci if (ctx->Point.Size == size) 55bf215546Sopenharmony_ci return; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci if (!no_error && size <= 0.0F) { 58bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "glPointSize"); 59bf215546Sopenharmony_ci return; 60bf215546Sopenharmony_ci } 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT); 63bf215546Sopenharmony_ci ctx->Point.Size = size; 64bf215546Sopenharmony_ci update_point_size_set(ctx); 65bf215546Sopenharmony_ci} 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_civoid GLAPIENTRY 69bf215546Sopenharmony_ci_mesa_PointSize_no_error(GLfloat size) 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 72bf215546Sopenharmony_ci point_size(ctx, size, true); 73bf215546Sopenharmony_ci} 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_civoid GLAPIENTRY 77bf215546Sopenharmony_ci_mesa_PointSize( GLfloat size ) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 80bf215546Sopenharmony_ci point_size(ctx, size, false); 81bf215546Sopenharmony_ci} 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_civoid GLAPIENTRY 85bf215546Sopenharmony_ci_mesa_PointParameteri( GLenum pname, GLint param ) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci GLfloat p[3]; 88bf215546Sopenharmony_ci p[0] = (GLfloat) param; 89bf215546Sopenharmony_ci p[1] = p[2] = 0.0F; 90bf215546Sopenharmony_ci _mesa_PointParameterfv(pname, p); 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_civoid GLAPIENTRY 95bf215546Sopenharmony_ci_mesa_PointParameteriv( GLenum pname, const GLint *params ) 96bf215546Sopenharmony_ci{ 97bf215546Sopenharmony_ci GLfloat p[3]; 98bf215546Sopenharmony_ci p[0] = (GLfloat) params[0]; 99bf215546Sopenharmony_ci if (pname == GL_DISTANCE_ATTENUATION_EXT) { 100bf215546Sopenharmony_ci p[1] = (GLfloat) params[1]; 101bf215546Sopenharmony_ci p[2] = (GLfloat) params[2]; 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci _mesa_PointParameterfv(pname, p); 104bf215546Sopenharmony_ci} 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_civoid GLAPIENTRY 108bf215546Sopenharmony_ci_mesa_PointParameterf( GLenum pname, GLfloat param) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci GLfloat p[3]; 111bf215546Sopenharmony_ci p[0] = param; 112bf215546Sopenharmony_ci p[1] = p[2] = 0.0F; 113bf215546Sopenharmony_ci _mesa_PointParameterfv(pname, p); 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_civoid GLAPIENTRY 118bf215546Sopenharmony_ci_mesa_PointParameterfv( GLenum pname, const GLfloat *params) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci switch (pname) { 123bf215546Sopenharmony_ci case GL_DISTANCE_ATTENUATION_EXT: 124bf215546Sopenharmony_ci if (TEST_EQ_3V(ctx->Point.Params, params)) 125bf215546Sopenharmony_ci return; 126bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM | 127bf215546Sopenharmony_ci _NEW_TNL_SPACES, GL_POINT_BIT); 128bf215546Sopenharmony_ci COPY_3V(ctx->Point.Params, params); 129bf215546Sopenharmony_ci ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0F || 130bf215546Sopenharmony_ci ctx->Point.Params[1] != 0.0F || 131bf215546Sopenharmony_ci ctx->Point.Params[2] != 0.0F); 132bf215546Sopenharmony_ci update_point_size_set(ctx); 133bf215546Sopenharmony_ci break; 134bf215546Sopenharmony_ci case GL_POINT_SIZE_MIN_EXT: 135bf215546Sopenharmony_ci if (params[0] < 0.0F) { 136bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, 137bf215546Sopenharmony_ci "glPointParameterf[v]{EXT,ARB}(param)" ); 138bf215546Sopenharmony_ci return; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci if (ctx->Point.MinSize == params[0]) 141bf215546Sopenharmony_ci return; 142bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT); 143bf215546Sopenharmony_ci ctx->Point.MinSize = params[0]; 144bf215546Sopenharmony_ci break; 145bf215546Sopenharmony_ci case GL_POINT_SIZE_MAX_EXT: 146bf215546Sopenharmony_ci if (params[0] < 0.0F) { 147bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, 148bf215546Sopenharmony_ci "glPointParameterf[v]{EXT,ARB}(param)" ); 149bf215546Sopenharmony_ci return; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci if (ctx->Point.MaxSize == params[0]) 152bf215546Sopenharmony_ci return; 153bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT); 154bf215546Sopenharmony_ci ctx->Point.MaxSize = params[0]; 155bf215546Sopenharmony_ci break; 156bf215546Sopenharmony_ci case GL_POINT_FADE_THRESHOLD_SIZE_EXT: 157bf215546Sopenharmony_ci if (params[0] < 0.0F) { 158bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, 159bf215546Sopenharmony_ci "glPointParameterf[v]{EXT,ARB}(param)" ); 160bf215546Sopenharmony_ci return; 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci if (ctx->Point.Threshold == params[0]) 163bf215546Sopenharmony_ci return; 164bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT); 165bf215546Sopenharmony_ci ctx->Point.Threshold = params[0]; 166bf215546Sopenharmony_ci break; 167bf215546Sopenharmony_ci case GL_POINT_SPRITE_COORD_ORIGIN: 168bf215546Sopenharmony_ci /* GL_POINT_SPRITE_COORD_ORIGIN was added to point sprites when the 169bf215546Sopenharmony_ci * extension was merged into OpenGL 2.0. 170bf215546Sopenharmony_ci */ 171bf215546Sopenharmony_ci if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20) 172bf215546Sopenharmony_ci || ctx->API == API_OPENGL_CORE) { 173bf215546Sopenharmony_ci GLenum value = (GLenum) params[0]; 174bf215546Sopenharmony_ci if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) { 175bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 176bf215546Sopenharmony_ci "glPointParameterf[v]{EXT,ARB}(param)"); 177bf215546Sopenharmony_ci return; 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci if (ctx->Point.SpriteOrigin == value) 180bf215546Sopenharmony_ci return; 181bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT); 182bf215546Sopenharmony_ci ctx->Point.SpriteOrigin = value; 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci else { 185bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 186bf215546Sopenharmony_ci "glPointParameterf[v]{EXT,ARB}(pname)"); 187bf215546Sopenharmony_ci return; 188bf215546Sopenharmony_ci } 189bf215546Sopenharmony_ci break; 190bf215546Sopenharmony_ci default: 191bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, 192bf215546Sopenharmony_ci "glPointParameterf[v]{EXT,ARB}(pname)" ); 193bf215546Sopenharmony_ci return; 194bf215546Sopenharmony_ci } 195bf215546Sopenharmony_ci} 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci/** 200bf215546Sopenharmony_ci * Initialize the context point state. 201bf215546Sopenharmony_ci * 202bf215546Sopenharmony_ci * \param ctx GL context. 203bf215546Sopenharmony_ci * 204bf215546Sopenharmony_ci * Initializes __struct gl_contextRec::Point and point related constants in 205bf215546Sopenharmony_ci * __struct gl_contextRec::Const. 206bf215546Sopenharmony_ci */ 207bf215546Sopenharmony_civoid 208bf215546Sopenharmony_ci_mesa_init_point(struct gl_context *ctx) 209bf215546Sopenharmony_ci{ 210bf215546Sopenharmony_ci ctx->Point.SmoothFlag = GL_FALSE; 211bf215546Sopenharmony_ci ctx->Point.Size = 1.0; 212bf215546Sopenharmony_ci ctx->Point.Params[0] = 1.0; 213bf215546Sopenharmony_ci ctx->Point.Params[1] = 0.0; 214bf215546Sopenharmony_ci ctx->Point.Params[2] = 0.0; 215bf215546Sopenharmony_ci ctx->Point._Attenuated = GL_FALSE; 216bf215546Sopenharmony_ci ctx->Point.MinSize = 0.0; 217bf215546Sopenharmony_ci ctx->Point.MaxSize 218bf215546Sopenharmony_ci = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA); 219bf215546Sopenharmony_ci ctx->Point.Threshold = 1.0; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci /* Page 403 (page 423 of the PDF) of the OpenGL 3.0 spec says: 222bf215546Sopenharmony_ci * 223bf215546Sopenharmony_ci * "Non-sprite points (section 3.4) - Enable/Disable targets 224bf215546Sopenharmony_ci * POINT_SMOOTH and POINT_SPRITE, and all associated state. Point 225bf215546Sopenharmony_ci * rasterization is always performed as though POINT_SPRITE were 226bf215546Sopenharmony_ci * enabled." 227bf215546Sopenharmony_ci * 228bf215546Sopenharmony_ci * In a core context, the state will default to true, and the setters and 229bf215546Sopenharmony_ci * getters are disabled. 230bf215546Sopenharmony_ci */ 231bf215546Sopenharmony_ci ctx->Point.PointSprite = (ctx->API == API_OPENGL_CORE || 232bf215546Sopenharmony_ci ctx->API == API_OPENGLES2); 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */ 235bf215546Sopenharmony_ci ctx->Point.CoordReplace = 0; /* GL_ARB_point_sprite */ 236bf215546Sopenharmony_ci} 237