4332f97b20581b92af08903670aee953aa54830e
[mesa.git] / src / mesa / drivers / beos / GLView.cpp
1 /* $Id: GLView.cpp,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 /*
29 * $Log: GLView.cpp,v $
30 * Revision 1.1 1999/08/19 00:55:41 jtg
31 * Initial revision
32 *
33 * Revision 1.7 1999/03/28 21:08:17 brianp
34 * updated SetBuffer driver function
35 *
36 * Revision 1.6 1999/02/14 03:44:37 brianp
37 * new copyright
38 *
39 * Revision 1.5 1999/02/11 03:50:57 brianp
40 * added CopySubBufferMESA()
41 *
42 * Revision 1.4 1999/02/06 17:44:59 brianp
43 * code clean-up and bug fixes
44 *
45 * Revision 1.3 1999/02/04 04:13:15 brianp
46 * implemented double buffering
47 *
48 * Revision 1.2 1999/02/03 04:23:28 brianp
49 * basic device driver functions now work (yeah!)
50 *
51 * Revision 1.1 1999/02/02 04:40:46 brianp
52 * Initial revision
53 */
54
55
56
57 #include <assert.h>
58 #include <stdio.h>
59 #include <GLView.h>
60 #include "../src/context.h"
61
62
63 // BeOS component ordering for B_RGBA32 bitmap format
64 #define BE_RCOMP 2
65 #define BE_GCOMP 1
66 #define BE_BCOMP 0
67 #define BE_ACOMP 3
68
69
70 //
71 // This object hangs off of the BGLView object. We have to use
72 // Be's BGLView class as-is to maintain binary compatibility (we
73 // can't add new members to it). Instead we just put all our data
74 // in this class and use BGLVIew::m_gc to point to it.
75 //
76 class AuxInfo
77 {
78 public:
79 AuxInfo();
80 ~AuxInfo();
81 void Init(BGLView *bglView, GLcontext *c, GLvisual *v, GLframebuffer *b);
82
83 void MakeCurrent();
84 void SwapBuffers() const;
85 void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const;
86
87 private:
88 AuxInfo(const AuxInfo &rhs); // copy constructor illegal
89 AuxInfo &operator=(const AuxInfo &rhs); // assignment oper. illegal
90
91 GLcontext *mContext;
92 GLvisual *mVisual;
93 GLframebuffer *mBuffer;
94
95 BGLView *mBGLView;
96 BBitmap *mBitmap;
97
98 GLubyte mColor[4]; // current color
99 GLuint mIndex; // current color index
100 GLubyte mClearColor[4]; // buffer clear color
101 GLuint mClearIndex; // buffer clear color index
102 GLint mBottom; // used for flipping Y coords
103 GLint mWidth, mHeight; // size of buffer
104
105 // Mesa device driver functions
106 static void UpdateState(GLcontext *ctx);
107 static void ClearIndex(GLcontext *ctx, GLuint index);
108 static void ClearColor(GLcontext *ctx, GLubyte r, GLubyte g,
109 GLubyte b, GLubyte a);
110 static GLbitfield ClearFront(GLcontext *ctx, GLbitfield mask,
111 GLboolean all, GLint x, GLint y,
112 GLint width, GLint height);
113 static GLbitfield ClearBack(GLcontext *ctx, GLbitfield mask,
114 GLboolean all, GLint x, GLint y,
115 GLint width, GLint height);
116 static void Index(GLcontext *ctx, GLuint index);
117 static void Color(GLcontext *ctx, GLubyte r, GLubyte g,
118 GLubyte b, GLubyte a);
119 static GLboolean SetBuffer(GLcontext *ctx, GLenum mode);
120 static void GetBufferSize(GLcontext *ctgx, GLuint *width,
121 GLuint *height);
122 static const GLubyte *GetString(GLcontext *ctx, GLenum name);
123
124 // Front-buffer functions
125 static void WriteRGBASpanFront(const GLcontext *ctx, GLuint n,
126 GLint x, GLint y,
127 CONST GLubyte rgba[][4],
128 const GLubyte mask[]);
129 static void WriteRGBSpanFront(const GLcontext *ctx, GLuint n,
130 GLint x, GLint y,
131 CONST GLubyte rgba[][3],
132 const GLubyte mask[]);
133 static void WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n,
134 GLint x, GLint y, const GLubyte mask[]);
135 static void WriteRGBAPixelsFront(const GLcontext *ctx, GLuint n,
136 const GLint x[], const GLint y[],
137 CONST GLubyte rgba[][4],
138 const GLubyte mask[]);
139 static void WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n,
140 const GLint x[], const GLint y[],
141 const GLubyte mask[]);
142 static void WriteCI32SpanFront(const GLcontext *ctx, GLuint n,
143 GLint x, GLint y,
144 const GLuint index[], const GLubyte mask[]);
145 static void WriteCI8SpanFront(const GLcontext *ctx, GLuint n,
146 GLint x, GLint y,
147 const GLubyte index[], const GLubyte mask[]);
148 static void WriteMonoCISpanFront(const GLcontext *ctx, GLuint n,
149 GLint x, GLint y, const GLubyte mask[]);
150 static void WriteCI32PixelsFront(const GLcontext *ctx,
151 GLuint n, const GLint x[], const GLint y[],
152 const GLuint index[], const GLubyte mask[]);
153 static void WriteMonoCIPixelsFront(const GLcontext *ctx, GLuint n,
154 const GLint x[], const GLint y[],
155 const GLubyte mask[]);
156 static void ReadCI32SpanFront(const GLcontext *ctx,
157 GLuint n, GLint x, GLint y, GLuint index[]);
158 static void ReadRGBASpanFront(const GLcontext *ctx, GLuint n,
159 GLint x, GLint y,
160 GLubyte rgba[][4]);
161 static void ReadCI32PixelsFront(const GLcontext *ctx,
162 GLuint n, const GLint x[], const GLint y[],
163 GLuint indx[], const GLubyte mask[]);
164 static void ReadRGBAPixelsFront(const GLcontext *ctx,
165 GLuint n, const GLint x[], const GLint y[],
166 GLubyte rgba[][4], const GLubyte mask[]);
167
168 // Back buffer functions
169 static void WriteRGBASpanBack(const GLcontext *ctx, GLuint n,
170 GLint x, GLint y,
171 CONST GLubyte rgba[][4],
172 const GLubyte mask[]);
173 static void WriteRGBSpanBack(const GLcontext *ctx, GLuint n,
174 GLint x, GLint y,
175 CONST GLubyte rgba[][3],
176 const GLubyte mask[]);
177 static void WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n,
178 GLint x, GLint y, const GLubyte mask[]);
179 static void WriteRGBAPixelsBack(const GLcontext *ctx, GLuint n,
180 const GLint x[], const GLint y[],
181 CONST GLubyte rgba[][4],
182 const GLubyte mask[]);
183 static void WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n,
184 const GLint x[], const GLint y[],
185 const GLubyte mask[]);
186 static void WriteCI32SpanBack(const GLcontext *ctx, GLuint n,
187 GLint x, GLint y,
188 const GLuint index[], const GLubyte mask[]);
189 static void WriteCI8SpanBack(const GLcontext *ctx, GLuint n, GLint x, GLint y,
190 const GLubyte index[], const GLubyte mask[]);
191 static void WriteMonoCISpanBack(const GLcontext *ctx, GLuint n,
192 GLint x, GLint y,
193 const GLubyte mask[]);
194 static void WriteCI32PixelsBack(const GLcontext *ctx,
195 GLuint n, const GLint x[], const GLint y[],
196 const GLuint index[], const GLubyte mask[]);
197 static void WriteMonoCIPixelsBack(const GLcontext *ctx,
198 GLuint n, const GLint x[], const GLint y[],
199 const GLubyte mask[]);
200 static void ReadCI32SpanBack(const GLcontext *ctx,
201 GLuint n, GLint x, GLint y, GLuint index[]);
202 static void ReadRGBASpanBack(const GLcontext *ctx, GLuint n,
203 GLint x, GLint y,
204 GLubyte rgba[][4]);
205 static void ReadCI32PixelsBack(const GLcontext *ctx,
206 GLuint n, const GLint x[], const GLint y[],
207 GLuint indx[], const GLubyte mask[]);
208 static void ReadRGBAPixelsBack(const GLcontext *ctx,
209 GLuint n, const GLint x[], const GLint y[],
210 GLubyte rgba[][4], const GLubyte mask[]);
211
212 };
213
214
215
216 AuxInfo::AuxInfo()
217 {
218 mContext = NULL;
219 mVisual = NULL;
220 mBuffer = NULL;
221 mBGLView = NULL;
222 mBitmap = NULL;
223 mClearColor[BE_RCOMP] = 0;
224 mClearColor[BE_GCOMP] = 0;
225 mClearColor[BE_BCOMP] = 0;
226 mClearColor[BE_ACOMP] = 0;
227 mClearIndex = 0;
228 mColor[BE_RCOMP] = 255;
229 mColor[BE_GCOMP] = 255;
230 mColor[BE_BCOMP] = 255;
231 mColor[BE_ACOMP] = 255;
232 mIndex = 1;
233 }
234
235
236 AuxInfo::~AuxInfo()
237 {
238
239 gl_destroy_visual(mVisual);
240 gl_destroy_framebuffer(mBuffer);
241 gl_destroy_context(mContext);
242 }
243
244
245 void AuxInfo::Init(BGLView *bglView, GLcontext *c, GLvisual *v, GLframebuffer *b)
246 {
247 mBGLView = bglView;
248 mContext = c;
249 mVisual = v;
250 mBuffer = b;
251 }
252
253
254 void AuxInfo::MakeCurrent()
255 {
256 UpdateState(mContext);
257 gl_make_current(mContext, mBuffer);
258 }
259
260
261 void AuxInfo::SwapBuffers() const
262 {
263 if (mBitmap) {
264 mBGLView->DrawBitmap(mBitmap, BPoint(0, 0));
265 }
266 }
267
268
269 void AuxInfo::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const
270 {
271 if (mBitmap) {
272 // Source bitmap and view's bitmap are same size.
273 // Source and dest rectangle are the same.
274 // Note (x,y) = (0,0) is the lower-left corner, have to flip Y
275 BRect srcAndDest;
276 srcAndDest.left = x;
277 srcAndDest.right = x + width - 1;
278 srcAndDest.bottom = mBottom - y;
279 srcAndDest.top = srcAndDest.bottom - height + 1;
280 mBGLView->DrawBitmap(mBitmap, srcAndDest, srcAndDest);
281 }
282 }
283
284
285 void AuxInfo::UpdateState( GLcontext *ctx )
286 {
287 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
288
289 assert(aux->mContext == ctx );
290
291 ctx->Driver.UpdateState = AuxInfo::UpdateState;
292 ctx->Driver.SetBuffer = AuxInfo::SetBuffer;
293 ctx->Driver.Color = AuxInfo::Color;
294 ctx->Driver.Index = AuxInfo::Index;
295 ctx->Driver.ClearIndex = AuxInfo::ClearIndex;
296 ctx->Driver.ClearColor = AuxInfo::ClearColor;
297 ctx->Driver.GetBufferSize = AuxInfo::GetBufferSize;
298 ctx->Driver.GetString = AuxInfo::GetString;
299
300 if (ctx->Color.DrawBuffer == GL_FRONT) {
301 /* read/write front buffer */
302 ctx->Driver.Clear = AuxInfo::ClearFront;
303 ctx->Driver.WriteRGBASpan = AuxInfo::WriteRGBASpanFront;
304 ctx->Driver.WriteRGBSpan = AuxInfo::WriteRGBSpanFront;
305 ctx->Driver.WriteRGBAPixels = AuxInfo::WriteRGBAPixelsFront;
306 ctx->Driver.WriteMonoRGBASpan = AuxInfo::WriteMonoRGBASpanFront;
307 ctx->Driver.WriteMonoRGBAPixels = AuxInfo::WriteMonoRGBAPixelsFront;
308 ctx->Driver.WriteCI32Span = AuxInfo::WriteCI32SpanFront;
309 ctx->Driver.WriteCI8Span = AuxInfo::WriteCI8SpanFront;
310 ctx->Driver.WriteMonoCISpan = AuxInfo::WriteMonoCISpanFront;
311 ctx->Driver.WriteCI32Pixels = AuxInfo::WriteCI32PixelsFront;
312 ctx->Driver.WriteMonoCIPixels = AuxInfo::WriteMonoCIPixelsFront;
313 ctx->Driver.ReadRGBASpan = AuxInfo::ReadRGBASpanFront;
314 ctx->Driver.ReadRGBAPixels = AuxInfo::ReadRGBAPixelsFront;
315 ctx->Driver.ReadCI32Span = AuxInfo::ReadCI32SpanFront;
316 ctx->Driver.ReadCI32Pixels = AuxInfo::ReadCI32PixelsFront;
317 }
318 else {
319 /* read/write back buffer */
320 ctx->Driver.Clear = AuxInfo::ClearBack;
321 ctx->Driver.WriteRGBASpan = AuxInfo::WriteRGBASpanBack;
322 ctx->Driver.WriteRGBSpan = AuxInfo::WriteRGBSpanBack;
323 ctx->Driver.WriteRGBAPixels = AuxInfo::WriteRGBAPixelsBack;
324 ctx->Driver.WriteMonoRGBASpan = AuxInfo::WriteMonoRGBASpanBack;
325 ctx->Driver.WriteMonoRGBAPixels = AuxInfo::WriteMonoRGBAPixelsBack;
326 ctx->Driver.WriteCI32Span = AuxInfo::WriteCI32SpanBack;
327 ctx->Driver.WriteCI8Span = AuxInfo::WriteCI8SpanBack;
328 ctx->Driver.WriteMonoCISpan = AuxInfo::WriteMonoCISpanBack;
329 ctx->Driver.WriteCI32Pixels = AuxInfo::WriteCI32PixelsBack;
330 ctx->Driver.WriteMonoCIPixels = AuxInfo::WriteMonoCIPixelsBack;
331 ctx->Driver.ReadRGBASpan = AuxInfo::ReadRGBASpanBack;
332 ctx->Driver.ReadRGBAPixels = AuxInfo::ReadRGBAPixelsBack;
333 ctx->Driver.ReadCI32Span = AuxInfo::ReadCI32SpanBack;
334 ctx->Driver.ReadCI32Pixels = AuxInfo::ReadCI32PixelsBack;
335 }
336 }
337
338
339 void AuxInfo::ClearIndex(GLcontext *ctx, GLuint index)
340 {
341 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
342 aux->mClearIndex = index;
343 }
344
345
346 void AuxInfo::ClearColor(GLcontext *ctx, GLubyte r, GLubyte g,
347 GLubyte b, GLubyte a)
348 {
349 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
350 aux->mClearColor[BE_RCOMP] = r;
351 aux->mClearColor[BE_GCOMP] = g;
352 aux->mClearColor[BE_BCOMP] = b;
353 aux->mClearColor[BE_ACOMP] = a;
354 assert(aux->mBGLView);
355 }
356
357
358 GLbitfield AuxInfo::ClearFront(GLcontext *ctx, GLbitfield mask,
359 GLboolean all, GLint x, GLint y,
360 GLint width, GLint height)
361 {
362 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
363 BGLView *bglview = aux->mBGLView;
364 assert(bglview);
365
366 bglview->SetHighColor(aux->mClearColor[BE_RCOMP],
367 aux->mClearColor[BE_GCOMP],
368 aux->mClearColor[BE_BCOMP],
369 aux->mClearColor[BE_ACOMP]);
370 bglview->SetLowColor(aux->mClearColor[BE_RCOMP],
371 aux->mClearColor[BE_GCOMP],
372 aux->mClearColor[BE_BCOMP],
373 aux->mClearColor[BE_ACOMP]);
374 if (all) {
375 BRect b = bglview->Bounds();
376 bglview->FillRect(b);
377 }
378 else {
379 // XXX untested
380 BRect b;
381 b.left = x;
382 b.right = x + width;
383 b.bottom = aux->mHeight - y - 1;
384 b.top = b.bottom - height;
385 bglview->FillRect(b);
386 }
387
388 // restore drawing color
389 bglview->SetHighColor(aux->mColor[BE_RCOMP],
390 aux->mColor[BE_GCOMP],
391 aux->mColor[BE_BCOMP],
392 aux->mColor[BE_ACOMP]);
393 bglview->SetLowColor(aux->mColor[BE_RCOMP],
394 aux->mColor[BE_GCOMP],
395 aux->mColor[BE_BCOMP],
396 aux->mColor[BE_ACOMP]);
397
398 return mask & (~GL_COLOR_BUFFER_BIT);
399 }
400
401
402 GLbitfield AuxInfo::ClearBack(GLcontext *ctx, GLbitfield mask,
403 GLboolean all, GLint x, GLint y,
404 GLint width, GLint height)
405 {
406 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
407 BGLView *bglview = aux->mBGLView;
408 assert(bglview);
409 BBitmap *bitmap = aux->mBitmap;
410 assert(bitmap);
411 GLuint *start = (GLuint *) bitmap->Bits();
412 const GLuint *clearPixelPtr = (const GLuint *) aux->mClearColor;
413 const GLuint clearPixel = *clearPixelPtr;
414
415 if (all) {
416 const int numPixels = aux->mWidth * aux->mHeight;
417 if (clearPixel == 0) {
418 memset(start, 0, numPixels * 4);
419 }
420 else {
421 for (int i = 0; i < numPixels; i++) {
422 start[i] = clearPixel;
423 }
424 }
425 }
426 else {
427 // XXX untested
428 start += y * aux->mWidth + x;
429 for (int i = 0; i < height; i++) {
430 for (int j = 0; j < width; j++) {
431 start[j] = clearPixel;
432 }
433 start += aux->mWidth;
434 }
435 }
436
437 return mask & (~GL_COLOR_BUFFER_BIT);
438 }
439
440
441 void AuxInfo::Index(GLcontext *ctx, GLuint index)
442 {
443 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
444 BGLView *bglview = aux->mBGLView;
445 assert(bglview);
446 aux->mIndex = index;
447 }
448
449
450 void AuxInfo::Color(GLcontext *ctx, GLubyte r, GLubyte g,
451 GLubyte b, GLubyte a)
452 {
453 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
454 BGLView *bglview = aux->mBGLView;
455 assert(bglview);
456 aux->mColor[BE_RCOMP] = r;
457 aux->mColor[BE_GCOMP] = g;
458 aux->mColor[BE_BCOMP] = b;
459 aux->mColor[BE_ACOMP] = a;
460 bglview->SetHighColor(r, g, b, a);
461 bglview->SetLowColor(r, g, b, a);
462 }
463
464 GLboolean AuxInfo::SetBuffer(GLcontext *ctx, GLenum buffer)
465 {
466 if (buffer == GL_FRONT_LEFT)
467 return GL_TRUE;
468 else if (buffer == GL_BACK_LEFT)
469 return GL_TRUE;
470 else
471 return GL_FALSE;
472 }
473
474 void AuxInfo::GetBufferSize(GLcontext *ctx, GLuint *width,
475 GLuint *height)
476 {
477 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
478 BGLView *bglview = aux->mBGLView;
479 assert(bglview);
480 BRect b = bglview->Bounds();
481 *width = (GLuint) (b.right - b.left + 1);
482 *height = (GLuint) (b.bottom - b.top + 1);
483 aux->mBottom = (GLint) b.bottom;
484
485 if (ctx->Visual->DBflag) {
486 if (*width != aux->mWidth || *height != aux->mHeight) {
487 // allocate new size of back buffer bitmap
488 if (aux->mBitmap)
489 delete aux->mBitmap;
490 BRect rect(0.0, 0.0, *width - 1, *height - 1);
491 aux->mBitmap = new BBitmap(rect, B_RGBA32);
492 }
493 }
494 else
495 {
496 aux->mBitmap = NULL;
497 }
498
499 aux->mWidth = *width;
500 aux->mHeight = *height;
501 }
502
503
504 const GLubyte *AuxInfo::GetString(GLcontext *ctx, GLenum name)
505 {
506 switch (name) {
507 case GL_RENDERER:
508 return (const GLubyte *) "Mesa BeOS";
509 default:
510 // Let core library handle all other cases
511 return NULL;
512 }
513 }
514
515
516 // Plot a pixel. (0,0) is upper-left corner
517 // This is only used when drawing to the front buffer.
518 static void Plot(BGLView *bglview, int x, int y)
519 {
520 // XXX There's got to be a better way!
521 BPoint p(x, y), q(x+1, y);
522 bglview->StrokeLine(p, q);
523 }
524
525
526 void AuxInfo::WriteRGBASpanFront(const GLcontext *ctx, GLuint n,
527 GLint x, GLint y,
528 CONST GLubyte rgba[][4],
529 const GLubyte mask[])
530 {
531 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
532 BGLView *bglview = aux->mBGLView;
533 assert(bglview);
534 int flippedY = aux->mBottom - y;
535 if (mask) {
536 for (GLuint i = 0; i < n; i++) {
537 if (mask[i]) {
538 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
539 Plot(bglview, x++, flippedY);
540 }
541 }
542 }
543 else {
544 for (GLuint i = 0; i < n; i++) {
545 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
546 Plot(bglview, x++, flippedY);
547 }
548 }
549 }
550
551 void AuxInfo::WriteRGBSpanFront(const GLcontext *ctx, GLuint n,
552 GLint x, GLint y,
553 CONST GLubyte rgba[][3],
554 const GLubyte mask[])
555 {
556 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
557 BGLView *bglview = aux->mBGLView;
558 assert(bglview);
559 int flippedY = aux->mBottom - y;
560 if (mask) {
561 for (GLuint i = 0; i < n; i++) {
562 if (mask[i]) {
563 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
564 Plot(bglview, x++, flippedY);
565 }
566 }
567 }
568 else {
569 for (GLuint i = 0; i < n; i++) {
570 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
571 Plot(bglview, x++, flippedY);
572 }
573 }
574 }
575
576 void AuxInfo::WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n,
577 GLint x, GLint y, const GLubyte mask[])
578 {
579 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
580 BGLView *bglview = aux->mBGLView;
581 assert(bglview);
582 int flippedY = aux->mBottom - y;
583 if (mask) {
584 for (GLuint i = 0; i < n; i++) {
585 if (mask[i]) {
586 Plot(bglview, x++, flippedY);
587 }
588 }
589 }
590 else {
591 for (GLuint i = 0; i < n; i++) {
592 Plot(bglview, x++, flippedY);
593 }
594 }
595 }
596
597 void AuxInfo::WriteRGBAPixelsFront(const GLcontext *ctx,
598 GLuint n, const GLint x[], const GLint y[],
599 CONST GLubyte rgba[][4],
600 const GLubyte mask[] )
601 {
602 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
603 BGLView *bglview = aux->mBGLView;
604 assert(bglview);
605 if (mask) {
606 for (GLuint i = 0; i < n; i++) {
607 if (mask[i]) {
608 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
609 Plot(bglview, x[i], aux->mBottom - y[i]);
610 }
611 }
612 }
613 else {
614 for (GLuint i = 0; i < n; i++) {
615 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
616 Plot(bglview, x[i], aux->mBottom - y[i]);
617 }
618 }
619 }
620
621
622 void AuxInfo::WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n,
623 const GLint x[], const GLint y[],
624 const GLubyte mask[])
625 {
626 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
627 BGLView *bglview = aux->mBGLView;
628 assert(bglview);
629 // plot points using current color
630 if (mask) {
631 for (GLuint i = 0; i < n; i++) {
632 if (mask[i]) {
633 Plot(bglview, x[i], aux->mBottom - y[i]);
634 }
635 }
636 }
637 else {
638 for (GLuint i = 0; i < n; i++) {
639 Plot(bglview, x[i], aux->mBottom - y[i]);
640 }
641 }
642 }
643
644
645 void AuxInfo::WriteCI32SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y,
646 const GLuint index[], const GLubyte mask[] )
647 {
648 // XXX to do
649 }
650
651 void AuxInfo::WriteCI8SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y,
652 const GLubyte index[], const GLubyte mask[] )
653 {
654 // XXX to do
655 }
656
657 void AuxInfo::WriteMonoCISpanFront( const GLcontext *ctx, GLuint n,
658 GLint x, GLint y, const GLubyte mask[] )
659 {
660 // XXX to do
661 }
662
663
664 void AuxInfo::WriteCI32PixelsFront( const GLcontext *ctx, GLuint n,
665 const GLint x[], const GLint y[],
666 const GLuint index[], const GLubyte mask[] )
667 {
668 // XXX to do
669 }
670
671 void AuxInfo::WriteMonoCIPixelsFront( const GLcontext *ctx, GLuint n,
672 const GLint x[], const GLint y[],
673 const GLubyte mask[] )
674 {
675 // XXX to do
676 }
677
678
679 void AuxInfo::ReadCI32SpanFront( const GLcontext *ctx,
680 GLuint n, GLint x, GLint y, GLuint index[] )
681 {
682 // XXX to do
683 }
684
685
686 void AuxInfo::ReadRGBASpanFront( const GLcontext *ctx, GLuint n,
687 GLint x, GLint y, GLubyte rgba[][4] )
688 {
689 // XXX to do
690 }
691
692
693 void AuxInfo::ReadCI32PixelsFront( const GLcontext *ctx,
694 GLuint n, const GLint x[], const GLint y[],
695 GLuint indx[], const GLubyte mask[] )
696 {
697 // XXX to do
698 }
699
700
701 void AuxInfo::ReadRGBAPixelsFront( const GLcontext *ctx,
702 GLuint n, const GLint x[], const GLint y[],
703 GLubyte rgba[][4], const GLubyte mask[] )
704 {
705 // XXX to do
706 }
707
708
709
710
711 void AuxInfo::WriteRGBASpanBack(const GLcontext *ctx, GLuint n,
712 GLint x, GLint y,
713 CONST GLubyte rgba[][4],
714 const GLubyte mask[])
715 {
716 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
717 BBitmap *bitmap = aux->mBitmap;
718 assert(bitmap);
719 int row = aux->mBottom - y;
720 GLubyte *pixel = (GLubyte *) bitmap->Bits() + (row * aux->mWidth + x) * 4;
721 if (mask) {
722 for (GLuint i = 0; i < n; i++) {
723 if (mask[i]) {
724 pixel[BE_RCOMP] = rgba[i][RCOMP];
725 pixel[BE_GCOMP] = rgba[i][GCOMP];
726 pixel[BE_BCOMP] = rgba[i][BCOMP];
727 pixel[BE_ACOMP] = rgba[i][ACOMP];
728 }
729 pixel += 4;
730 }
731 }
732 else {
733 for (GLuint i = 0; i < n; i++) {
734 pixel[BE_RCOMP] = rgba[i][RCOMP];
735 pixel[BE_GCOMP] = rgba[i][GCOMP];
736 pixel[BE_BCOMP] = rgba[i][BCOMP];
737 pixel[BE_ACOMP] = rgba[i][ACOMP];
738 pixel += 4;
739 }
740 }
741 }
742
743
744 void AuxInfo::WriteRGBSpanBack(const GLcontext *ctx, GLuint n,
745 GLint x, GLint y,
746 CONST GLubyte rgb[][3],
747 const GLubyte mask[])
748 {
749 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
750 BBitmap *bitmap = aux->mBitmap;
751 assert(bitmap);
752 int row = aux->mBottom - y;
753 GLubyte *pixel = (GLubyte *) bitmap->Bits() + (row * aux->mWidth + x) * 4;
754 if (mask) {
755 for (GLuint i = 0; i < n; i++) {
756 if (mask[i]) {
757 pixel[BE_RCOMP] = rgb[i][RCOMP];
758 pixel[BE_GCOMP] = rgb[i][GCOMP];
759 pixel[BE_BCOMP] = rgb[i][BCOMP];
760 pixel[BE_ACOMP] = 255;
761 }
762 pixel += 4;
763 }
764 }
765 else {
766 for (GLuint i = 0; i < n; i++) {
767 pixel[BE_RCOMP] = rgb[i][RCOMP];
768 pixel[BE_GCOMP] = rgb[i][GCOMP];
769 pixel[BE_BCOMP] = rgb[i][BCOMP];
770 pixel[BE_ACOMP] = 255;
771 pixel += 4;
772 }
773 }
774 }
775
776
777 void AuxInfo::WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n,
778 GLint x, GLint y, const GLubyte mask[])
779 {
780 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
781 BBitmap *bitmap = aux->mBitmap;
782 assert(bitmap);
783 int row = aux->mBottom - y;
784 GLuint *pixelPtr = (GLuint *) bitmap->Bits() + row * aux->mWidth + x;
785 const GLuint pixel = *((GLuint *) aux->mColor);
786 if (mask) {
787 for (GLuint i = 0; i < n; i++) {
788 if (mask[i])
789 *pixelPtr = pixel;
790 pixelPtr++;
791 }
792 }
793 else {
794 for (GLuint i = 0; i < n; i++) {
795 *pixelPtr++ = pixel;
796 }
797 }
798 }
799
800
801 void AuxInfo::WriteRGBAPixelsBack(const GLcontext *ctx,
802 GLuint n, const GLint x[], const GLint y[],
803 CONST GLubyte rgba[][4],
804 const GLubyte mask[] )
805 {
806 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
807 BBitmap *bitmap = aux->mBitmap;
808 assert(bitmap);
809 if (mask) {
810 for (GLuint i = 0; i < n; i++) {
811 if (mask[i]) {
812 GLubyte *pixel = (GLubyte *) bitmap->Bits()
813 + (aux->mBottom - y[i]) * bitmap->BytesPerRow() + x[i] * 4;
814 pixel[BE_RCOMP] = rgba[i][RCOMP];
815 pixel[BE_GCOMP] = rgba[i][GCOMP];
816 pixel[BE_BCOMP] = rgba[i][BCOMP];
817 pixel[BE_ACOMP] = rgba[i][ACOMP];
818 }
819 }
820 }
821 else {
822 for (GLuint i = 0; i < n; i++) {
823 GLubyte *pixel = (GLubyte *) bitmap->Bits()
824 + (aux->mBottom - y[i]) * bitmap->BytesPerRow() + x[i] * 4;
825 pixel[BE_RCOMP] = rgba[i][RCOMP];
826 pixel[BE_GCOMP] = rgba[i][GCOMP];
827 pixel[BE_BCOMP] = rgba[i][BCOMP];
828 pixel[BE_ACOMP] = rgba[i][ACOMP];
829 }
830 }
831 }
832
833
834 void AuxInfo::WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n,
835 const GLint x[], const GLint y[],
836 const GLubyte mask[])
837 {
838 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
839 BBitmap *bitmap = aux->mBitmap;
840 assert(bitmap);
841 const GLuint pixel = *((GLuint *) aux->mColor);
842 if (mask) {
843 for (GLuint i = 0; i < n; i++) {
844 if (mask[i]) {
845 GLuint *pixelPtr = (GLuint *) bitmap->Bits()
846 + (aux->mBottom - y[i]) * aux->mWidth + x[i];
847 *pixelPtr = pixel;
848 }
849 }
850 }
851 else {
852 for (GLuint i = 0; i < n; i++) {
853 GLuint *pixelPtr = (GLuint *) bitmap->Bits()
854 + (aux->mBottom - y[i]) * aux->mWidth + x[i];
855 *pixelPtr = pixel;
856 }
857 }
858 }
859
860
861 void AuxInfo::WriteCI32SpanBack( const GLcontext *ctx, GLuint n,
862 GLint x, GLint y,
863 const GLuint index[], const GLubyte mask[] )
864 {
865 // XXX to do
866 }
867
868 void AuxInfo::WriteCI8SpanBack( const GLcontext *ctx, GLuint n,
869 GLint x, GLint y,
870 const GLubyte index[], const GLubyte mask[] )
871 {
872 // XXX to do
873 }
874
875 void AuxInfo::WriteMonoCISpanBack( const GLcontext *ctx, GLuint n,
876 GLint x, GLint y, const GLubyte mask[] )
877 {
878 // XXX to do
879 }
880
881
882 void AuxInfo::WriteCI32PixelsBack( const GLcontext *ctx, GLuint n,
883 const GLint x[], const GLint y[],
884 const GLuint index[], const GLubyte mask[] )
885 {
886 // XXX to do
887 }
888
889 void AuxInfo::WriteMonoCIPixelsBack( const GLcontext *ctx, GLuint n,
890 const GLint x[], const GLint y[],
891 const GLubyte mask[] )
892 {
893 // XXX to do
894 }
895
896
897 void AuxInfo::ReadCI32SpanBack( const GLcontext *ctx,
898 GLuint n, GLint x, GLint y, GLuint index[] )
899 {
900 // XXX to do
901 }
902
903
904 void AuxInfo::ReadRGBASpanBack( const GLcontext *ctx, GLuint n,
905 GLint x, GLint y, GLubyte rgba[][4] )
906 {
907 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
908 const BBitmap *bitmap = aux->mBitmap;
909 assert(bitmap);
910 int row = aux->mBottom - y;
911 const GLubyte *pixel = (GLubyte *) bitmap->Bits()
912 + row * bitmap->BytesPerRow() + x * 4;
913 for (GLuint i = 0; i < n; i++) {
914 rgba[i][RCOMP] = pixel[BE_RCOMP];
915 rgba[i][GCOMP] = pixel[BE_GCOMP];
916 rgba[i][BCOMP] = pixel[BE_BCOMP];
917 rgba[i][ACOMP] = pixel[BE_ACOMP];
918 pixel += 4;
919 }
920 }
921
922
923 void AuxInfo::ReadCI32PixelsBack( const GLcontext *ctx,
924 GLuint n, const GLint x[], const GLint y[],
925 GLuint indx[], const GLubyte mask[] )
926 {
927 // XXX to do
928 }
929
930
931 void AuxInfo::ReadRGBAPixelsBack( const GLcontext *ctx,
932 GLuint n, const GLint x[], const GLint y[],
933 GLubyte rgba[][4], const GLubyte mask[] )
934 {
935 AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
936 const BBitmap *bitmap = aux->mBitmap;
937 assert(bitmap);
938 for (GLuint i = 0; i < n; i++) {
939 if (y[i] < aux->mHeight) {
940 const GLubyte *pixel = (const GLubyte *) bitmap->Bits()
941 + ((aux->mBottom - y[i]) * aux->mWidth + x[i]) * 4;
942 rgba[i][RCOMP] = pixel[BE_RCOMP];
943 rgba[i][GCOMP] = pixel[BE_GCOMP];
944 rgba[i][BCOMP] = pixel[BE_BCOMP];
945 rgba[i][ACOMP] = pixel[BE_ACOMP];
946 }
947 }
948 }
949
950
951
952
953 //------------------------------------------------------------------
954 // Public interface methods
955 //------------------------------------------------------------------
956
957
958 //
959 // Input: rect - initial rectangle
960 // name - window name
961 // resizingMode - example: B_FOLLOW_NONE
962 // mode - usually 0 ?
963 // options - Bitwise-OR of BGL_* tokens
964 //
965 BGLView::BGLView(BRect rect, char *name,
966 ulong resizingMode, ulong mode,
967 ulong options)
968 :BView(rect, name, resizingMode, mode)
969 {
970 const GLboolean rgbFlag = (options & BGL_RGB) == BGL_RGB;
971 const GLboolean alphaFlag = (options & BGL_ALPHA) == BGL_ALPHA;
972 const GLboolean dblFlag = (options & BGL_DOUBLE) == BGL_DOUBLE;
973 const GLboolean stereoFlag = false;
974 const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
975 const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
976 const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
977 const GLint index = (options & BGL_INDEX) ? 32 : 0;
978 const GLint red = (options & BGL_RGB) ? 8 : 0;
979 const GLint green = (options & BGL_RGB) ? 8 : 0;
980 const GLint blue = (options & BGL_RGB) ? 8 : 0;
981 const GLint alpha = (options & BGL_RGB) ? 8 : 0;
982
983 if (!rgbFlag) {
984 fprintf(stderr, "Mesa Warning: color index mode not supported\n");
985 }
986
987 // Allocate auxiliary data object
988 AuxInfo *aux = new AuxInfo;
989
990 // examine option flags and create gl_context struct
991 GLvisual *visual = gl_create_visual( rgbFlag, alphaFlag,
992 dblFlag, stereoFlag,
993 depth, stencil, accum, index,
994 red, green, blue, alpha);
995
996 // create core framebuffer
997 GLframebuffer *buffer = gl_create_framebuffer(visual);
998
999 // create core context
1000 const GLboolean direct = GL_TRUE;
1001 GLcontext *ctx = gl_create_context( visual, NULL, aux, direct );
1002
1003 aux->Init(this, ctx, visual, buffer );
1004
1005 // Hook aux data into BGLView object
1006 m_gc = aux;
1007 }
1008
1009
1010 BGLView::~BGLView()
1011 {
1012 printf("BGLView destructor\n");
1013 AuxInfo *aux = (AuxInfo *) m_gc;
1014 assert(aux);
1015 delete aux;
1016 }
1017
1018 void BGLView::LockGL()
1019 {
1020 AuxInfo *aux = (AuxInfo *) m_gc;
1021 assert(aux);
1022 aux->MakeCurrent();
1023 }
1024
1025 void BGLView::UnlockGL()
1026 {
1027 AuxInfo *aux = (AuxInfo *) m_gc;
1028 assert(aux);
1029 // Could call gl_make_current(NULL, NULL) but it would just
1030 // hinder performance
1031 }
1032
1033 void BGLView::SwapBuffers()
1034 {
1035 AuxInfo *aux = (AuxInfo *) m_gc;
1036 assert(aux);
1037 aux->SwapBuffers();
1038 }
1039
1040
1041 void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height)
1042 {
1043 AuxInfo *aux = (AuxInfo *) m_gc;
1044 assert(aux);
1045 aux->CopySubBuffer(x, y, width, height);
1046 }
1047
1048
1049 BView *BGLView::EmbeddedView()
1050 {
1051 // XXX to do
1052
1053 }
1054
1055 status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest)
1056 {
1057 // XXX to do
1058 }
1059
1060
1061 status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest)
1062 {
1063 // XXX to do
1064 }
1065
1066 void BGLView::ErrorCallback(GLenum errorCode)
1067 {
1068 // XXX to do
1069 }
1070
1071 void BGLView::Draw(BRect updateRect)
1072 {
1073 // printf("BGLView draw\n");
1074 // XXX to do
1075 }
1076
1077 void BGLView::AttachedToWindow()
1078 {
1079 BView::AttachedToWindow();
1080
1081 // don't paint window background white when resized
1082 SetViewColor(B_TRANSPARENT_32_BIT);
1083 }
1084
1085 void BGLView::AllAttached()
1086 {
1087 BView::AllAttached();
1088 // printf("BGLView AllAttached\n");
1089 }
1090
1091 void BGLView::DetachedFromWindow()
1092 {
1093 BView::DetachedFromWindow();
1094 }
1095
1096 void BGLView::AllDetached()
1097 {
1098 BView::AllDetached();
1099 // printf("BGLView AllDetached");
1100 }
1101
1102 void BGLView::FrameResized(float width, float height)
1103 {
1104 return BView::FrameResized(width, height);
1105 }
1106
1107 status_t BGLView::Perform(perform_code d, void *arg)
1108 {
1109 return BView::Perform(d, arg);
1110 }
1111
1112
1113 status_t BGLView::Archive(BMessage *data, bool deep) const
1114 {
1115 return BView::Archive(data, deep);
1116 }
1117
1118 void BGLView::MessageReceived(BMessage *msg)
1119 {
1120 BView::MessageReceived(msg);
1121 }
1122
1123 void BGLView::SetResizingMode(uint32 mode)
1124 {
1125 BView::SetResizingMode(mode);
1126 }
1127
1128 void BGLView::Show()
1129 {
1130 // printf("BGLView Show\n");
1131 BView::Show();
1132 }
1133
1134 void BGLView::Hide()
1135 {
1136 // printf("BGLView Hide\n");
1137 BView::Hide();
1138 }
1139
1140 BHandler *BGLView::ResolveSpecifier(BMessage *msg, int32 index,
1141 BMessage *specifier, int32 form,
1142 const char *property)
1143 {
1144 return BView::ResolveSpecifier(msg, index, specifier, form, property);
1145 }
1146
1147 status_t BGLView::GetSupportedSuites(BMessage *data)
1148 {
1149 return BView::GetSupportedSuites(data);
1150 }
1151
1152 void BGLView::DirectConnected( direct_buffer_info *info )
1153 {
1154 // XXX to do
1155 }
1156
1157 void BGLView::EnableDirectMode( bool enabled )
1158 {
1159 // XXX to do
1160 }
1161
1162
1163
1164 //---- private methods ----------
1165
1166 void BGLView::_ReservedGLView1() {}
1167 void BGLView::_ReservedGLView2() {}
1168 void BGLView::_ReservedGLView3() {}
1169 void BGLView::_ReservedGLView4() {}
1170 void BGLView::_ReservedGLView5() {}
1171 void BGLView::_ReservedGLView6() {}
1172 void BGLView::_ReservedGLView7() {}
1173 void BGLView::_ReservedGLView8() {}
1174
1175 #if 0
1176 BGLView::BGLView(const BGLView &v)
1177 : BView(v)
1178 {
1179 // XXX not sure how this should work
1180 printf("Warning BGLView::copy constructor not implemented\n");
1181 }
1182 #endif
1183
1184
1185 BGLView &BGLView::operator=(const BGLView &v)
1186 {
1187 printf("Warning BGLView::operator= not implemented\n");
1188 }
1189
1190 void BGLView::dither_front()
1191 {
1192 // no-op
1193 }
1194
1195 bool BGLView::confirm_dither()
1196 {
1197 // no-op
1198 return false;
1199 }
1200
1201 void BGLView::draw(BRect r)
1202 {
1203 // XXX no-op ???
1204 }
1205
1206 /* Direct Window stuff */
1207 void BGLView::drawScanline( int x1, int x2, int y, void *data )
1208 {
1209 // no-op
1210 }
1211
1212 void BGLView::scanlineHandler(struct rasStateRec *state,
1213 GLint x1, GLint x2)
1214 {
1215 // no-op
1216 }
1217
1218 void BGLView::lock_draw()
1219 {
1220 // no-op
1221 }
1222
1223 void BGLView::unlock_draw()
1224 {
1225 // no-op
1226 }
1227
1228 bool BGLView::validateView()
1229 {
1230 // no-op
1231 return true;
1232 }
1233