1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/*
PsychToolbox3/Source/Common/Screen/ScreenTypes.cpp
PLATFORMS: Windows
MacOS9
AUTHORS:
Allen Ingling awi Allen.Ingling@nyu.edu
Mario Kleiner mk mario.kleiner at tuebingen.mpg.de
HISTORY:
09/09/02 awi wrote it.
11/14/06 mk Rewritten to support 10bpc, float framebuffers.
01/06/07 mk Purged much of the bullshit it was.
DESCRIPTION:
functions which operate on types defined in ScreenTypes.h
TODO:
Most of this stuff should just die. It doesn't match how OpenGL works.
--> Done. Killed as much as possible.
*/
#include "Screen.h"
//accessors for PsychDepthType
void PsychInitDepthStruct(PsychDepthType *depth)
{
depth->numDepths = 0;
}
int PsychGetNumDepthsFromStruct(PsychDepthType *depth)
{
return(depth->numDepths);
}
int PsychGetValueFromDepthStruct(int index, PsychDepthType *depth)
{
if(depth->numDepths<=0 || index >= depth->numDepths){
PsychErrorExitMsg(PsychError_internal,"Invalid depth index passed to PsychGetDepthFromStruct()");
return(-1); //makes the compiler happy.
}
else
return(depth->depths[index]);
}
void PsychAddValueToDepthStruct(int value, PsychDepthType *depth)
{
int i;
//check to see if the value is already in the list
for(i=0;i<depth->numDepths;i++){
if(depth->depths[i] == value)
return;
}
//check to see if we have space left
if(depth->numDepths==kPsychMaxPossiblePixelDepths)
PsychErrorExitMsg(PsychError_internal,"Capacity of PsychDepthType struture exceeded");
//increment the count and store the new value
depth->depths[depth->numDepths++] = value;
}
/*
PsychDepthIsMember()
Accepts two depth structs and returns true if the one depth held by the first struct is among the one or more
depths within the second struct.
*/
psych_bool PsychIsMemberDepthStruct(PsychDepthType *depth, PsychDepthType *depthSet)
{
int numDepths, i;
numDepths=PsychGetNumDepthsFromStruct(depth);
if(numDepths>1)
PsychErrorExitMsg(PsychError_internal, "depth structure contains multiple depths");
else if(numDepths==0)
return(FALSE);
for(i=0;i<PsychGetNumDepthsFromStruct(depthSet);i++){
if(PsychGetValueFromDepthStruct(i,depthSet) == PsychGetValueFromDepthStruct(0,depth))
return(TRUE);
}
return(FALSE);
}
/*
PsychDepthCopy()
Accepts two depth structs which must both have been initialized and copies the contents of the second
depth to the first. Copy is cumulative.
*/
void PsychCopyDepthStruct(PsychDepthType *toDepth, PsychDepthType *fromDepth)
{
int i;
for(i=0;i<PsychGetNumDepthsFromStruct(fromDepth); i++)
PsychAddValueToDepthStruct(PsychGetValueFromDepthStruct(i,fromDepth), toDepth);
}
/*
PsychGetColorModeFromDepthStruct()
MK: This is a useless relict from old times. It always returns RGBA color mode,
the only mode we will ever support...
*/
PsychColorModeType PsychGetColorModeFromDepthStruct(PsychDepthType *depth)
{
(void) depth;
return(kPsychRGBAColor);
}
// Return the white value that really corresponds to white for a specific
// window, regardless of color depths and whatever...
double PsychGetWhiteValueFromWindow(PsychWindowRecordType* windowRecord)
{
return(fabs(windowRecord->colorRange));
}
/*
PsychLoadColorStruct(): Internal method to set colors, usually used to
setup default colors.
CAUTION: Only accepts double values, not int's, does not automatically
cast, but screws up insted due to the va_arg macro magic below...
PsychLoadColorStruct is polymorphic:
PsychLoadColorStruct(*color, kPsychIndexColor, int index)
PsychLoadColorStruct(*color, kPsychRGBColor, int r, int g, int b)
PsychLoadColorStruct(*color, kPsychRGBAColor, int r, int g, int b, int a)
*/
void PsychLoadColorStruct(PsychColorType *color, PsychColorModeType mode, ...)
{
va_list ap;
color->mode=mode;
va_start(ap, mode);
switch(mode){
case kPsychIndexColor:
color->value.index.i=va_arg(ap,double);
break;
case kPsychRGBColor:
color->value.rgb.r=va_arg(ap,double);
color->value.rgb.g=va_arg(ap,double);
color->value.rgb.b=va_arg(ap,double);
break;
case kPsychRGBAColor:
color->value.rgba.r=va_arg(ap,double);
color->value.rgba.g=va_arg(ap,double);
color->value.rgba.b=va_arg(ap,double);
color->value.rgba.a=va_arg(ap,double);
break;
case kPsychUnknownColor:
PsychErrorExitMsg(PsychError_internal,"Unspecified display mode");
}
va_end(ap);
}
/*
PsychCoerceColorMode()
Converts any color mode into RGBA mode, the only mode we need to handle with OpenGL,
regardless of display depth, number of color planes or whatever. The GL will always
accept the full thing and discard unwanted information internally in a much more fool
proof way than we could do it.
MK: Important change! We now assign DBL_MAX for unknown alphas and our color setup routine
(see SetGLColor()) maps DBL_MAX to the maximum supported value, which is simple, because
it always passes colors as doubles via glColor4d, so the maximum is always 1.0, irrespective
of display depth.
*/
void PsychCoerceColorMode(PsychColorType *color)
{
double index;
// Conversion from Index color?
if(color->mode==kPsychIndexColor) {
// Replicate index color value into RGB channels:
index=color->value.index.i;
color->value.rgba.r=index;
color->value.rgba.g=index;
color->value.rgba.b=index;
// Set alpha to our "maximum alpha" value:
color->value.rgba.a=DBL_MAX;
}
else {
// No, conversion from RGB?
if(color->mode==kPsychRGBColor) {
// Yes. Copy RGB channels over:
color->value.rgba.r=color->value.rgb.r;
color->value.rgba.g=color->value.rgb.g;
color->value.rgba.b=color->value.rgb.b;
// Set alpha to our "maximum alpha" value:
color->value.rgba.a=DBL_MAX;
}
// Third case would be from RGBA to RGBA, but that's
// a no-op.
}
// Always convert to RGBA color mode:
color->mode=kPsychRGBAColor;
}
|