File: ScreenTypes.c

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (212 lines) | stat: -rw-r--r-- 6,264 bytes parent folder | download | duplicates (5)
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;
}