1 /* 2 * Copyright (c) 2002-2008 LWJGL Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'LWJGL' nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package org.lwjgl.opengl; 33 34 /** 35 * This class describes pixel format properties for an OpenGL context. Instances 36 * of this class is used as arguments to Display.create(), Pbuffer.create() and 37 * AWTGLCanvas, to indicate minimum required properties. 38 * <p/> 39 * Instants of this class are immutable. An example of the expected way to set 40 * the PixelFormat property values is the following: 41 * <code>PixelFormat pf = new PixelFormat().withDepthBits(24).withSamples(4).withSRGB(true);</code> 42 * <p/> 43 * WARNING: Some pixel formats are known to cause troubles on certain buggy drivers. 44 * Example: Under Windows, specifying samples != 0 will enable the ARB 45 * pixel format selection path, which could trigger a crash. 46 * 47 * @author elias_naur@sourceforge.net 48 * @version $Revision$ 49 */ 50 public final class PixelFormat implements PixelFormatLWJGL { 51 52 /** 53 * The number of bits per pixel, exluding alpha. 54 * This parameter is ignored in Display.create(). 55 */ 56 private int bpp; 57 /** The number of alpha bits. */ 58 private int alpha; 59 /** The number of depth buffer bits */ 60 private int depth; 61 /** The number of stencil bits */ 62 private int stencil; 63 /** 64 * The number of samples to use in anti-aliasing. 65 * 0 means that anti-aliasing is disabled. 66 */ 67 private int samples; 68 /** 69 * The number of COLOR_SAMPLES_NV to use for Coverage Sample Anti-aliasing (CSAA). 70 * When this number is greater than 0, the {@code samples} property will be treated 71 * as if it were the COVERAGE_SAMPLES_NV property. 72 * <p/> 73 * This property is currently a no-op for the MacOS implementation. 74 */ 75 private int colorSamples; 76 /** The number of auxiliary buffers */ 77 private int num_aux_buffers; 78 /** The number of bits per pixel in the accumulation buffer */ 79 private int accum_bpp; 80 /** The number of alpha bits in the accumulation buffer */ 81 private int accum_alpha; 82 /** Whether this format requires a stereo buffer */ 83 private boolean stereo; 84 /** Whether this format specifies a floating point format */ 85 private boolean floating_point; 86 /** 87 * Whether this format specifies a packed floating point format (32 bit unsigned - R11F_G11F_B10F) 88 * This property is currently a no-op for the MacOS implementation. 89 */ 90 private boolean floating_point_packed; 91 /** 92 * Whether this format specifies an sRGB format 93 * This property is currently a no-op for the MacOS implementation. 94 */ 95 private boolean sRGB; 96 97 /** 98 * Default pixel format is minimum 8 bits depth, and no alpha 99 * nor stencil requirements. 100 */ PixelFormat()101 public PixelFormat() { 102 this(0, 8, 0); 103 } 104 PixelFormat(int alpha, int depth, int stencil)105 public PixelFormat(int alpha, int depth, int stencil) { 106 this(alpha, depth, stencil, 0); 107 } 108 PixelFormat(int alpha, int depth, int stencil, int samples)109 public PixelFormat(int alpha, int depth, int stencil, int samples) { 110 this(0, alpha, depth, stencil, samples); 111 } 112 PixelFormat(int bpp, int alpha, int depth, int stencil, int samples)113 public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples) { 114 this(bpp, alpha, depth, stencil, samples, 0, 0, 0, false); 115 } 116 PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo)117 public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo) { 118 this(bpp, alpha, depth, stencil, samples, num_aux_buffers, accum_bpp, accum_alpha, stereo, false); 119 } 120 PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo, boolean floating_point)121 public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo, boolean floating_point) { 122 this.bpp = bpp; 123 this.alpha = alpha; 124 this.depth = depth; 125 this.stencil = stencil; 126 127 this.samples = samples; 128 129 this.num_aux_buffers = num_aux_buffers; 130 131 this.accum_bpp = accum_bpp; 132 this.accum_alpha = accum_alpha; 133 134 this.stereo = stereo; 135 136 this.floating_point = floating_point; 137 this.floating_point_packed = false; 138 this.sRGB = false; 139 } 140 PixelFormat(final PixelFormat pf)141 private PixelFormat(final PixelFormat pf) { 142 this.bpp = pf.bpp; 143 this.alpha = pf.alpha; 144 this.depth = pf.depth; 145 this.stencil = pf.stencil; 146 147 this.samples = pf.samples; 148 this.colorSamples = pf.colorSamples; 149 150 this.num_aux_buffers = pf.num_aux_buffers; 151 152 this.accum_bpp = pf.accum_bpp; 153 this.accum_alpha = pf.accum_alpha; 154 155 this.stereo = pf.stereo; 156 157 this.floating_point = pf.floating_point; 158 this.floating_point_packed = pf.floating_point_packed; 159 this.sRGB = pf.sRGB; 160 } 161 getBitsPerPixel()162 public int getBitsPerPixel() { 163 return bpp; 164 } 165 166 /** 167 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new bits per pixel value. 168 * 169 * @param bpp the new bits per pixel value. 170 * 171 * @return the new PixelFormat 172 */ withBitsPerPixel(final int bpp)173 public PixelFormat withBitsPerPixel(final int bpp) { 174 if ( bpp < 0 ) 175 throw new IllegalArgumentException("Invalid number of bits per pixel specified: " + bpp); 176 177 final PixelFormat pf = new PixelFormat(this); 178 pf.bpp = bpp; 179 return pf; 180 } 181 getAlphaBits()182 public int getAlphaBits() { 183 return alpha; 184 } 185 186 /** 187 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new alpha bits value. 188 * 189 * @param alpha the new alpha bits value. 190 * 191 * @return the new PixelFormat 192 */ withAlphaBits(final int alpha)193 public PixelFormat withAlphaBits(final int alpha) { 194 if ( alpha < 0 ) 195 throw new IllegalArgumentException("Invalid number of alpha bits specified: " + alpha); 196 197 final PixelFormat pf = new PixelFormat(this); 198 pf.alpha = alpha; 199 return pf; 200 } 201 getDepthBits()202 public int getDepthBits() { 203 return depth; 204 } 205 206 /** 207 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new depth bits value. 208 * 209 * @param depth the new depth bits value. 210 * 211 * @return the new PixelFormat 212 */ withDepthBits(final int depth)213 public PixelFormat withDepthBits(final int depth) { 214 if ( depth < 0 ) 215 throw new IllegalArgumentException("Invalid number of depth bits specified: " + depth); 216 217 final PixelFormat pf = new PixelFormat(this); 218 pf.depth = depth; 219 return pf; 220 } 221 getStencilBits()222 public int getStencilBits() { 223 return stencil; 224 } 225 226 /** 227 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new stencil bits value. 228 * 229 * @param stencil the new stencil bits value. 230 * 231 * @return the new PixelFormat 232 */ withStencilBits(final int stencil)233 public PixelFormat withStencilBits(final int stencil) { 234 if ( stencil < 0 ) 235 throw new IllegalArgumentException("Invalid number of stencil bits specified: " + stencil); 236 237 final PixelFormat pf = new PixelFormat(this); 238 pf.stencil = stencil; 239 return pf; 240 } 241 getSamples()242 public int getSamples() { 243 return samples; 244 } 245 246 /** 247 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new samples value. 248 * 249 * @param samples the new samples value. 250 * 251 * @return the new PixelFormat 252 */ withSamples(final int samples)253 public PixelFormat withSamples(final int samples) { 254 if ( samples < 0 ) 255 throw new IllegalArgumentException("Invalid number of samples specified: " + samples); 256 257 final PixelFormat pf = new PixelFormat(this); 258 pf.samples = samples; 259 return pf; 260 } 261 262 /** 263 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new color samples values. 264 * A value greater than 0 is valid only if the {@code samples} property is also greater than 0. Additionally, the 265 * color samples value needs to be lower than or equal to the {@code samples} property. 266 * 267 * @param colorSamples the new color samples value. 268 * 269 * @return the new PixelFormat 270 */ withCoverageSamples(final int colorSamples)271 public PixelFormat withCoverageSamples(final int colorSamples) { 272 return withCoverageSamples(colorSamples, samples); 273 } 274 275 /** 276 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new color samples 277 * and coverage samples values. 278 * 279 * @param colorSamples the new color samples value. This value must be lower than or equal to the coverage samples value. 280 * @param coverageSamples the new coverage samples value. 281 * 282 * @return the new PixelFormat 283 */ withCoverageSamples(final int colorSamples, final int coverageSamples)284 public PixelFormat withCoverageSamples(final int colorSamples, final int coverageSamples) { 285 if ( coverageSamples < 0 || colorSamples < 0 || (coverageSamples == 0 && 0 < colorSamples) || coverageSamples < colorSamples ) 286 throw new IllegalArgumentException("Invalid number of coverage samples specified: " + coverageSamples + " - " + colorSamples); 287 288 final PixelFormat pf = new PixelFormat(this); 289 pf.samples = coverageSamples; 290 pf.colorSamples = colorSamples; 291 return pf; 292 } 293 getAuxBuffers()294 public int getAuxBuffers() { 295 return num_aux_buffers; 296 } 297 298 /** 299 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new auxiliary buffers value. 300 * 301 * @param num_aux_buffers the new auxiliary buffers value. 302 * 303 * @return the new PixelFormat 304 */ withAuxBuffers(final int num_aux_buffers)305 public PixelFormat withAuxBuffers(final int num_aux_buffers) { 306 if ( num_aux_buffers < 0 ) 307 throw new IllegalArgumentException("Invalid number of auxiliary buffers specified: " + num_aux_buffers); 308 309 final PixelFormat pf = new PixelFormat(this); 310 pf.num_aux_buffers = num_aux_buffers; 311 return pf; 312 } 313 getAccumulationBitsPerPixel()314 public int getAccumulationBitsPerPixel() { 315 return accum_bpp; 316 } 317 318 /** 319 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new bits per pixel in the accumulation buffer value. 320 * 321 * @param accum_bpp the new bits per pixel in the accumulation buffer value. 322 * 323 * @return the new PixelFormat 324 */ withAccumulationBitsPerPixel(final int accum_bpp)325 public PixelFormat withAccumulationBitsPerPixel(final int accum_bpp) { 326 if ( accum_bpp < 0 ) 327 throw new IllegalArgumentException("Invalid number of bits per pixel in the accumulation buffer specified: " + accum_bpp); 328 329 final PixelFormat pf = new PixelFormat(this); 330 pf.accum_bpp = accum_bpp; 331 return pf; 332 } 333 getAccumulationAlpha()334 public int getAccumulationAlpha() { 335 return accum_alpha; 336 } 337 338 /** 339 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new alpha bits in the accumulation buffer value. 340 * 341 * @param accum_alpha the new alpha bits in the accumulation buffer value. 342 * 343 * @return the new PixelFormat 344 */ withAccumulationAlpha(final int accum_alpha)345 public PixelFormat withAccumulationAlpha(final int accum_alpha) { 346 if ( accum_alpha < 0 ) 347 throw new IllegalArgumentException("Invalid number of alpha bits in the accumulation buffer specified: " + accum_alpha); 348 349 final PixelFormat pf = new PixelFormat(this); 350 pf.accum_alpha = accum_alpha; 351 return pf; 352 } 353 isStereo()354 public boolean isStereo() { 355 return stereo; 356 } 357 358 /** 359 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new stereo value. 360 * 361 * @param stereo the new stereo value. 362 * 363 * @return the new PixelFormat 364 */ withStereo(final boolean stereo)365 public PixelFormat withStereo(final boolean stereo) { 366 final PixelFormat pf = new PixelFormat(this); 367 pf.stereo = stereo; 368 return pf; 369 } 370 isFloatingPoint()371 public boolean isFloatingPoint() { 372 return floating_point; 373 } 374 375 /** 376 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new floating point value. 377 * If floating_point is true, floating_point_packed will be reset to false. 378 * 379 * @param floating_point the new floating point value. 380 * 381 * @return the new PixelFormat 382 */ withFloatingPoint(final boolean floating_point)383 public PixelFormat withFloatingPoint(final boolean floating_point) { 384 final PixelFormat pf = new PixelFormat(this); 385 pf.floating_point = floating_point; 386 if ( floating_point ) 387 pf.floating_point_packed = false; 388 return pf; 389 } 390 391 /** 392 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new packed floating point value. 393 * If floating_point_packed is true, floating_point will be reset to false. 394 * 395 * @param floating_point_packed the new packed floating point value. 396 * 397 * @return the new PixelFormat 398 */ withFloatingPointPacked(final boolean floating_point_packed)399 public PixelFormat withFloatingPointPacked(final boolean floating_point_packed) { 400 final PixelFormat pf = new PixelFormat(this); 401 pf.floating_point_packed = floating_point_packed; 402 if ( floating_point_packed ) 403 pf.floating_point = false; 404 return pf; 405 } 406 isSRGB()407 public boolean isSRGB() { 408 return sRGB; 409 } 410 411 /** 412 * Returns a new PixelFormat object with the same properties as this PixelFormat and the new sRGB value. 413 * 414 * @param sRGB the new floating point value. 415 * 416 * @return the new PixelFormat 417 */ withSRGB(final boolean sRGB)418 public PixelFormat withSRGB(final boolean sRGB) { 419 final PixelFormat pf = new PixelFormat(this); 420 pf.sRGB = sRGB; 421 return pf; 422 } 423 424 }