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