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