Compare commits

...

200 Commits

Author SHA1 Message Date
Julien Cristau
99f159339e Prepare changelog for upload 2009-04-01 20:25:25 +02:00
Timo Aaltonen
4830fab603 update the changelog. 2009-03-30 10:41:39 +03:00
Timo Aaltonen
1e142bf63d Merge commit 'mesa_7_4' into debian-experimental 2009-03-30 10:38:45 +03:00
Brian Paul
bf1e6581a5 docs: set 7.4 release date 2009-03-27 18:57:39 -06:00
Brian Paul
80ec7843bc mesa: set VERSION=7.4 2009-03-27 18:57:23 -06:00
Brian Paul
366d6e8cd1 mesa: set version to 7.4 2009-03-27 18:57:07 -06:00
Ian Romanick
63ed288396 intel: Add extra, stronger flushes around CopyTexSubImage blits 2009-03-27 15:22:27 -07:00
Eric Anholt
88ce34f400 swrast: Add support for x8r8g8b8 fbconfig.
This lets swrast produce an fbconfig suitable for the root visual now that
the server's not allowing mismatched fbconfigs.
(cherry picked from commit 529d1d720e)
2009-03-27 15:20:09 -07:00
Ian Romanick
f535de8721 Mark current bits as 2009Q1-RC2 for Intel driver. 2009-03-26 15:32:29 -07:00
Eric Anholt
1db913f687 i965: Fix glFrontFacing in twoside GLSL demo.
This also cuts instructions by just using the existing bit in the payload
rather than computing it from the determinant in the SF unit and passing it
as a varying down to the WM.  Something still goes wrong with getting the
backface color right, but a simpler shader appears to get the right result.
(cherry picked from commit 699db6d842)
2009-03-26 15:15:51 -07:00
Eric Anholt
0e5d1f43af i965: Fix fog coordinate g,b,a values when glFrontFacing isn't used.
Previously, we would sample (f,glFrontFacing,undef,undef) instead of the
(f,0,0,1) that fragment.fogcoord is supposed to return.  Due to
glFrontFacing's presence in FOGC.y, we'll still give bad results there when
glFrontFacing is used.

Bug #19122, piglit testcase fp-fog.
(cherry picked from commit 411d913cce)
2009-03-26 15:15:27 -07:00
Eric Anholt
09c587ae55 i965: Clean up a bit of mess with unneeded variables in emit_interp.
(cherry picked from commit b013f945d8)
2009-03-26 15:15:14 -07:00
Brian Paul
775d8431e9 i965: separate emit_op() and emit_tex_op() functions
(cherry picked from commit a79186e29e)
2009-03-26 15:14:56 -07:00
Brian Paul
3217ea8a1d i965: minor clean-up, comments, etc.
(cherry picked from commit 9e7903e492)
2009-03-26 15:14:22 -07:00
Brian Paul
00aea5853d docs: mention Solaris updates in release notes 2009-03-25 21:08:21 -06:00
Brian Paul
20d34b50b5 mesa: bump version to 7.4 rc2 2009-03-25 21:06:41 -06:00
Alan Coopersmith
9cff0acb36 define __builtin_expect for non-gcc compilers in two more glx files
Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
2009-03-25 16:26:03 -07:00
Alan Coopersmith
791b59493f mklib improvements for Solaris
Move flags for linking standard C/C++ libraries from configure.ac to mklib
Use -norunpath flag when linking with Sun C++ compiler
Convert mklib -exports list into a linker mapfile
Set FINAL_LIBS correctly when -noprefix is used

Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
2009-03-25 16:26:02 -07:00
Michel Dänzer
7dff7029fa Revert "dri2: Avoid round-tripping on DRI2GetBuffers for the same set of buffers."
This scheme breaks when the display connection doesn't receive ConfigureNotify
events. This caused reporoducible problems (cropped / misplaced output) when
starting a 3D application in a guest operating system in VMware Workstation.

This reverts commit dd1c68f151.

Conflicts:

	src/glx/x11/dri2_glx.c
(cherry picked from commit 11da7e02aa)
2009-03-25 15:55:20 +01:00
Brian Paul
f8fd9bc46b docs: update glext.h to version 48 2009-03-25 08:35:15 -06:00
Brian Paul
53f0e141c0 gl: update include/GL/glext.h to version 48 2009-03-25 08:35:02 -06:00
Julien Cristau
af3c568475 Prepare changelog for upload 2009-03-25 11:34:58 +01:00
Julien Cristau
7d01429512 Build-depend on linux-libc-dev >= 2.6.29 on linux archs.
The 2.6.28 kernel headers miss some compat defines.
2009-03-25 01:51:02 +01:00
Brian Paul
14a794300e demos: add LDFLAGS for corender target, bug 20844
(cherry picked from commit c4c4358e08)
2009-03-24 16:09:23 -06:00
Eric Anholt
912ec292c1 i965: Fix occlusion query when no other WM state updates occur.
Turns out that XXX comment was important.  We weren't flagging the WM to
re-update with the statistics enable, so we got zeroes out of our query.

Bug #20740, fixes piglit occlusion_query test.

Signed-off-by: Eric Anholt <eric@anholt.net>
(cherry picked from commit c0d6e07909)
2009-03-23 12:49:31 -07:00
Tom Fogal
e814b5ae2f mesa: fix _glxapi_get_proc_address() for mangled names
(cherry picked from commit 7399d56ec6)
2009-03-23 12:49:13 -07:00
Brian Paul
0fea05915a glapi: update find_entry() for mangled names
(cherry picked from commit 4447fddc82)
2009-03-23 12:49:05 -07:00
Brian Paul
dfa44f0ff9 mesa: regenerated gl_mange.h file
(cherry picked from commit fe0ccf323d)
2009-03-23 12:48:56 -07:00
Julien Cristau
8d088cd34f update changelog 2009-03-23 17:25:04 +01:00
Julien Cristau
094d627885 Merge tag 'mesa_7_4_rc1' into debian-experimental 2009-03-23 17:21:26 +01:00
Brian Paul
f850ff2bcc mesa: remove unused 'out' label 2009-03-23 08:27:00 -06:00
Brian Paul
66f972ab55 Add Solaris to OS'es using PROT_EXEC mmap() to get executable heap space
Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>

(cherry picked from master, commit a06dd4de87)
2009-03-23 08:18:48 -06:00
Brian Paul
17db2db9dc docs: prep for 7.4 release 2009-03-20 17:34:54 -06:00
Brian Paul
dba79af9bc mesa: prep for 7.4-rc1 release 2009-03-20 17:26:04 -06:00
Brian Paul
b009a32bf4 r300: don't crash on sw tcl hw if point size vertex attrib is sent
(cherry picked from master, commit 005ad1a71d)
2009-03-20 08:49:39 -06:00
Brian Paul
7122490982 mesa: avoid setting texObj->_Complete = GL_FALSE when there's no state change
Avoid a little bit of unneeded state validation and fixes a bug where the
texture complete flags was set to false, but we didn't signal _NEW_TEXTURE.

Fixes piglit tex1d-2dborder failure.
(cherry picked from commit aad3f546a0)
2009-03-18 14:47:47 -07:00
Brian Paul
6ada1d47d9 mesa: add no-change testing for a few more texture parameters
(cherry picked from commit 37c768b36a)
2009-03-18 10:54:09 -07:00
Robert Ellison
55865335f4 i965: fix polygon stipple when rendering to FBO
The polygon stipple pattern, like the viewport and the
polygon face orientation, must be inverted on the i965
when rendering to a FBO (which itself has an inverted pixel
coordinate system compared to raw Mesa).

In addition, the polygon stipple offset, which orients
the stipple to the window system, disappears when rendering
to an FBO (because the window system offset doesn't apply,
and there's no associated FBO offset).

With these fixes, the conform triangle and polygon stipple
tests pass when rendering to texture.
(cherry picked from commit 29309b45b0)
2009-03-18 10:47:24 -07:00
Robert Ellison
918e5221ef i965: fix polygon face orientation when rendering to FBO
In the i965, the FBO coordinate system is inverted from the standard
OpenGL/Mesa coordinate system; that means that the viewport and the
polygon face orientation have to be inverted if rendering to a FBO.

The viewport was already being handled correctly; but polygon face
was not.  This caused a conform failure when rendering to texture with
two-sided lighting enabled.

This fixes the problem in the i965 driver, and adds to the comment about
the gl_framebuffer "Name" field so that this isn't a surprise to other
driver writers.
(cherry picked from commit 6dceeb2eb8)
2009-03-18 10:47:24 -07:00
Brian Paul
9feb26584a swrast: use better _swrast_compute_lambda() function
The MAX-based function can produce values that are non-monotonic for a span
which causes glitches in texture filtering.  The sqrt-based one avoids that.

This is perhaps slightly slower than before, but the difference
probably isn't noticable given we're doing software mipmap filtering.

Issue reported by Nir Radian <nirr@horizonsemi.com>

(cherry picked from master, commit c334ce273e)
2009-03-17 10:34:45 -06:00
Ian Romanick
a8528a2e86 Mark current bits as 2009Q1-RC1 for Intel driver. 2009-03-16 13:39:32 -07:00
Brian Paul
119360cccd i965: init dest reg CondMask = COND_TR (the proper default)
Plus fix up a debug printf.
(cherry picked from commit 20f49252e1)
2009-03-13 17:38:40 -07:00
Brian Paul
ac2216542d glsl: fix vec4_texp_rect IR code (need projective version) (cherry picked from commit ad2cfa4199) 2009-03-13 17:38:40 -07:00
Brian Paul
37e5c057f1 i965: check if we run out of GRF/temp registers
Before this change we would up emitting instructions with invalid register
numbers.  This typically (but not always) hung the GPU.  For now, just
prevent emitting bad instructions to avoid hangs.  Still need to do some
kind of proper error recovery.
(cherry picked from commit e60b3067d8)
2009-03-13 17:38:40 -07:00
Brian Paul
4d9b8e0f93 mesa: added _mesa_fprintf() wrapper (cherry picked from commit 596b8fbbbf) 2009-03-13 17:38:40 -07:00
Brian Paul
c1b71f46b5 i965: fix emit_math1() function used for scalar instructions
Instructions such as RCP, RSQ, LOG must smear the result of the function
across the dest register's X, Y, Z and W channels (subject to write masking).
Before this change, only the X component was getting written.

Among other things, this fixes cube map texture sampling in GLSL shaders
(since cube lookups involve normalizing the texcoord).
(cherry picked from commit 3485801978)
2009-03-13 17:38:39 -07:00
Brian Paul
4a25ac9564 i965: rewrite the code for handling shader subroutine calls
Previously, the prog_instruction::Data field was used to map original Mesa
instructions to brw instructions in order to resolve subroutine calls.  This
was a rather tangled mess.  Plus it's an obstacle to implementing dynamic
allocation/growing of the instruction buffer (it's still a fixed size).

Mesa's GLSL compiler emits a label for each subroutine and CAL instruction.
Now we use those labels to patch the subroutine calls after code generation
has been done.  We just keep a list of all CAL instructions that needs patching
and a list of all subroutine labels.  It's a simple matter to resolve them.

This also consolidates some redundant post-emit code between brw_vs_emit.c and
brw_wm_glsl.c and removes some loops that cleared the prog_instruction::Data
fields at the end.

Plus, a bunch of new comments.
(cherry picked from commit c51c822ee0)
2009-03-13 17:38:39 -07:00
Eric Anholt
35d965b39b intel: Fix bpp setting of blits to 8bpp targets.
This was causing hangs in cairogears, as we would blit to the 8bpp target
(A8 texture) as 16bpp, and stomp over state objects.
(cherry picked from commit 19e134051c)
2009-03-13 17:38:39 -07:00
Robert Ellison
d0aab00609 i965: add software fallback for conformant 3D textures and GL_CLAMP
The i965 hardware cannot do GL_CLAMP behavior on textures; an earlier
commit forced a software fallback if strict conformance was required
(i.e. the INTEL_STRICT_CONFORMANCE environment variable was set) and
2D textures were used, but it was somewhat flawed - it could trigger
the software fallback even if 2D textures weren't enabled, as long
as one texture unit was enabled.

This fixes that, and adds software fallback for GL_CLAMP behavior with
1D and 3D textures.

It also adds support for a particular setting of the INTEL_STRICT_CONFORMANCE
environment variable, which forces software fallbacks to be taken *all*
the time.  This is helpful with debugging.  The value is:
   export INTEL_STRICT_CONFORMANCE=2
(cherry picked from commit 3468315087)
2009-03-13 17:38:39 -07:00
Brian Paul
ef33d0f103 mesa: don't draw arrays if vertex position array is not enabled
For regular GL, we must have vertex positions in order to draw.  But ES2
doesn't have that requirement (positions can be computed from any array
of data).

See bug 19911.
(cherry picked from commit 97dd2ddbd9)
2009-03-13 17:38:39 -07:00
Robert Ellison
349b819768 i965: texture fixes: bordered textures, fallback rendering
i965 doesn't natively support GL_CLAMP; it treats it like
GL_CLAMP_TO_EDGE, which fails conformance tests.

This fix adds a clause to the check_fallbacks() test to check
whether GL_CLAMP is in use on any enabled 2D texture.  If so,
and if strict conformance is required (via INTEL_STRICT_CONFORMANCE),
a software fallback is mandated.

In addition, validate textures *before* checking for fallbacks,
rather than after; otherwise, the texture state is never validated
and can't be trusted.  (In particular, if texturing is enabled and
the sampler would access any level beyond level 0 of a texture, the
sampler will segfault, because texture validation sets the firstLevel
and lastLevel fields of a texture object so that the valid levels
will be mapped and accessed correctly.  If texture validation doesn't
occur, only level 0 is accessed correctly, and that only because
firstLevel and lastLevel happen to be set to 0.)
(cherry picked from commit 17c7852bf9)
2009-03-13 17:38:39 -07:00
Dave Airlie
50443db882 texmem: fix typo from brianp's changes.
Reported by cjb via tinderbox on irc
(cherry picked from commit 487a55af78)
2009-03-13 17:38:39 -07:00
Brian Paul
c503cacb53 mesa: use an array for current texture objects
Use loops to consolidate lots of texture object code.
(cherry picked from commit 9818734e01)
2009-03-13 17:38:39 -07:00
Brian Paul
e862b4e38f mesa: use an array for default texture objects
Replace Default1D/2D/3D/Cube/etc with DefaultTex[TEXTURE_x_INDEX].
The same should be done with the Current1D/2D/3D/etc pointers...
(cherry picked from commit 4d24b639d1)
2009-03-13 17:38:39 -07:00
Robert Ellison
e9dfc858fb Fix an i965 assertion failure on glClear()
While running conform with render-to-texture:

	conform -d 33 -v 2 -t -direct

the i965 driver failed this assertion:

intel_clear.c:77: intel_clear_tris: Assertion `(mask & ~((1 << BUFFER_BACK_LEFT) | (1 << BUFFER_FRONT_LEFT) | (1 << BUFFER_DEPTH) | (1 << BUFFER_STENCIL))) == 0' failed.

The problem is that intel_clear_tris() is called by intelClear() to
clear any and all of the available color buffers, but intel_clear_tris()
actually only handles the back left and front left color buffers; so
the assertion fails as soon as you try to clear a non-standard color
buffer.

The fix is to have intelClear() only call intel_clear_tris() with
buffers that intel_clear_tris() can support.  intelClear() already backs
down to _swrast_Clear() for all buffers that aren't handled explicitly.
(cherry picked from commit 0ccbc3c905)
2009-03-13 17:38:39 -07:00
Brian Paul
5efbca1e21 intel: fix datatype typo, s/GLboolean/GLuint/
Fixes mysterious failures in glean glsl1 test.
(cherry picked from commit da2b661ee4)
2009-03-13 17:38:39 -07:00
Kristian Høgsberg
d6d8663a88 intel: Fix intelSetTexBuffer miptree leak.
The intelImage also holds a reference to the miptree, so unref that as well.
(cherry picked from commit 5b354d39d4)
2009-03-13 17:38:39 -07:00
Eric Anholt
13990bd98a intel: tell libdrm whether we want a cpu-ready or gpu-ready BO for regions.
This lets us avoid allocing new buffers for renderbuffers, finalized miptrees,
and PBO-uploaded textures when there's an unreferenced but still active one
cached, while also avoiding CPU waits for batchbuffers and CPU-uploaded
textures.  The size of BOs allocated for a desktop running current GL
cairogears on i915 is cut in half with this.

Note that this means we require libdrm 2.4.5.
(cherry picked from commit 40dd024be6)
2009-03-13 17:38:39 -07:00
Eric Anholt
def630d0a2 i965: Fix render target read domains.
We were asking for something illegal (write_domain != 0 && read_domains !=
write_domain) because at the time of writing the region surfaces were used
for texturing occasionally as well, and we weren't really clear on the model
GEM was going to use.

This reliably triggered a kernel bug with domain handling, resulting in
oglconform mustpass.c failure.  Of course, it only became visible after
01bc4d441f cleaned up some gratuitous flushing.
(cherry picked from commit 078e8a61b2)
2009-03-13 17:38:39 -07:00
Eric Anholt
ca2564f1e6 intel: Don't do the extra MI_FLUSH in flushing except when doing glFlush().
Everything other than "make sure the last rendering ends up visible on the
screen" doesn't need that behavior.
(cherry picked from commit 01bc4d441f)
2009-03-13 17:38:38 -07:00
Eric Anholt
711a57f7c7 intel: don't crash when dri2 tells us about buffers we don't care about. (cherry picked from commit f82f1ffba9) 2009-03-13 17:38:38 -07:00
Eric Anholt
058cf2fff1 dri2: Initialize variables for the getbuffers round-trip reduction.
Missed setting the initial values which usually didn't hurt at runtime.
(cherry picked from commit 680c708dee)
2009-03-13 17:38:38 -07:00
Eric Anholt
715f509c5d intel: Fix tri clear to do FBO color attachments as well.
This is a 2% win in fbo_firecube, and would avoid a sw fallback for
masked clears.
(cherry picked from commit fd51cf1531)
2009-03-13 17:38:38 -07:00
Eric Anholt
e704e6c6f3 i965: Fix fallback on stencil drawing to fbo when the visual lacks stencil.
Noticed this with the fbotexture demo.
(cherry picked from commit c06f4e2a37)
2009-03-13 17:38:38 -07:00
Brian Paul
01f34e667a i965: need to disable current shader, if any, in intel_clear_tris()
Fixes bad background in all the progs/glsl/ tests.
(cherry picked from commit 60b3fe6c19)
2009-03-13 17:38:38 -07:00
Eric Anholt
4d0a7b33c5 intel: Speed up glDrawPixels(GL_ALPHA) by using an alpha texture format. (cherry picked from commit 0b63f6449e) 2009-03-13 17:38:38 -07:00
Eric Anholt
fb1d2ed34c intel: Fix some state leakage of {Client,}ActiveTexture in metaops.
Found while debugging cairo-gl.
(cherry picked from commit d11981e0d7)
2009-03-13 17:38:38 -07:00
Eric Anholt
9395fedf98 i965: Remove brw->attribs now that we can just always look in the GLcontext. (cherry picked from commit 052c1d66a1) 2009-03-13 17:38:38 -07:00
Eric Anholt
9abc0d80af i965: Delete old metaops code now that there are no remaining consumers. (cherry picked from commit 14321fcfde) 2009-03-13 17:38:38 -07:00
Brian Paul
90e89c01df i965: init array->Format fields (see bug 19708) (cherry picked from commit 628b52241b) 2009-03-13 17:38:38 -07:00
Eric Anholt
790d93e362 intel: If we're doing a depth clear with tris, do color with it.
This is a 10% win on the ever-important glxgears not-a-benchmark.
(cherry picked from commit 67ee22c89f)
2009-03-13 17:38:38 -07:00
Eric Anholt
e9f3783169 i915: Only call CalcViewport from DrawBuffers instead of Viewport.
This saves an inadvertent round-trip to the X Server on DrawBuffers, which was
hurting some metaops.
(cherry picked from commit ac0dfbdf0f)
2009-03-13 17:38:38 -07:00
Brian Paul
e41780fedc intel: move some driver functions around
A step toward consolidating i915/intel_state.c and i965/intel_state.c
(cherry picked from commit 84c8b5bbf9)
2009-03-13 17:38:38 -07:00
Eric Anholt
d0edbbb3f3 intel: replace custom metaops clear with generic.
No real-world impact on performance seen.  Even glxgears seems to be, if
anything, happier.
(cherry picked from commit c96bac0950)
2009-03-13 17:38:38 -07:00
Brian Paul
e10119c23e intel: make intelUpdateScreenFromSAREA() static (cherry picked from commit aae2729aeb) 2009-03-13 17:38:38 -07:00
Brian Paul
208c087f39 intel: remove unused var (cherry picked from commit 66c7f06413) 2009-03-13 17:38:38 -07:00
Shaohua Li
0c8b40b42b i915: Add support for a new G33-like chipset.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
(cherry picked from commit 40290745ea)
2009-03-13 17:38:37 -07:00
Xiang, Haihao
5199f451bb i965: fix for RHW workaround
It is possible that an object whose vertices all are outside of a
view plane is passed to clip thread due to the RHW workaround. This
object should be rejected by clip thread. Fix bug #19879
(cherry picked from commit 68915fd6fa)
2009-03-13 17:38:37 -07:00
Brian Paul
dd7cde5230 i965: tell GLSL compiler to emit code using condition codes
The default for EmitCondCodes got flipped when gallium-0.2 was merged.
This fixes GLSL if/else/endif regressions.
Drivers that use GLSL should always explicitly set the flag to be safe.
(cherry picked from commit a9e753c84c)
2009-03-13 17:38:37 -07:00
Eric Anholt
ab5746e5d8 tdfx: Fix begin/endquery for current API. (cherry picked from commit 0cb295584f) 2009-03-13 17:38:37 -07:00
Brian Paul
3bd446c0ab i965: add missing break for OPCODE_RET case
This doesn't effect correctness, but we were emitting an extraneous ADD.
(cherry picked from commit 74b6d55864)
2009-03-13 17:38:37 -07:00
Brian Paul
9b78402ee4 mesa: more info in error messages (cherry picked from commit 1ca05a066b) 2009-03-13 17:38:37 -07:00
Brian Paul
cf1ef0f308 mesa: minor error msg improvement (cherry picked from commit 803504e69f) 2009-03-13 17:38:37 -07:00
Chris Wilson
fd1f65ba61 intel: Decode MI operands using specific length masks
The MI opcodes have different variable length masks, so use an operand
specific mask to decode the length.
(cherry picked from commit e92d97d75b)
2009-03-13 17:38:37 -07:00
Chris Wilson
967345b497 intel: Correct decoding of 3DSTATE_PIXEL_SHADER_CONSTANTS
A couple of minor typos that proclaimed an error in the wrong command, and
failed to offset the mask.
(cherry picked from commit 05d130a35a)
2009-03-13 17:38:37 -07:00
Ian Romanick
41ad853a6a glxgears: No, really. Fix the dyslexia. (cherry picked from commit 5b5ddfb89c) 2009-03-13 17:38:37 -07:00
Ian Romanick
842baa29cb Fix dyslexia. (cherry picked from commit 9d6880ec8d) 2009-03-13 17:38:37 -07:00
Ian Romanick
9556d870a1 glxgears: Log a message if synched to vblank
Tries to use either GLX_MESA_swap_control or GLX_SGI_video_sync to
detect whether the display is synchronized to the vertical blank.  If
it detects this, a message will be printed.  HOPEFULLY this will
prevent some of the bug reports such as "glxgears only gets 59.7fps.
What's wrong with my driver?"
(cherry picked from commit 58b9cd411f)
2009-03-13 17:38:37 -07:00
Brian Paul
42ce790086 mesa: refactor glTexParameter code (cherry picked from commit 318e53a4bf) 2009-03-13 17:38:37 -07:00
Robert Ellison
b17769af42 mesa: add missing texture_put_row_rgb() function in texrender.c
The wrap_texture() function doesn't set the renderbuffer PutRowRGB() method,
which is used to implement DrawPixels().  This fix adds an implementation
of this method.
(cherry picked from commit 523febe12e)
2009-03-13 17:38:37 -07:00
Brian Paul
9030277b0d intel: move glClear-related code into new intel_clear.c file (cherry picked from commit 4451eb2e75) 2009-03-13 17:38:37 -07:00
Brian Paul
a37a9bf769 intel: Move swap-related functions from intel_buffers.c to new intel_swapbuffers.c (cherry picked from commit 6fcebbe719) 2009-03-13 17:38:37 -07:00
Brian Paul
8afb8a8145 i965: scissor rect was inverted when rendering to texture (cherry picked from commit 3b23a8e07d) 2009-03-13 17:38:37 -07:00
Brian Paul
801f933694 mesa: consolidate glGetTexEnvi/f() code with new get_texenvi() helper (cherry picked from commit ad338c14c2) 2009-03-13 17:38:36 -07:00
Jesse Barnes
75ecd6ebbf intel: fix the mismerge of the vblank pipe enable sanity check
Fix the last merge fix, had the blocks ordered incorrectly.
(cherry picked from commit e57e398960)
2009-03-13 17:38:36 -07:00
Jesse Barnes
1cd7317fdb intel: move pipe enable sanity check to where it belongs
Bah, applied the patches in the wrong order, not Owain's fault...
(cherry picked from commit 216bff5fd4)
2009-03-13 17:38:36 -07:00
Owain Ainsworth
1865291701 intel: fix vblank crtc selection with DRI1 when only one pipe is enabled.
On Mobile chipsets, we often enable PipeB instead of PipeA, but the test
in here was insufficient, falling back to pipe A if the area
intersection returned zero. Therefore, in the case where a window went
off to the top of the left of the screen, it would freeze, waiting on
the wrong vblank.

Fix this mess by checking the sarea for a crtc being zero sized, and in
that case always default to the other one.
(cherry picked from commit 0b5266ff64)
2009-03-13 17:38:36 -07:00
Owain G. Ainsworth
3edbcce7d5 intel: Prevent an "irq is not working" printf when only pipe B is enabled.
intelMakeCurrent is called before intelWindowMoved (in fact, it calls
it), so calculation of the correct vblank crtc has not happened yet.
Fix this by making a function that fixes up a set of vblank flags and
call if from both functions.
(cherry picked from commit 39b4061bb9)
2009-03-13 17:38:36 -07:00
Robert Ellison
b1fb34d0ac i965: fix line stipple fallback for GL_LINE_STRIP primitives
When doing line stipple, the stipple count resets on each line segment,
unless the primitive is a GL_LINE_LOOP or a GL_LINE_STRIP.

The existing code correctly identifies the need for a software fallback
to handle conformant line stipple on GL_LINE_LOOP primitives, but
neglects to make the same assessment on GL_LINE_STRIP primitives.
This fixes it so they match.
(cherry picked from commit 73658ff04f)
2009-03-13 17:38:36 -07:00
Ian Romanick
606099f545 swrast: Enable GL_EXT_stencil_two_side (cherry picked from commit b5fbdef7ec) 2009-03-13 17:38:36 -07:00
Brian Paul
32e3142071 i965: minor improvements in brw_wm_populate_key() (cherry picked from commit 89fddf978c) 2009-03-13 17:38:36 -07:00
Brian Paul
66eea4e104 mesa: fix/update/restore comments related to two-sided stencil (cherry picked from commit a304cc6cca) 2009-03-13 17:38:36 -07:00
Brian Paul
e428cf3afd mesa: initialize ctx->Stencil._BackFace = 1
Back-face stencil operations didn't work correctly because this value was
zero.  It needs to be 1 or 2.  The only place it's set otherwise is in
glEnable/Disable(GL_STENCIL_TEST_TWO_SIDE_EXT).
(cherry picked from commit 2a968113a9)
2009-03-13 17:38:36 -07:00
Ian Romanick
842b5164d2 Track two sets of back-face stencil state
Track separate back-face stencil state for OpenGL 2.0 /
GL_ATI_separate_stencil and GL_EXT_stencil_two_side.  This allows all
three to be enabled in a driver.  One set of state is set via the 2.0
or ATI functions and is used when STENCIL_TEST_TWO_SIDE_EXT is
disabled.  The other is set by StencilFunc and StencilOp when the
active stencil face is set to BACK.  The GL_EXT_stencil_two_side spec has
more details.

http://opengl.org/registry/specs/EXT/stencil_two_side.txt
(cherry picked from commit dde7cb9628)
2009-03-13 17:38:36 -07:00
Brian Paul
a6f7e909a7 mesa: fix transposed red/blue in store_texel_rgb888/bgr888() functions
(cherry picked from master, commit 862dccd560)
2009-03-12 09:32:55 -06:00
Brian Paul
ca87e5a7bd mesa: add missing _glthread_INIT_MUTEX in _mesa_new_framebuffer()
(cherry picked from master, commit 81569c2f69)
2009-03-12 08:12:54 -06:00
Alan Hourihane
45c4b4dfbd xdemos: On termination with esc close the contexts correctly. 2009-03-11 13:36:26 +00:00
Brian Paul
2adaec1226 xmesa: set back-buffer's drawable field
Fixes back-buffer rendering when MESA_BACK_BUFFER=pixmap

(cherry picked from master, commit 22bac2a1a0)
2009-03-09 16:28:50 -06:00
Brian Paul
549586c319 i965: fix cube map lock-up / corruption
If we're using anything but GL_NEAREST sampling of a cube map, we need to
use the BRW_TEXCOORDMODE_CUBE texcoord wrap mode.  Before this, the GPU
would either lock up or subsequent texture filtering would be corrupted.

(cherry picked from master, commit 6f915b10d5)
2009-03-09 11:57:16 -06:00
Dan Nicholson
463ac421a5 autoconf: Restore _GNU_SOURCE for all Linux systems
This catches the linux-uclibc case and any others that were being set
prior to 98fcdf3f. Fixes bug 20345.

Signed-off-by: Dan Nicholson <dbn.lists@gmail.com>
(cherry picked from commit ac55db1d7d)
2009-03-06 07:59:00 -08:00
Brian Paul
6801240205 mesa: Reads must also be done with lock held.
Otherwise two threads might think each made the refcount go zero.

(cherry picked from master, commit 8bbb6b352a)
2009-03-06 07:51:18 -07:00
Brian Paul
a22088b7d5 mesa: Fix typo.
Windows threads block if one over-unlocks them.

(cherry picked from master, commit f6159ba4d5)
2009-03-06 07:50:55 -07:00
Brian Paul
e89c49147f docs: update glext.h to version 46 2009-03-05 08:25:17 -07:00
Brian Paul
67634240d1 gl: update glext.h to version 46 2009-03-05 08:25:09 -07:00
Brian Paul
819b028a8e mesa: fix sw fallback state validation bug
When a hw driver fell back to swrast, swrast wasn't always getting informed
of program changes.  When fixed function is translated into shaders, flags
like _NEW_LIGHT, _NEW_TEXTURE, etc. should really signal _NEW_PROGRAM.
In this case, swrast wasn't seeing _NEW_PROGRAM when new fragment shaders
were generated.

(cherry picked from master, commit de1caa5507)
2009-03-03 14:25:28 -07:00
Brian Paul
a43c30ef41 mesa: update fragResults array in arb_output_attrib_string()
Plus add some comments.

(cherry picked from master, commit a070937c00)
2009-02-27 13:49:58 -07:00
Brian Paul
b65bfde84d mesa: set bufObj->Pointer = NULL after unmapping
Also, ctx->Driver.UnmapBuffer can never be null, so remove conditional.

(cherry picked from master, commit 67025f7893)
2009-02-27 13:13:31 -07:00
Brian Paul
c39e6917ac mesa: if a buffer object is mapped when glDeleteBuffers() is called, unmap it
(cherry picked from master, commit a7f434b486)
2009-02-27 13:05:51 -07:00
Brian Paul
c79079895f mesa: fix incorrect error handling in glBufferDataARB()
If glBufferDataARB() is called while a buffer object is currently mapped
we're supposed to unmap the current buffer, then replace it.  Don't generate
an error.

(cherry picked from master, commit 75e3ccf6a5)
2009-02-27 12:58:07 -07:00
Alex Deucher
4480e631cd R300: Add support for RS600 chips 2009-02-25 17:48:45 -05:00
Brian Paul
c32661c3ce mesa: Build DRI by default on Linux/sparc
Signed-off-by: David S. Miller <davem@davemloft.net>

(cherry picked from master, commit 32dc28ac7a)
2009-02-24 20:08:00 -07:00
Brian Paul
d5c06bb812 glsl: yet another swizzled expression fix
This fixes swizzled conditional expressions such "(b ? p : q).x"

(cherry picked from master, commit 00f0b05d5f)
2009-02-24 08:32:01 -07:00
Brian Paul
9d5aa36239 glsl: fix another swizzle-related bug
This fixes the case of "infinitely" nested swizzles such as EXPR.wzyx.yxwz.xxyz
This doesn't appear in typical shaders but with function inlining and the
compiler's internal use of swizzles it can happen.
New glean glsl1 test case added for this.

(cherry picked from master, commit d9881356a6)
2009-02-24 08:31:02 -07:00
Brian Paul
e3050c1777 docs: Haiku fixes 2009-02-23 08:16:09 -07:00
Brian Paul
06295ddbdd mesa: fixes for building on Haiku
(cherry picked from master, commit 41172c0430)

Conflicts:
	src/mesa/main/dlopen.c
2009-02-23 08:15:43 -07:00
Brian Paul
e2092bb23c demos: update multitex.c GLSL demo to use vertex arrays or glVertex-mode
Press 'a' to toggle drawing mode.

(cherry picked from master, commit 8e8b25c26a)
2009-02-19 17:05:14 -07:00
Brian Paul
528836d0ad util: added more functions to extfuncs.h
(cherry picked from master, commit 4c5f390328)
2009-02-19 17:04:42 -07:00
Brian Paul
3511442e43 mesa: fix GLSL issue preventing use of all 16 generic vertex attributes
Only 15 actually worked before since we always reserved generic[0] as an
alias for vertex position.

The case of vertex attribute 0 is tricky.  The spec says that there is no
aliasing between generic vertex attributes 0..MAX_VERTEX_ATTRIBS-1 and the
conventional attributes.  But it also says that calls to glVertexAttrib(0, v)
are equivalent to glVertex(v).  The distinction seems to be in glVertex-mode
versus vertex array mode.

So update the VBO code so that if the shader uses generic[0] but not gl_Vertex,
route the attribute data set with glVertex() to go to shader input generic[0].

No change needed for the glDrawArrays/Elements() path.

This is a potentially risky change so regressions are possible.  All the usual
tests seem OK though.

(cherry picked from mesa, commit dea0d4d563)

Follow-up: This patch doesn't seem to be as risky as noted above.
There have been no known regressions on Mesa/master because of it.
2009-02-19 17:01:17 -07:00
Brian Paul
d20c53b511 glsl: update program->InputsRead when referencing input attributes
This info will be used in the linker for allocating generic vertex attribs.

(cherry picked from master, commit 1cb7cd1292)
2009-02-19 17:00:06 -07:00
Brian Paul
091cc122ad glsl: asst improvements, clean-ups in set_program_uniform()
Move the is_boolean/integer_type() calls out of the loops.
Move the is_sampler_type() function near the bool/int functions.
Add a bunch of comments.

(cherry picked from master, commit c4ffbf009e)
2009-02-18 17:53:08 -07:00
Brian Paul
c983abbb9e glsl: fix inequality in set_program_uniform()
We were off by one when checking for too many uniform values.

(cherry picked from master, commit b9d8f717d2)
2009-02-18 17:52:47 -07:00
Brian Paul
a0a81204c2 mesa: bump gl.h version comment to 7.4 (bug 20170) 2009-02-18 15:37:44 -07:00
Brian Paul
409d4f839c glsl: fix link failure for variable-indexed varying output arrays
If the vertex shader writes to a varying array with a variable index,
mark all the elements of that array as being written.

For example, if the vertex shader does:

   for (i = 0; i < 4; i++)
      gl_TexCoord[i] = expr;

Mark all texcoord outputs as being written, not just the first.

Linking will fail if a fragment shader tries to read an input that's not
written by the vertex shader.  Before this fix, this linker test could fail.

(cherry picked from master, commit dac19f17f3)
2009-02-18 14:29:46 -07:00
Brian Paul
0ab36958ea mesa: improved error msg
(cherry picked from master, commit 621c999d82)
2009-02-18 13:41:12 -07:00
Brian Paul
c2445f43a3 mesa: increase MAX_UNIFORMS to 1024 (of vec4 type)
Old limit was 256.  Note that no arrays are declared to this size.
The only place we have to be careful about raising this limit is the
prog_src/dst_register Index bitfields.  These have been bumped up too.

Added assertions to check we don't exceed the bitfield in the future too.

(cherry picked from master, commit 5b2f8dc013)
2009-02-18 13:40:57 -07:00
Brian Paul
f3d1c136b7 glsl: fix a swizzle-related regression
This new issue was exposed by commit 6eabfc27f1

(cherry picked from master, commit 212f41b80f)
2009-02-18 13:37:31 -07:00
Brian Paul
dd10a8b09d docs: 7.4 relnotes: report GLSL 1.20, fixed GLSL array index bug 2009-02-17 16:39:45 -07:00
Brian Paul
dd312366da glsl: silence some uninit var warnings
(cherry picked from master, commit 9d49802b7a)
2009-02-17 16:38:30 -07:00
Brian Paul
d2fe466ef3 mesa: turn on reporting of GLSL version 1.20
The new array features, precision/invariant/centroid qualifiers, etc. were
done a while back.  The glGetString(GL_SHADING_LANGUAGE_VERSION) query returns
"1.20" now (for drivers that support it anyway).

(cherry picked from master, commit f59719c6c7)
2009-02-17 16:37:41 -07:00
Brian Paul
fe5328bfad glsl: fix mistake in a comment
(cherry picked from master, commit be8dd01678)
2009-02-17 16:36:15 -07:00
Brian Paul
c0891dde07 glsl: fix an array indexing bug
This fixes a bug found with swizzled array indexes such as in "array[index.z]"
where "index" is an ivec4.

(cherry picked from master, commit 6eabfc27f1)
2009-02-17 16:35:59 -07:00
Brian Paul
0e6d9c1a55 docs: recent 7.4 bug fixes 2009-02-16 20:35:12 -07:00
Brian Paul
5f74a66132 glsl: allow setting arrays of samplers in set_program_uniform()
Arrays of sampler vars haven't been tested much and might actually be broken.
Will need to be revisited someday.

Another fix for bug 20056.

(cherry picked from master, commit 2b4f0216bf)
2009-02-16 20:30:49 -07:00
Brian Paul
46f8b62d5f glsl: raise GL_INVALID_OPERATION for glUniform(location < -1)
location = -1 is silently ignored, but other negative values should raise
an error.

Another fix for bug 20056.

(cherry picked from master, commit 234f03e90a)
2009-02-16 20:30:06 -07:00
Brian Paul
3e3e80c431 glsl: rework _mesa_get_uniform[fi]v() to avoid using a fixed size intermediate array
(cherry picked from master, commit 4ef7a93296)
2009-02-16 20:29:36 -07:00
Brian Paul
0486d117e4 glsl: fix glUniform() array bounds error checking
If too many array elements are specified, they're to be silently ignored (don't
raise a GL error).

Fixes another issue in bug 20056.

(cherry picked from master, commit 2c1ea0720d)
2009-02-16 20:28:57 -07:00
Brian Paul
29981c14da glsl: fix incorrect size returned by glGetActiveUniform() for array elements.
Fixes one of the issues in bug 20056.

(cherry picked from master, commit 369d1859d7)
2009-02-16 20:28:14 -07:00
Brian Paul
98d5efb2c5 glsl: use _slang_var_swizzle() in a few places to simplify the code.
(cherry picked from master, commit 285b500bb7)
2009-02-16 20:26:58 -07:00
Brian Paul
77a44aafaf mesa: another fix for program/texture state validation
This fixes a regression introduced in 46ae1abbac

Break program validation into two steps, do part before texture state
validation and do the rest after:
1. Determine Vertex/Fragment _Enabled state.
2. Update texture state.
3. Determine pointers to current Vertex/Fragment programs (which may involve
generating new "fixed-function" programs).

See comments in the code for more details of the dependencies.

(cherry picked from master, commit 537d3ed6f3)
2009-02-16 20:23:17 -07:00
Brian Paul
8278c70716 mesa: fix/change state validation order for program/texture state
Program state needs to be updated before texture state since the later depends
on the former.

Fixes piglit texgen failure.  The second time through the modes (press 't'
three times) we disable the fragment program and return to conventional texture
mode.  State validation failed here because update_texture() saw stale fragment
program state.

(cherry picked from master, commit 46ae1abbac)
2009-02-16 20:22:46 -07:00
Alan Hourihane
ac0955f5e2 demos: fix glxpixmap and call glXWaitGL before calling XCopyArea. 2009-02-16 11:55:47 +00:00
Alan Hourihane
4130c35ca8 dri2: support glXWaitX & glXWaitGL by using fake front buffer. 2009-02-16 11:48:24 +00:00
Brian Paul
d440647eb8 autoconf: Use include-fixed directory with makedepend on newer GCC
On newer GCC releases, the compiler's headers have been split between
the include and include-fixed directories. Add both if the directories
exist.

Signed-off-by: Dan Nicholson <dbn.lists@gmail.com>
Signed-off-by: Julien Cristau <jcristau@debian.org>

(cherry picked from master, commit a3d223f0d2)
2009-02-13 09:10:09 -07:00
Brian Paul
7e8f2c56c0 mesa: fix logic error in computing enableBits in update_texture_state()
If we had a vertex shader but no fragment shader (i.e. fixed function) we
didn't get the right enabled texture targets.

Fixes blank/white texture problem.

(cherry picked from master, commit b46611633c)
2009-02-07 12:04:15 -07:00
Brian Paul
a0880a152f mesa: fix tnl->render_inputs_bitset setup for fragment program texcoords
Handle the case where there's no per-vertex texcoords but the fragment shader
needs texcoords.

Fixes piglit shaders/fp-generic/dph test.

(cherry picked from master, commit f6d23943cd)
2009-02-07 12:03:37 -07:00
Brian Paul
4608a9172f swrast: return (0,0,0,1) when sampling incomplete textures, not (0,0,0,0)
Fixes piglit shaders/fp-incomplete-tex test.

(cherry picked from master, commit 1df62651b2)

Conflicts:
	src/mesa/swrast/s_fragprog.c

Also updated the fetch_texel_lod(), fetch_texel_deriv() functions to match
those in git/master.
2009-02-07 12:02:22 -07:00
Brian Paul
d0e38f7ec0 glsl: replace assertion with conditional in _slang_pop_var_table()
We were hitting the assertion when we ran out of registers, which can happen.

Also, add some additional assertions and freshen up some comments.

(cherry picked from master, commit 0744805d58)
2009-02-07 11:57:43 -07:00
Brian Paul
a69bdbbbdd docs: fixed Windows build error, added MESA_GLX_FORCE_DIRECT env var 2009-02-03 15:40:16 -07:00
Brian Paul
88c97a2662 docs: document new MESA_GLX_FORCE_DIRECT env var for the Xlib driver
(cherry picked from master, commit 2f51be75c5)
2009-02-03 15:39:13 -07:00
Brian Paul
ce9c69ddbc xlib: use MESA_GLX_FORCE_DIRECT to make glXIsDirect() always return True
Some apps won't run w/ indirect rendering contexts.
Also, consolidate some context-init code in new init_glx_context() function.

(cherry-picked from master, commit 49e80bf6b1)
2009-02-03 15:38:44 -07:00
Eric Anholt
e430fcb716 dri2: Avoid round-tripping on DRI2GetBuffers for the same set of buffers.
We only wanted to request when asked for the same set of buffers when a resize
has happened.  We can just watch the protocol stream for a ConfigureNotify
and flag to do it then.

This is about a 5% win from doing two glViewport()s per frame in openarena.
2009-02-03 21:36:38 +00:00
Brian Paul
11a363e632 mesa: move code after decls. Fixes Window build failure.
(cherry picked from master, commit 92ced46eaf)
2009-02-02 07:50:31 -07:00
Julien Cristau
9a3a20b2b9 debian/rules: on lpia, only build the i915 and i965 dri drivers
Based on Ubuntu changes, modified to also build swrast.
2009-01-31 23:04:06 +01:00
Julien Cristau
4672811541 debian/control: build the dri drivers on lpia
add lpia to the Architecture field for libgl1-mesa-dri{,-dbg} to match Ubuntu.
2009-01-31 22:30:15 +01:00
Julien Cristau
3cad3d28a5 mangle upstream version in debian/watch
Fix watch file to make uscan not consider release candidates as newer than
actual releases.
2009-01-31 22:07:51 +01:00
Brian Paul
41e63fbdb2 docs: recent bug fixes for 7.4 2009-01-30 16:09:58 -07:00
Brian Paul
b543401a5c mesa: fix incorrect call to clear_teximage_fields() in _mesa_TexImage2D()
Fixes failed assertion / segfault for particular proxy texture tests.

(cherry picked from master, commit ea4b183b8c)
2009-01-30 16:06:52 -07:00
Brian Paul
8c4f08fbad mesa: add missing _mesa_reference_texobj() calls for texture array targets
(cherry picked from master, commit 7c48719a5f)
2009-01-30 16:06:21 -07:00
Brian Paul
f3081a34d2 mesa: remove incorrect refcounting adjustment in adjust_buffer_object_ref_counts()
Fixes bug 19835.  However, a more elaborate fix should be implemented someday
which uses proper reference counting for gl_array_object.

(cherry picked from master, commit 88e0b92a74)
2009-01-30 16:05:51 -07:00
Julien Cristau
cff0971f87 Prepare changelog for upload 2009-01-30 20:00:37 +01:00
Julien Cristau
5ac4c69d83 More superfluous directories 2009-01-30 19:56:29 +01:00
Julien Cristau
a314c40cc4 Document my changes in debian/changelog 2009-01-30 19:42:38 +01:00
Julien Cristau
959fd6b8f6 Add back progs/fbdev
It was added to the tarballs in 22b0b2f47e
2009-01-30 19:34:47 +01:00
Julien Cristau
937f0da04a Delete more directories that aren't in the tarball 2009-01-30 19:25:50 +01:00
Julien Cristau
73bc5967e2 Merge commit '5a458977113e4a0d3c389b03801cf6ce580d3935' into debian-experimental 2009-01-30 19:06:19 +01:00
Brian Paul
7b1d3cf392 docs: i965 fixes 2009-01-28 17:02:39 -07:00
Brian Paul
25515b557e i965: fix bug in pass0_precalc_mov()
Previously, "in-place" swizzles such as:
   MOV t, t.xxyx;
were handled incorrectly.  Fixed by splitting the one loop into two loops so we
get all the refs before assigning them (to avoid potential clobbering).

(cherry picked from master/commit faa48915d2)
2009-01-28 17:01:34 -07:00
Brian Paul
51625ff86e i965: widen per-texture bitfields for 16 texture image units
(cherry picked from master/commit f78c388b6c)
2009-01-28 17:01:03 -07:00
Brian Paul
4d8f661726 intel: check if stencil test is enabled in intel_stencil_drawpixels()
(cherry picked from master/commit 72ee0e247d)
2009-01-28 17:00:23 -07:00
Brian Paul
efa69a2f66 intel: save/restore GL matrix mode in intel_meta_set_passthrough_transform(), intel_meta_restore_transform()
(cherry picked from master, commit 723648f2ee)
2009-01-28 16:55:16 -07:00
Timo Aaltonen
a2dce49158 New changelog entry for 7.3 2009-01-25 17:51:16 +02:00
Timo Aaltonen
e4b28de803 Merge branch 'upstream-experimental' into debian-experimental 2009-01-25 17:30:47 +02:00
Brian Paul
30a6dd78d5 docs: fix typo 2009-01-22 10:39:05 -07:00
Brian Paul
9f75836308 mesa: set version to 7.4 for mesa_7_4_branch 2009-01-22 10:19:39 -07:00
Brian Paul
609cc9c139 docs: skeleton 7.4 release notes file 2009-01-22 10:18:04 -07:00
Brian Paul
e5aa89386d docs: 7.3 md5 sums 2009-01-22 10:14:39 -07:00
Brian Paul
5a45897711 mesa: set version to 7.3 2009-01-22 10:14:24 -07:00
Brian Paul
faa6d8af59 docs: set 7.3 release date 2009-01-22 10:01:17 -07:00
Brian Paul
b6c41fd933 docs: assorted updates, link fixes 2009-01-22 10:01:17 -07:00
Eric Anholt
b8bd0b0ddc i915: Add decode for PS in batchbuffers. 2009-01-21 14:03:56 -08:00
Eric Anholt
fc3971d800 i965: Remove gratuitous whitespace in INTEL_DEBUG=wm output. 2009-01-21 14:03:56 -08:00
Eric Anholt
046e88fc0b i965: Use _mesa_num_inst_src_regs() instead of keeping a copy of its contents. 2009-01-21 14:03:56 -08:00
Kristian Høgsberg
194d039f1e [intel] Remove remaining references to intel_wait_flips().
Oops.
2009-01-21 11:47:01 -05:00
Thomas Henn
470e10dfaa windows: fix output dir for glut project file 2009-01-21 09:32:40 -07:00
Brian Paul
8c7135ee14 swrast: fix redundant texture application in affine_textured_triangle().
This function does simple texture mapping so disable normal texture mapping
before we call _swrast_write_rgba_span() so that we don't do it twice.
2009-01-21 09:05:02 -07:00
Brian Paul
4683cab29a mesa: add some debug assertions to detect null current texture object pointers
See bug #17895.  These assertions could be removed when this is resolved.
2009-01-21 08:18:07 -07:00
Karl Schultz
787a001a67 windows: another round of VC8 project file updates
New static configs generate DLLs that do not have a dependency on the MSCVR*
DLL's.
2009-01-21 07:59:11 -07:00
Brian Paul
dd92f483b0 Revert "windows: new VC8 projects statically linked against libcmt"
This reverts commit bbda892c55.

Static configs rolled into regular project files (in next commit).
Provided by Karl Schultz.
2009-01-21 07:57:45 -07:00
Brian Paul
65118a51b6 docs: document glXMakeContextCurrent() and Windows fixes 2009-01-20 15:36:01 -07:00
Ian Romanick
ab9b4e1f59 Fix issues with glXMakeContextCurrent and glXMakeCurrentReadSGI
There were several bugs in the infrastructure for these two routines.

1. GLX_ALIAS was incorrectly used.  The function and its alias must be
identical!  glXMakeContextCurrent / glXMakeCurrentReadSGI and
MakeContextCurrent had different parameters.  This caused the last
parameter of MakeContextCurrent to get random values.

2. We based the implementation of glXMakeContextCurrent on the manual
page instead of the GLX spec.  The GLX spec says that
glXMakeContextCurrent can be passed a Window as a drawable.  When this
happens, it will behave just like glXMakeCurrentReadSGI or
glXMakeCurrent.

3. If there was a problem finding or creating the DRI drawable,
MakeContextCurrent would crash instead of returning an error.

This commit fixes all three issues, and fixes bug #18367 and bug #19625.
2009-01-20 13:55:18 -08:00
351 changed files with 6953 additions and 78545 deletions

View File

@@ -174,10 +174,11 @@ ultrix-gcc:
# Rules for making release tarballs
DIRECTORY = Mesa-7.3-rc3
LIB_NAME = MesaLib-7.3-rc3
DEMO_NAME = MesaDemos-7.3-rc3
GLUT_NAME = MesaGLUT-7.3-rc3
VERSION=7.4
DIRECTORY = Mesa-$(VERSION)
LIB_NAME = MesaLib-$(VERSION)
DEMO_NAME = MesaDemos-$(VERSION)
GLUT_NAME = MesaGLUT-$(VERSION)
MAIN_FILES = \
$(DIRECTORY)/Makefile* \

View File

@@ -394,6 +394,30 @@ case $ARCH in
fi
fi
# If using Sun C++ compiler, need to tell it not to add runpaths
# that are specific to the build machine
if [ ${LINK} = "CC" ] ; then
OPTS="${OPTS} -norunpath"
fi
# Solaris linker requires explicitly listing the Standard C & C++
# libraries in the link path when building shared objects
if [ ${LINK} = "CC" ] ; then
DEPS="${DEPS} -lCrun"
fi
DEPS="${DEPS} -lc"
if [ $EXPORTS ] ; then
# Make the 'mapfile.scope' linker mapfile
echo "{" > mapfile.scope
echo "global:" >> mapfile.scope
sed 's/$/;/' ${EXPORTS} >> mapfile.scope
echo "local:" >> mapfile.scope
echo " *;" >> mapfile.scope
echo "};" >> mapfile.scope
OPTS="${OPTS} -Wl,-Mmapfile.scope"
fi
# Check if objects are SPARC v9
# file says: ELF 64-bit MSB relocatable SPARCV9 Version 1
set ${OBJECTS}
@@ -406,17 +430,19 @@ case $ARCH in
if [ "${ALTOPTS}" ] ; then
OPTS=${ALTOPTS}
fi
# for debug:
#echo "mklib: linker is" ${LINK} ${OPTS}
if [ $NOPREFIX = 1 ] ; then
rm -f ${LIBNAME}
${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
FINAL_LIBS="${LIBNAME}"
else
rm -f ${LIBNAME}.${MAJOR} ${LIBNAME}
${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.${MAJOR} -h ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS}
ln -s ${LIBNAME}.${MAJOR} ${LIBNAME}
FINAL_LIBS="${LIBNAME}.${MAJOR} ${LIBNAME}"
fi
FINAL_LIBS="${LIBNAME}.${MAJOR} ${LIBNAME}"
fi
;;

View File

@@ -46,10 +46,14 @@ esac
MKDEP_OPTIONS=-fdepend
dnl Ask gcc where it's keeping its secret headers
if test "x$GCC" = xyes; then
GCC_INCLUDES=`$CC -print-file-name=include`
if test "x$GCC_INCLUDES" != x; then
MKDEP_OPTIONS="$MKDEP_OPTIONS -I$GCC_INCLUDES"
fi
for dir in include include-fixed; do
GCC_INCLUDES=`$CC -print-file-name=$dir`
if test "x$GCC_INCLUDES" != x && \
test "$GCC_INCLUDES" != "$dir" && \
test -d "$GCC_INCLUDES"; then
MKDEP_OPTIONS="$MKDEP_OPTIONS -I$GCC_INCLUDES"
fi
done
fi
AC_SUBST([MKDEP_OPTIONS])
@@ -83,7 +87,7 @@ dnl Compiler macros
DEFINES=""
AC_SUBST([DEFINES])
case "$host_os" in
*-gnu*)
linux*|*-gnu*)
DEFINES="$DEFINES -D_GNU_SOURCE -DPTHREADS"
;;
solaris*)
@@ -342,17 +346,6 @@ if test "x$enable_selinux" = "xyes"; then
DEFINES="$DEFINES -DMESA_SELINUX"
fi
dnl OS-specific libraries
OS_LIBS=""
case "$host_os" in
solaris*)
OS_LIBS="-lc"
if test "x$GXX" != xyes; then
OS_CPLUSPLUS_LIBS="-lCrun $OS_LIBS"
fi
;;
esac
dnl
dnl Driver configuration. Options are xlib, dri and osmesa right now.
dnl More later: directfb, fbdev, ...
@@ -362,7 +355,7 @@ default_driver="xlib"
case "$host_os" in
linux*)
case "$host_cpu" in
i*86|x86_64|powerpc*) default_driver="dri";;
i*86|x86_64|powerpc*|sparc*) default_driver="dri";;
esac
;;
*freebsd* | dragonfly*)
@@ -514,8 +507,8 @@ xlib)
GL_PC_LIB_PRIV="$GL_LIB_DEPS"
GL_PC_CFLAGS="$X11_INCLUDES"
fi
GL_LIB_DEPS="$GL_LIB_DEPS $SELINUX_LIBS -lm -lpthread $OS_LIBS"
GL_PC_LIB_PRIV="$GL_PC_LIB_PRIV $SELINUX_LIBS -lm -lpthread $OS_LIBS"
GL_LIB_DEPS="$GL_LIB_DEPS $SELINUX_LIBS -lm -lpthread"
GL_PC_LIB_PRIV="$GL_PC_LIB_PRIV $SELINUX_LIBS -lm -lpthread"
# if static, move the external libraries to the programs
# and empty the libraries for libGL
@@ -565,12 +558,12 @@ dri)
fi
# need DRM libs, -lpthread, etc.
GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS $OS_LIBS"
GL_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS $OS_LIBS"
GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"
GL_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS"
;;
osmesa)
# No libGL for osmesa
GL_LIB_DEPS="$OS_LIBS"
GL_LIB_DEPS=""
;;
esac
AC_SUBST([GL_LIB_DEPS])
@@ -813,9 +806,9 @@ osmesa)
;;
esac
if test "$enable_static" = no; then
OSMESA_LIB_DEPS="$OSMESA_LIB_DEPS $OS_LIBS"
OSMESA_LIB_DEPS="$OSMESA_LIB_DEPS"
fi
OSMESA_PC_LIB_PRIV="$OSMESA_PC_LIB_PRIV $OS_LIBS"
OSMESA_PC_LIB_PRIV="$OSMESA_PC_LIB_PRIV"
AC_SUBST([OSMESA_LIB_DEPS])
AC_SUBST([OSMESA_MESA_DEPS])
AC_SUBST([OSMESA_PC_REQ])
@@ -928,10 +921,10 @@ if test "x$enable_glw" = xyes; then
fi
# If static, empty GLW_LIB_DEPS and add libs for programs to link
GLW_PC_LIB_PRIV="$GLW_PC_LIB_PRIV $OS_LIBS"
GLW_PC_LIB_PRIV="$GLW_PC_LIB_PRIV"
if test "$enable_static" = no; then
GLW_MESA_DEPS='-l$(GL_LIB)'
GLW_LIB_DEPS="$GLW_LIB_DEPS $OS_LIBS"
GLW_LIB_DEPS="$GLW_LIB_DEPS"
else
APP_LIB_DEPS="$APP_LIB_DEPS $GLW_LIB_DEPS"
GLW_LIB_DEPS=""
@@ -987,8 +980,8 @@ if test "x$enable_glut" = xyes; then
GLUT_PC_LIB_PRIV="$GLUT_LIB_DEPS"
GLUT_PC_CFLAGS="$X11_INCLUDES"
fi
GLUT_LIB_DEPS="$GLUT_LIB_DEPS -lm $OS_LIBS"
GLUT_PC_LIB_PRIV="$GLUT_PC_LIB_PRIV -lm $OS_LIBS"
GLUT_LIB_DEPS="$GLUT_LIB_DEPS -lm"
GLUT_PC_LIB_PRIV="$GLUT_PC_LIB_PRIV -lm"
# If glut is available, we can build most programs
if test "$with_demos" = yes; then

31
debian/changelog vendored
View File

@@ -1,3 +1,34 @@
mesa (7.4-1) experimental; urgency=low
[ Timo Aaltonen ]
* New upstream release.
-- Julien Cristau <jcristau@debian.org> Wed, 01 Apr 2009 20:25:00 +0200
mesa (7.4~rc1-1) experimental; urgency=low
* New upstream release candidate.
* Fix watch file to make uscan not consider release candidates as newer than
actual releases.
* debian/control: add lpia to the Architecture field for
libgl1-mesa-dri{,-dbg} to match Ubuntu.
* debian/rules: on lpia, only build the i915 and i965 dri drivers (based on
Ubuntu changes).
* Build-depend on linux-libc-dev >= 2.6.29 on linux archs.
-- Julien Cristau <jcristau@debian.org> Wed, 25 Mar 2009 11:34:42 +0100
mesa (7.3-1) experimental; urgency=low
[ Timo Aaltonen ]
* New upstream release.
[ Julien Cristau ]
* Try to make the diff a bit smaller by removing directories that are in
upstream git but not in tarballs.
-- Julien Cristau <jcristau@debian.org> Fri, 30 Jan 2009 20:00:34 +0100
mesa (7.3~rc3-1) experimental; urgency=low
[ Timo Aaltonen ]

7
debian/control vendored
View File

@@ -8,7 +8,8 @@ Build-Depends: debhelper (>= 5), quilt (>= 0.40), pkg-config,
libdrm-dev (>= 2.4.3) [!hurd-i386], libx11-dev, xutils-dev,
x11proto-gl-dev (>= 1.4.8), libxxf86vm-dev,
libexpat1-dev, lesstif2-dev, dpkg-dev (>= 1.13.19), libxfixes-dev,
libxdamage-dev, libxext-dev, autoconf, automake, x11proto-dri2-dev (>= 1.99.3)
libxdamage-dev, libxext-dev, autoconf, automake, x11proto-dri2-dev (>= 1.99.3),
linux-libc-dev (>= 2.6.29) [!hurd-i386 !kfreebsd-amd64 !kfreebsd-i386]
Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/mesa
Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/mesa.git
Homepage: http://mesa3d.sourceforge.net/
@@ -162,7 +163,7 @@ Description: Debugging symbols for the Mesa GLX runtime
Package: libgl1-mesa-dri
Section: libs
Priority: optional
Architecture: alpha amd64 arm armeb armel hppa i386 ia64 kfreebsd-i386 kfreebsd-amd64 m68k mips mipsel powerpc s390 sparc
Architecture: alpha amd64 arm armeb armel hppa i386 ia64 kfreebsd-i386 kfreebsd-amd64 lpia m68k mips mipsel powerpc s390 sparc
Depends: ${shlibs:Depends}, libgl1-mesa-glx (= ${binary:Version})
Suggests: libglide3
Conflicts: xlibmesa-dri (<< 1:7.0.0)
@@ -183,7 +184,7 @@ Description: A free implementation of the OpenGL API -- DRI modules
Package: libgl1-mesa-dri-dbg
Section: libdevel
Priority: extra
Architecture: alpha amd64 arm armeb armel hppa i386 ia64 kfreebsd-i386 kfreebsd-amd64 m68k mips mipsel powerpc s390 sparc
Architecture: alpha amd64 arm armeb armel hppa i386 ia64 kfreebsd-i386 kfreebsd-amd64 lpia m68k mips mipsel powerpc s390 sparc
Depends: libgl1-mesa-dri (= ${binary:Version})
Description: Debugging symbols for the Mesa DRI modules
This version of Mesa provides GLX and DRI capabilities: it is capable of

13
debian/rules vendored
View File

@@ -63,15 +63,18 @@ ifeq ($(DEB_HOST_ARCH_OS), hurd)
DIRECT_RENDERING = --disable-driglx-direct
else
DIRECT_RENDERING = --enable-driglx-direct
ifeq ($(DEB_HOST_ARCH), lpia)
DRI_DRIVERS += i915 i965
else
DRI_DRIVERS += mach64 mga r128 r200 r300 radeon s3v savage tdfx trident
endif
ifeq ($(DEB_HOST_GNU_CPU), i486)
ifeq ($(DEB_HOST_GNU_CPU), i486)
DRI_DRIVERS += i810 i915 i965 sis unichrome
else ifeq ($(DEB_HOST_GNU_CPU), x86_64)
else ifeq ($(DEB_HOST_GNU_CPU), x86_64)
DRI_DRIVERS += i915 i965 sis unichrome
else ifeq ($(DEB_HOST_ARCH), sparc)
else ifeq ($(DEB_HOST_ARCH), sparc)
DRI_DRIVERS += ffb
endif
endif
endif
confflags-dri = \

1
debian/watch vendored
View File

@@ -1,2 +1,3 @@
version=3
opts="uversionmangle=s/-rc/~rc/" \
http://sf.net/mesa3d/MesaLib-(.*)\.tar\.gz

View File

@@ -1,230 +0,0 @@
Name
MESA_packed_depth_stencil
Name Strings
GL_MESA_packed_depth_stencil
Contact
Keith Whitwell, VA Linux Systems Inc. (keithw 'at' valinux.com)
Brian Paul, VA Linux Systems Inc. (brianp 'at' valinux.com)
Status
Obsolete.
Version
Number
???
Dependencies
EXT_abgr affects the definition of this extension
SGIS_texture4D affects the definition of this extension
EXT_cmyka affects the definition of this extension
ARB_packed_pixels affects the definition of this extension
Overview
Provides a mechanism for DrawPixels and ReadPixels to efficiently
transfer depth and stencil image data. Specifically, we defined new
packed pixel formats and types which pack both stencil and depth
into one value.
Issues:
1. Is this the right way to distinguish between 24/8 and 8/24
pixel formats? Should we instead provide both:
GL_DEPTH_STENCIL_MESA
GL_STENCIL_DEPTH_MESA
And perhaps just use GL_UNSIGNED_INT, GL_UNSIGNED_SHORT ?
2. If not, is it correct to use _REV to indicate that stencil
preceeds depth in the 1_15 and 8_24 formats?
3. Do we really want the GL_UNSIGNED_SHORT formats?
New Procedures and Functions
None.
New Tokens
Accepted by the <format> parameter of ReadPixels and DrawPixels:
GL_DEPTH_STENCIL_MESA 0x8750
Accepted by the <type> parameter of ReadPixels and DrawPixels:
GL_UNSIGNED_INT_24_8_MESA 0x8751
GL_UNSIGNED_INT_8_24_REV_MESA 0x8752
GL_UNSIGNED_SHORT_15_1_MESA 0x8753
GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754
Additions to Chapter 2 of the 1.1 Specification (OpenGL Operation)
None
Additions to Chapter 3 of the 1.1 Specification (Rasterization)
One entry is added to table 3.5 (DrawPixels and ReadPixels formats).
The new table is:
Target
Format Name Buffer Element Meaning and Order
----------- ------ -------------------------
COLOR_INDEX Color Color index
STENCIL_INDEX Stencil Stencil index
DEPTH_COMPONENT Depth Depth component
RED Color R component
GREEN Color G component
BLUE Color B component
ALPHA Color A component
RGB Color R, G, B components
RGBA Color R, G, B, A components
BGRA Color B, G, R, A components
ABGR_EXT Color A, B, G, R components
CMYK_EXT Color Cyan, Magenta, Yellow, Black components
CMYKA_EXT Color Cyan, Magenta, Yellow, Black, A components
LUMINANCE Color Luminance component
LUMINANCE_ALPHA Color Luminance, A components
DEPTH_STENCIL Depth, Depth component, stencil index.
Stencil
Table 3.5: DrawPixels and ReadPixels formats. The third column
gives a description of and the number and order of elements in a
group.
Add to the description of packed pixel formats:
<type> Parameter Data of Matching
Token Name Type Elements Pixel Formats
---------------- ---- -------- -------------
UNSIGNED_BYTE_3_3_2 ubyte 3 RGB
UNSIGNED_BYTE_2_3_3_REV ubyte 3 RGB
UNSIGNED_SHORT_5_6_5 ushort 3 RGB
UNSIGNED_SHORT_5_6_5_REV ushort 3 RGB
UNSIGNED_SHORT_4_4_4_4 ushort 4 RGBA,BGRA,ABGR_EXT,CMYK_EXT
UNSIGNED_SHORT_4_4_4_4_REV ushort 4 RGBA,BGRA
UNSIGNED_SHORT_5_5_5_1 ushort 4 RGBA,BGRA,ABGR_EXT,CMYK_EXT
UNSIGNED_SHORT_1_5_5_5_REV ushort 4 RGBA,BGRA
UNSIGNED_INT_8_8_8_8 uint 4 RGBA,BGRA,ABGR_EXT,CMYK_EXT
UNSIGNED_INT_8_8_8_8_REV uint 4 RGBA,BGRA
UNSIGNED_INT_10_10_10_2 uint 4 RGBA,BGRA,ABGR_EXT,CMYK_EXT
UNSIGNED_INT_2_10_10_10_REV uint 4 RGBA,BGRA
UNSIGNED_SHORT_15_1_MESA ushort 2 DEPTH_STENCIL_MESA
UNSIGNED_SHORT_1_15_REV_MESA ushort 2 DEPTH_STENCIL_MESA
UNSIGNED_SHORT_24_8_MESA ushort 2 DEPTH_STENCIL_MESA
UNSIGNED_SHORT_8_24_REV_MESA ushort 2 DEPTH_STENCIL_MESA
UNSIGNED_INT_8_24:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-----------------------+-----------------------------------------------------------------------+
| | |
+-----------------------+-----------------------------------------------------------------------+
first second
element element
UNSIGNED_INT_24_8:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+----------------------------------------------------------------------+------------------------+
| | |
+----------------------------------------------------------------------+------------------------+
first second
element element
UNSIGNED_SHORT_15_1:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-----------------------------------------------------------+---+
| | |
+-----------------------------------------------------------+---+
first second
element element
UNSIGNED_SHORT_1_15_REV:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+-----------------------------------------------------------+
| | |
+---+-----------------------------------------------------------+
second first
element element
The assignment of elements to fields in the packed pixel is as
described in the table below:
First Second Third Fourth
Format Element Element Element Element
------ ------- ------- ------- -------
RGB red green blue
RGBA red green blue alpha
BGRA blue green red alpha
ABGR_EXT alpha blue green red
CMYK_EXT cyan magenta yellow black
DEPTH_STENCIL_MESA depth stencil
Additions to Chapter 4 of the 1.1 Specification (Per-Fragment Operations
and the Frame Buffer)
The new format is added to the discussion of Obtaining Pixels from the
Framebuffer. It should read " If the <format> is one of RED, GREEN,
BLUE, ALPHA, RGB, RGBA, ABGR_EXT, LUMINANCE, or LUMINANCE_ALPHA, and
the GL is in color index mode, then the color index is obtained."
The new format is added to the discussion of Index Lookup. It should
read "If <format> is one of RED, GREEN, BLUE, ALPHA, RGB, RGBA,
ABGR_EXT, LUMINANCE, or LUMINANCE_ALPHA, then the index is used to
reference 4 tables of color components: PIXEL_MAP_I_TO_R,
PIXEL_MAP_I_TO_G, PIXEL_MAP_I_TO_B, and PIXEL_MAP_I_TO_A."
Additions to Chapter 5 of the 1.1 Specification (Special Functions)
None
Additions to Chapter 6 of the 1.1 Specification (State and State Requests)
None
Additions to the GLX Specification
None
GLX Protocol
TBD
Errors
None
New State
None
Revision History
Version 1.0 - 23 Sep 2000
Keith's original version.
Version 1.1 - 3 Nov 2000
Brian's edits, assigned values to new enums.

View File

@@ -1,356 +0,0 @@
Name
MESA_program_debug
Name Strings
GL_MESA_program_debug
Contact
Brian Paul (brian.paul 'at' tungstengraphics.com)
Status
XXX - Not complete yet!!!
Version
Last Modified Date: July 20, 2003
Author Revision: 1.0
Number
TBD
Dependencies
OpenGL 1.4 is required
The extension is written against the OpenGL 1.4 specification.
ARB_vertex_program or ARB_fragment_program or NV_vertex_program
or NV_fragment_program is required.
Overview
The extension provides facilities for implementing debuggers for
vertex and fragment programs.
The concept is that vertex and fragment program debuggers will be
implemented outside of the GL as a utility package. This extension
only provides the minimal hooks required to implement a debugger.
There are facilities to do the following:
1. Have the GL call a user-specified function prior to executing
each vertex or fragment instruction.
2. Query the current program string's execution position.
3. Query the current values of intermediate program values.
The main feature is the ProgramCallbackMESA function. It allows the
user to register a callback function with the GL. The callback will
be called prior to executing each vertex or fragment program instruction.
From within the callback, the user may issue Get* commands to
query current GL state. The GetProgramRegisterfvMESA function allows
current program values to be queried (such as temporaries, input
attributes, and result registers).
There are flags for enabling/disabling the program callbacks.
The current execution position (as an offset from the start of the
program string) can be queried with
GetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos) or
GetIntegerv(GL_VERTEX_PROGRAM_POSITION_MESA, &pos).
IP Status
None
Issues
1. Is this the right model for a debugger?
It seems prudent to minimize the scope of this extension and leave
it up to the developer (or developer community) to write debuggers
that layer on top of this extension.
If the debugger were fully implemented within the GL it's not
clear how terminal and GUI-based interfaces would work, for
example.
2. There aren't any other extensions that register callbacks with
the GL. Isn't there another solution?
If we want to be able to single-step through vertex/fragment
programs I don't see another way to do it.
3. How do we prevent the user from doing something crazy in the
callback function, like trying to call glBegin (leading to
recursion)?
The rule is that the callback function can only issue glGet*()
functions and no other GL commands. It could be difficult to
enforce this, however. Therefore, calling any non-get GL
command from within the callback will result in undefined
results.
4. Is this extension amenable to hardware implementation?
Hopefully, but if not, the GL implementation will have to fall
back to a software path when debugging. This may be acceptable
for debugging.
5. What's the <data> parameter to ProgramCallbackMESA for?
It's a common programming practice to associate a user-supplied
value with callback functions.
6. Debuggers often allow one to modify intermediate program values,
then continue. Does this extension support that?
No.
New Procedures and Functions (and datatypes)
typedef void (*programcallbackMESA)(enum target, void *data)
void ProgramCallbackMESA(enum target, programcallbackMESA callback,
void *data)
void GetProgramRegisterfvMESA(enum target, sizei len,
const ubyte *registerName, float *v)
New Tokens
Accepted by the <cap> parameter of Enable, Disable, IsEnabled,
GetBooleanv, GetDoublev, GetFloatv and GetIntegerv:
FRAGMENT_PROGRAM_CALLBACK_MESA 0x8bb1
VERTEX_PROGRAM_CALLBACK_MESA 0x8bb4
Accepted by the <pname> parameter GetBooleanv, GetDoublev,
GetFloatv and GetIntegerv:
FRAGMENT_PROGRAM_POSITION_MESA 0x8bb0
VERTEX_PROGRAM_POSITION_MESA 0x8bb4
Accepted by the <pname> parameter of GetPointerv:
FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2
FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3
VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8bb6
VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8bb7
Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
None.
Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
None.
Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment
Operations and the Frame Buffer)
None.
Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions)
In section 5.4 "Display Lists", page 202, add the following command
to the list of those that are not compiled into display lists:
ProgramCallbackMESA.
Add a new section 5.7 "Callback Functions"
The function
void ProgramCallbackMESA(enum target, programcallbackMESA callback,
void *data)
registers a user-defined callback function with the GL. <target>
may be FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB. The enabled
callback functions registered with these targets will be called
prior to executing each instruction in the current fragment or
vertex program, respectively. The callbacks are enabled and
disabled by calling Enable or Disable with <cap>
FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.
The callback function's signature must match the typedef
typedef void (*programcallbackMESA)(enum target, void *data)
When the callback function is called, <target> will either be
FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB to indicate which
program is currently executing and <data> will be the value
specified when ProgramCallbackMESA was called.
From within the callback function, only the following GL commands
may be called:
GetBooleanv
GetDoublev
GetFloatv
GetIntegerv
GetProgramLocalParameter
GetProgramEnvParameter
GetProgramRegisterfvMESA
GetProgramivARB
GetProgramStringARB
GetError
Calling any other command from within the callback results in
undefined behaviour.
Additions to Chapter 6 of the OpenGL 1.4 Specification (State and
State Requests)
Add a new section 6.1.3 "Program Value Queries":
The command
void GetProgramRegisterfvMESA(enum target, sizei len,
const ubyte *registerName,
float *v)
Is used to query the value of program variables and registers
during program execution. GetProgramRegisterfvMESA may only be
called from within a callback function registered with
ProgramCallbackMESA.
<registerName> and <len> specify the name a variable, input
attribute, temporary, or result register in the program string.
The current value of the named variable is returned as four
values in <v>. If <name> doesn't exist in the program string,
the error INVALID_OPERATION is generated.
Additions to Appendix A of the OpenGL 1.4 Specification (Invariance)
None.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
XXX TBD
Dependencies on NV_vertex_program and NV_fragment_program
If NV_vertex_program and/or NV_fragment_program are supported,
vertex and/or fragment programs defined by those extensions may
be debugged as well. Register queries will use the syntax used
by those extensions (i.e. "v[X]" to query vertex attributes,
"o[X]" for vertex outputs, etc.)
Errors
INVALID_OPERATION is generated if ProgramCallbackMESA is called
between Begin and End.
INVALID_ENUM is generated by ProgramCallbackMESA if <target> is not
a supported vertex or fragment program type.
Note: INVALID_OPERAION IS NOT generated by GetProgramRegisterfvMESA,
GetBooleanv, GetDoublev, GetFloatv, or GetIntegerv if called between
Begin and End when a vertex or fragment program is currently executing.
INVALID_ENUM is generated by ProgramCallbackMESA,
GetProgramRegisterfvMESA if <target> is not a program target supported
by ARB_vertex_program, ARB_fragment_program (or NV_vertex_program or
NV_fragment_program).
INVALID_VALUE is generated by GetProgramRegisterfvMESA if <registerName>
does not name a known program register or variable.
INVALID_OPERATION is generated by GetProgramRegisterfvMESA when a
register query is attempted for a program target that's not currently
being executed.
New State
XXX finish
(table 6.N, p. ###)
Initial
Get Value Type Get Command Value Description Sec. Attribute
--------- ---- ----------- ----- ----------- ---- ---------
FRAGMENT_PROGRAM_CALLBACK_MESA B IsEnabled FALSE XXX XXX enable
VERTEX_PROGRAM_CALLBACK_MESA B IsEnabled FALSE XXX XXX enable
FRAGMENT_PROGRAM_POSITION_MESA Z+ GetIntegerv -1 XXX XXX -
VERTEX_PROGRAM_POSITION_MESA Z+ GetIntegerv -1 XXX XXX -
FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA P GetPointerv NULL XXX XXX -
VERTEX_PROGRAM_CALLBACK_FUNC_MESA P GetPointerv NULL XXX XXX -
FRAGMENT_PROGRAM_CALLBACK_DATA_MESA P GetPointerv NULL XXX XXX -
VERTEX_PROGRAM_CALLBACK_DATA_MESA P GetPointerv NULL XXX XXX -
XXX more?
New Implementation Dependent State
None.
Revision History
8 July 2003
Initial draft. (Brian Paul)
11 July 2003
Second draft. (Brian Paul)
20 July 2003
Third draft. Lots of fundamental changes. (Brian Paul)
23 July 2003
Added chapter 5 and 6 spec language. (Brian Paul)
Example Usage
The following is a very simple example of how this extension may
be used to print the values of R0, R1, R2 and R3 while executing
vertex programs.
/* This is called by the GL when the vertex program is executing.
* We can only make glGet* calls from within this function!
*/
void DebugCallback(GLenum target, GLvoid *data)
{
GLint pos;
GLuint i;
/* Get PC and current instruction string */
glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_ARB, &pos);
printf("Current position: %d\n", pos);
printf("Current temporary registers:\n");
for (i = 0; i < 4; i++) {
GLfloat v[4];
char s[10];
sprintf(s, "R%d", i);
glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_ARB, strlen(s), s, v);
printf("R%d = %g, %g, %g, %g\n", i, v[0], v[1], v[2], v[3]);
}
}
/*
* elsewhere...
*/
/* Register our debugger callback function */
glProgramCallbackMESA(GL_VERTEX_PROGRAM_ARB, DebugCallback, NULL);
glEnable(GL_VERTEX_PROGRAM_CALLBACK_MESA);
/* define/bind a vertex program */
glEnable(GL_VERTEX_PROGRAM);
/* render something */
glBegin(GL_POINTS);
glVertex2f(0, 0);
glEnd();

View File

@@ -1,190 +0,0 @@
Name
MESA_sprite_point
Name Strings
GL_MESA_sprite_point
Contact
Brian Paul, VA Linux Systems Inc. (brianp 'at' valinux.com)
Status
Obsolete - see GL_ARB_point_sprite.
Version
Number
???
Dependencies
GL_EXT_point_parameters effects the definition of this extension
GL_ARB_multitexture effects the definition of this extension
Overview
This extension modifies the way in which points are rendered,
specifically when they're textured. When SPRITE_POINT_MESA is enabled
a point is rendered as if it were a quadrilateral with unique texture
coordinates at each vertex. This extension effectively turns points
into sprites which may be rendered more easily and quickly than using
conventional textured quadrilaterals.
When using point size > 1 or attenuated points this extension is an
effective way to render many small sprite images for particle systems
or other effects.
Issues:
1. How are the texture coordinates computed?
The lower-left corner has texture coordinate (0,0,r,q).
The lower-right, (1,0,r,q). The upper-right, (1,1,r,q).
The upper-left, (0,1,r,q).
2. What about texgen and texture matrices?
Texgen and the texture matrix have no effect on the point's s and t
texture coordinates. The r and q coordinates may have been computed
by texgen or the texture matrix. Note that with a 3D texture and/or
texgen that the r coordinate could be used to select a slice in the
3D texture.
3. What about point smoothing?
When point smoothing is enabled, a triangle fan could be rendered
to approximate a circular point. This could be problematic to
define and implement so POINT_SMOOTH is ignored when drawing sprite
points.
Smoothed points can be approximated by using an appropriate texture
images, alpha testing and blending.
POLYGON_SMOOTH does effect the rendering of the quadrilateral, however.
4. What about sprite rotation?
There is none. Sprite points are always rendered as window-aligned
squares. One could define rotated texture images if desired. A 3D
texture and appropriate texture r coordinates could be used to
effectively specify image rotation per point.
5. What about POLYGON_MODE?
POLYGON_MODE does not effect the rasterization of the quadrilateral.
6. What about POLYGON_CULL?
TBD. Polygon culling is normally specified and implemented in the
transformation stage of OpenGL. However, some rasterization hardware
implements it later during triangle setup.
Polygon culling wouldn't be useful for sprite points since the
quadrilaterals are always defined in counter-clockwise order in
window space. For that reason, polygon culling should probably be
ignored.
7. Should sprite points be alpha-attenuated if their size is below the
point parameter's threshold size?
8. Should there be an advertisized maximum sprite point size?
No. Since we're rendering the point as a quadrilateral there's no
need to limit the size.
New Procedures and Functions
None.
New Tokens
Accepted by the <pname> parameter of Enable, Disable, IsEnabled,
GetIntegerv, GetBooleanv, GetFloatv and GetDoublev:
SPRITE_POINT_MESA 0x????
MAX_SPRITE_POINT_SIZE_MESA 0x???? (need this?)
Additions to Chapter 2 of the 1.1 Specification (OpenGL Operation)
None
Additions to Chapter 3 of the 1.1 Specification (Rasterization)
Section ???.
When SPRITE_POINT_MESA is enabled points are rasterized as screen-
aligned quadrilaterals. If the four vertices of the quadrilateral
are labeled A, B, C, and D, starting at the lower-left corner and moving
counter-clockwise around the quadrilateral, then the vertex and
texture coordinates are computed as follows:
vertex window coordinate texture coordinate
A (x-r, y-r, z, w) (0, 0, r, q)
B (x+r, y-r, z, w) (1, 0, r, q)
C (x+r, y+r, z, w) (1, 1, r, q)
D (x-r, y+r, z, w) (0, 1, r, q)
where x, y, z, w are the point's window coordinates, r and q are the
point's 3rd and 4th texture coordinates and r is half the point's
size. The other vertex attributes (such as the color and fog coordinate)
are simply duplicated from the original point vertex.
Point size may either be specified with PointSize or computed
according to the EXT_point_parameters extension.
The new texture coordinates are not effected by texgen or the texture
matrix. Note, however, that the texture r and q coordinates are passed
unchanged and may have been computed with texgen and/or the texture
matrix.
If multiple texture units are present the same texture coordinate is
used for all texture units.
The point is then rendered as if it were a quadrilateral using the
normal point sampling rules. POLYGON_MODE does not effect the
rasterization of the quadrilateral but POLYGON_SMOOTH does.
POINT_SMOOTH has no effect when SPRITE_POINT_MESA is enabled.
Additions to Chapter 4 of the 1.1 Specification (Per-Fragment Operations
and the Frame Buffer)
None.
Additions to Chapter 5 of the 1.1 Specification (Special Functions)
None
Additions to Chapter 6 of the 1.1 Specification (State and State Requests)
None
Additions to the GLX Specification
None
GLX Protocol
TBD
Errors
None
New State
Add boolean variable SPRITE_POINT_MESA to the point attribute group.
Revision History
Version 1.0 - 4 Dec 2000
Original draft.

View File

@@ -1,359 +0,0 @@
Name
MESA_trace
Name Strings
GL_MESA_trace
Contact
Bernd Kreimeier, Loki Entertainment, bk 'at' lokigames.com
Brian Paul, VA Linux Systems, Inc., brianp 'at' valinux.com
Status
Obsolete.
Version
Number
none yet
Dependencies
OpenGL 1.2 is required.
The extension is written against the OpenGL 1.2 Specification
Overview
Provides the application with means to enable and disable logging
of GL calls including parameters as readable text. The verbosity
of the generated log can be controlled. The resulting logs are
valid (but possibly incomplete) C code and can be compiled and
linked for standalone test programs. The set of calls and the
amount of static data that is logged can be controlled at runtime.
The application can add comments and enable or disable tracing of GL
operations at any time. The data flow from the application to GL
and back is unaffected except for timing.
Application-side implementation of these features raises namespace
and linkage issues. In the driver dispatch table a simple
"chain of responsibility" pattern (aka "composable piepline")
can be added.
IP Status
The extension spec is in the public domain. The current implementation
in Mesa is covered by Mesa's XFree86-style copyright by the authors above.
This extension is partially inspired by the Quake2 QGL wrapper.
Issues
(1) Is this Extension obsolete because it can
be implemented as a wrapper DLL?
RESOLVED: No. While certain operating systems (Win32) provide linkers
that facilitate this kind of solution, other operating systems
(Linux) do not support hierarchical linking, so a wrapper solution
would result in symbol collisions.
Further, IHV's might have builtin support for tracing GL execution
that enjoys privileged access, or that they do not wish to separate
the tracing code from their driver code base.
(2) Should the Trace API explicitely support the notion of "frames?
This would require hooking into glXSwapBuffers calls as well.
RESOLVED: No. The application can use NewTraceMESA/EndTraceMESA
and TraceComment along with external parsing tools to split the
trace into frames, in whatever way considered adequate.
(2a) Should GLX calls be traced?
PBuffers and other render-to-texture solutions demonstrate that
context level commands beyond SwapBuffers might have to be
traced. The GL DLL exports the entry points, so this would not
be out of the question.
(3) Should the specification mandate the actual output format?
RESOLVED: No. It is sufficient to guarantee that all data and commands
will be traced as requested by Enable/DisableTraceMESA, in the order
encountered. Whether the resulting trace is available as a readable
text file, binary metafile, compilable source code, much less which
indentation and formatting has been used, is up to the implementation.
For the same reason this specification does not enforce or prohibit
additional information added to the trace (statistics, profiling/timing,
warnings on possible error conditions).
(4) Should the comment strings associated with names and pointer (ranges)
be considered persistent state?
RESOLVED: No. The implementation is not forced to use this information
on subsequent occurences of name/pointer, and is free to consider it
transient state.
(5) Should comment commands be prohibited between Begin/End?
RESOLVED: Yes, with the exception of TraceCommentMESA. TraceCommentMESA
is transient, the other commands might cause storage of persistent
data in the context. There is no need to have the ability mark names
or pointers between Begin and End.
New Procedures and Functions
void NewTraceMESA( bitfield mask, const ubyte * traceName )
void EndTraceMESA( void )
void EnableTraceMESA( bitfield mask )
void DisableTraceMESA( bitfield mask )
void TraceAssertAttribMESA( bitfield attribMask )
void TraceCommentMESA( const ubyte* comment )
void TraceTextureMESA( uint name, const ubyte* comment )
void TraceListMESA( uint name, const ubyte* comment )
void TracePointerMESA( void* pointer, const ubyte* comment )
void TracePointerRangeMESA( const void* first,
const void* last,
const ubyte* comment )
New Tokens
Accepted by the <mask> parameter of EnableTrace and DisableTrace:
TRACE_ALL_BITS_MESA 0xFFFF
TRACE_OPERATIONS_BIT_MESA 0x0001
TRACE_PRIMITIVES_BIT_MESA 0x0002
TRACE_ARRAYS_BIT_MESA 0x0004
TRACE_TEXTURES_BIT_MESA 0x0008
TRACE_PIXELS_BIT_MESA 0x0010
TRACE_ERRORS_BIT_MESA 0x0020
Accepted by the <pname> parameter of GetIntegerv, GetBooleanv,
GetFloatv, and GetDoublev:
TRACE_MASK_MESA 0x8755
Accepted by the <pname> parameter to GetString:
TRACE_NAME_MESA 0x8756
Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
None.
Additions to Chapter 3 of the OpenGL 1.2.1 Specification (OpenGL Operation)
None.
Additions to Chapter 4 of the OpenGL 1.2.1 Specification (OpenGL Operation)
None.
Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
Add a new section:
5.7 Tracing
The tracing facility is used to record the execution of a GL program
to a human-readable log. The log appears as a sequence of GL commands
using C syntax. The primary intention of tracing is to aid in program
debugging.
A trace is started with the command
void NewTraceMESA( bitfield mask, const GLubyte * traceName )
<mask> may be any value accepted by PushAttrib and specifies a set of
attribute groups. The state values included in those attribute groups
is written to the trace as a sequence of GL commands.
<traceName> specifies a name or label for the trace. It is expected
that <traceName> will be interpreted as a filename in most implementations.
A trace is ended by calling the command
void EndTraceMESA( void )
It is illegal to call NewTraceMESA or EndTraceMESA between Begin and End.
The commands
void EnableTraceMESA( bitfield mask )
void DisableTraceMESA( bitfield mask )
enable or disable tracing of different classes of GL commands.
<mask> may be the union of any of TRACE_OPERATIONS_BIT_MESA,
TRACE_PRIMITIVES_BIT_MESA, TRACE_ARRAYS_BIT_MESA, TRACE_TEXTURES_BIT_MESA,
and TRACE_PIXELS_BIT_MESA. The special token TRACE_ALL_BITS_MESA
indicates all classes of commands are to be logged.
TRACE_OPERATIONS_BIT_MESA controls logging of all commands outside of
Begin/End, including Begin/End.
TRACE_PRIMITIVES_BIT_MESA controls logging of all commands inside of
Begin/End, including Begin/End.
TRACE_ARRAYS_BIT_MESA controls logging of VertexPointer, NormalPointer,
ColorPointer, IndexPointer, TexCoordPointer and EdgeFlagPointer commands.
TRACE_TEXTURES_BIT_MESA controls logging of texture data dereferenced by
TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D, and
TexSubImage3D commands.
TRACE_PIXELS_BIT_MESA controls logging of image data dereferenced by
Bitmap and DrawPixels commands.
TRACE_ERRORS_BIT_MESA controls logging of all errors. If this bit is
set, GetError will be executed whereever applicable, and the result will
be added to the trace as a comment. The error returns are cached and
returned to the application on its GetError calls. If the user does not
wish the additional GetError calls to be performed, this bit should not
be set.
The command
void TraceCommentMESA( const ubyte* comment )
immediately adds the <comment> string to the trace output, surrounded
by C-style comment delimiters.
The commands
void TraceTextureMESA( uint name, const ubyte* comment )
void TraceListMESA( uint name, const ubyte* comment )
associates <comment> with the texture object or display list specified
by <name>. Logged commands which reference the named texture object or
display list will be annotated with <comment>. If IsTexture(name) or
IsList(name) fail (respectively) the command is quietly ignored.
The commands
void TracePointerMESA( void* pointer, const ubyte* comment )
void TracePointerRangeMESA( const void* first,
const void* last,
const ubyte* comment )
associate <comment> with the address specified by <pointer> or with
a range of addresses specified by <first> through <last>.
Any logged commands which reference <pointer> or an address between
<first> and <last> will be annotated with <comment>.
The command
void TraceAssertAttribMESA( bitfield attribMask )
will add GL state queries and assertion statements to the log to
confirm that the current state at the time TraceAssertAttrib is
executed matches the current state when the trace log is executed
in the future.
<attribMask> is any value accepted by PushAttrib and specifies
the groups of state variables which are to be asserted.
The commands NewTraceMESA, EndTraceMESA, EnableTraceMESA, DisableTraceMESA,
TraceAssertAttribMESA, TraceCommentMESA, TraceTextureMESA, TraceListMESA,
TracePointerMESA and TracePointerRangeMESA are not compiled into display lists.
Examples:
The command NewTraceMESA(DEPTH_BUFFER_BIT, "log") will query the state
variables DEPTH_TEST, DEPTH_FUNC, DEPTH_WRITEMASK, and DEPTH_CLEAR_VALUE
to get the values <test>, <func>, <mask>, and <clear> respectively.
Statements equivalent to the following will then be logged:
glEnable(GL_DEPTH_TEST); (if <test> is true)
glDisable(GL_DEPTH_TEST); (if <test> is false)
glDepthFunc(<func>);
glDepthMask(<mask>);
glClearDepth(<clear>);
The command TraceAssertAttribMESA(DEPTH_BUFFER_BIT) will query the state
variables DEPTH_TEST, DEPTH_FUNC, DEPTH_WRITEMASK, and DEPTH_CLEAR_VALUE
to get the values <test>, <func>, <mask>, and <clear> respectively.
The resulting trace might then look will like this:
{
GLboolean b;
GLint i;
GLfloat f;
b = glIsEnabled(GL_DEPTH_TEST);
assert(b == <test>);
glGetIntegerv(GL_DEPTH_FUNC, &i);
assert(i == <func>);
glGetIntegerv(GL_DEPTH_MASK, &i);
assert(i == <mask>);
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &f);
assert(f == <clear>);
}
Additions to Chapter 6 of the OpenGL 1.2.1 Specification
(State and State Requests)
Querying TRACE_MASK_MESA with GetIntegerv, GetFloatv, GetBooleanv or
GetDoublev returns the current command class trace mask.
Querying TRACE_NAME_MESA with GetString returns the current trace name.
Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
The MESA_trace extension can be used in a way that does not affect data
flow from application to OpenGL, as well as data flow from OpenGL to
application, except for timing, possible print I/O. TRACE_ERRORS_BIT_MESA
will add additional GetError queries. Setting a trace mask with NewTraceMESA
as well as use of TraceAssertAttribMESA might cause additional state queries.
With the possible exception of performance, OpenGL rendering should not be
affected at all by a properly chosen logging operation.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
None. The logging operation is carried out client-side, by exporting
entry points to the wrapper functions that execute the logging operation.
Errors
INVALID_OPERATION is generated if any trace command except TraceCommentMESA
is called between Begin and End.
New State
The current trace name and current command class mask are stored
per-context.
New Implementation Dependent State
None.
Revision History
* Revision 0.1 - Initial draft from template (bk000415)
* Revision 0.2 - Draft (bk000906)
* Revision 0.3 - Draft (bk000913)
* Revision 0.4 - Reworked text, fixed typos (bp000914)
* Revision 0.5 - Assigned final GLenum values (bp001103)
* Revision 0.6 - TRACE_ERRORS_BIT_MESA (bk000916)
* Revision 0.7 - Added MESA postfix (bk010126)

View File

@@ -48,7 +48,7 @@ a:visited {
<li><a href="lists.html" target="MainFrame">Mailing Lists</a>
<li><a href="bugs.html" target="MainFrame">Bug Database</a>
<li><a href="webmaster.html" target="MainFrame">Webmaster</a>
<li><a href="http://dri.freedesktop.org/" target="MainFrame">Wiki</a>
<li><a href="http://dri.freedesktop.org/" target="_parent">Mesa/DRI Wiki</a>
</ul>
<b>User Topics</b>

View File

@@ -9,9 +9,9 @@
<H1>Downloading</H1>
<p>
Current development release: <b>7.3</b>
Current stable release: <b>7.4</b>
<br>
Last stable release: <b>7.2</b>
Last unstable/development release: <b>7.3</b>
</p>
<p>

View File

@@ -29,7 +29,7 @@ Setting this variable automatically sets the MESA_TEX_PROG variable as well.
<p>
The following are only applicable to the Xlib software driver.
See <A HREF="README.X11">README.X11</A> for details.
See the <A HREF="xlibdriver.html">Xlib software driver page</A> for details.
</p>
<ul>
<li>MESA_RGB_VISUAL - specifies the X visual and depth for RGB mode

View File

@@ -15,17 +15,40 @@ Here are some specific ideas and areas where help would be appreciated:
<ol>
<li>
Enable -Wstrict-aliasing=2 -fstrict-aliasing and track down aliasing
<b>Driver patching and testing.</b>
Patches are often posted to the mesa3d-dev mailing list, but aren't
immediately checked into git because not enough people are testing them.
Just applying patches, testing and reporting back is helpful.
<li>
<b>Driver debugging.</b>
There are plenty of open bugs in the bug database.
<li>
<b>Remove aliasing warnings.</b>
Enable gcc -Wstrict-aliasing=2 -fstrict-aliasing and track down aliasing
issues in the code.
<li>
Windows 98/NT driver building, maintenance and testing
<b>Windows driver building, testing and maintenance.</b>
The Visual Studio project files aren't always updated in a timely manner
when new source files are added or old ones are removed.
Fixing these tends to delay new Mesa releases.
<li>
Maintenance and testing of lesser-used drivers, such as DOS/DJGPP, GGI, etc.
<b>Maintenance and testing of lesser-used drivers.</b>
Drivers such as DOS/DJGPP, GGI, etc that aren't being maintained are being
deprecated starting in Mesa 7.3.
<li>
<b>Contribute more tests to
<a href="http://glean.sourceforge.net/" target="_parent">glean</a>.</b>
<li>
<b>Automatic testing.
</b>
It would be great if someone would set up an automated system for grabbing
the latest Mesa code and run tests (such as glean) then report issues to
the mailing list.
</ol>
<p>
If you want to help with Mesa, first join the Mesa developer's
If you want to do something new in Mesa, first join the Mesa developer's
mailing list.
Then post a message to propose what you want to do, just to make sure
there's no issues.

View File

@@ -11,10 +11,18 @@
<H1>News</H1>
<h2>January TBD, 2009</h2>
<h2>March 27, 2009</h2>
<p>
<a href="relnotes-7.4.html">Mesa 7.4</a> is released.
This is a stable release fixing bugs since the 7.3 release.
</p>
<h2>January 22, 2009</h2>
<p>
<a href="relnotes-7.3.html">Mesa 7.3</a> is released.
This is a new development release.
Mesa 7.4 will follow and will have bug fixes relative to 7.3.
</p>

View File

@@ -8,7 +8,7 @@
<body bgcolor="#eeeeee">
<H1>Mesa 7.3 Release Notes / TBD January 2009</H1>
<H1>Mesa 7.3 Release Notes / 22 January 2009</H1>
<p>
Mesa 7.3 is a new development release.
@@ -22,13 +22,21 @@ Some drivers don't support all the features required in OpenGL 2.1.
</p>
<p>
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
for DRI ardware acceleration.
for DRI hardware acceleration.
</p>
<h2>MD5 checksums</h2>
<pre>
tbd
8ed03191432b22d118d88d6db497f304 MesaLib-7.3.tar.gz
781e7811a6ed5c97b2b8defefc8ffbc9 MesaLib-7.3.tar.bz2
3ccba9a1734ed6d4b3389e1535d90fbf MesaLib-7.3.zip
d312e974b31043b13b61bac5fbf00b87 MesaDemos-7.3.tar.gz
3f0741394069bdf2329565a387396cda MesaDemos-7.3.tar.bz2
4d0887fd4c66a824295cdd619f6d34cb MesaDemos-7.3.zip
2d7661b66022bcb8878728f3d5bd33ab MesaGLUT-7.3.tar.gz
abe8036a724c1a483bdad6b5a55ddc1a MesaGLUT-7.3.tar.bz2
5f247819b47e2a7c62d07a6afe5262fb MesaGLUT-7.3.zip
</pre>
@@ -47,6 +55,8 @@ tbd
<li>Build fixes for OpenBSD and gcc 2.95
<li>GLSL preprocessor handles #pragma now
<li>Fix incorrect transformation of GL_SPOT_DIRECTION
<li>Fixed several bugs (#18367 and #19625) in glXMakeContextCurrent()
<li>Assorted Windows build fixes
</ul>
<h2>Changes</h2>

81
docs/relnotes-7.4.html Normal file
View File

@@ -0,0 +1,81 @@
<HTML>
<TITLE>Mesa Release Notes</TITLE>
<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
<BODY>
<body bgcolor="#eeeeee">
<H1>Mesa 7.4 Release Notes / 27 March 2009</H1>
<p>
Mesa 7.4 is a stable development release fixing bugs since the 7.3 release.
</p>
<p>
Mesa 7.4 implements the OpenGL 2.1 API, but the version reported by
glGetString(GL_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 2.1.
</p>
<p>
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
for DRI ardware acceleration.
</p>
<h2>MD5 checksums</h2>
<pre>
tbd
</pre>
<h2>New features</h2>
<ul>
<li>Added MESA_GLX_FORCE_DIRECT env var for Xlib/software driver
<li>GLSL version 1.20 is returnd by the GL_SHADING_LANGUAGE_VERSION query
</ul>
<h2>Bug fixes</h2>
<ul>
<li>glGetActiveUniform() returned wrong size for some array types
<li>Fixed some error checking in glUniform()
<li>Fixed a potential glTexImage('proxy target') segfault
<li>Fixed bad reference counting for 1D/2D texture arrays
<li>Fixed VBO + glPush/PopClientAttrib() bug #19835
<li>Assorted i965 driver bug fixes
<li>Fixed a Windows compilation failure in s_triangle.c
<li>Fixed a GLSL array indexing bug
<li>Fixes for building on Haiku
</ul>
<h2>Changes</h2>
<ul>
<li>Updated GL/glxext.h to version 48
<li>Assorted updates for building on Solaris
</ul>
<h2>Driver Status</h2>
<pre>
Driver Status
---------------------- ----------------------
DRI drivers varies with the driver
XMesa/GLX (on Xlib) implements OpenGL 2.1
OSMesa (off-screen) implements OpenGL 2.1
Windows/Win32 implements OpenGL 2.1
Glide (3dfx Voodoo1/2) implements OpenGL 1.3
SVGA unsupported
Wind River UGL unsupported
DJGPP unsupported
GGI unsupported
BeOS unsupported
Allegro unsupported
D3D unsupported
</pre>
</body>
</html>

View File

@@ -20,6 +20,7 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<UL>
<LI><A HREF="relnotes-7.4.html">7.4 release notes</A>
<LI><A HREF="relnotes-7.3.html">7.3 release notes</A>
<LI><A HREF="relnotes-7.2.html">7.2 release notes</A>
<LI><A HREF="relnotes-7.1.html">7.1 release notes</A>

View File

@@ -27,16 +27,27 @@ the Amiga, Apple Macintosh, BeOS, NeXT, OS/2, MS-DOS, VMS, Windows
</p>
<p>
Details about particular drivers follows.
Be warned that some drivers may be out of date and no longer function.
Details about particular drivers follows:
</p>
<UL>
<LI><a href="xlibdriver.html">Xlib driver</a> for the X Window System
<li><a href="http://dri.freedesktop.org/" target="_parent">
DRI hardware drivers</a> for the X window system
<li><a href="http://dri.freedesktop.org/" target="_parent"> DRI hardware
drivers</a> for the X Window System
<LI><a href="xlibdriver.html">Xlib software driver</a> for the X Window System
and Unix-like operating systems
<LI>Microsoft Windows <A HREF="README.WIN32">(README.WIN32)</A>
<LI>DEC VMS <A HREF="README.VMS">(README.VMS)</A>
</UL>
<h2>Deprecated Systems</h2>
<p>
These drivers have not been maintained and are being deprecated.
They can be saved if someone steps up to help.
</p>
<UL>
<LI>3dfx/Glide <A HREF="README.3DFX">(README.3DFX)</A>
<LI>GGI <A HREF="README.GGI">(README.GGI)</A>
<LI>Amiga Amiwin <A HREF="README.AMIWIN">(README.AMIWIN)</A>
@@ -49,6 +60,10 @@ DRI hardware drivers</a> for the X window system
<LI>OpenStep <A HREF="README.OpenStep">(README.OpenStep)</A>
<LI>OS/2 <A HREF="README.OS2">(README.OS2)</A>
<LI>WindML <A HREF="README.WINDML">(README.WINDML)</A>
</UL>
And for historical reference:
<UL>
<LI><a href="http://utah-glx.sourceforge.net/" target="_parent">Utah GLX drivers</a>
</UL>

View File

@@ -169,6 +169,20 @@ the Gamma FAQ</a>
</p>
<H2>Direct Rendering Flag</H2>
<p>
Some applications won't run with indirect rendering contexts (which is
what the Xlib driver supports).
To force the glXIsDirect() query to return True, set the MESA_GLX_FORCE_DIRECT
environment variable.
For example:
</p>
<pre>
$ export MESA_GLX_FORCE_DIRECT=1
</pre>
<H2>Overlay Planes</H2>
<p>
Hardware overlay planes are supported by the Xlib driver. To
@@ -268,6 +282,8 @@ This extension was added in Mesa 2.6
MESA_BACK_BUFFER - specifies how to implement the back color buffer (X only)
MESA_PRIVATE_CMAP - force aux/tk libraries to use private colormaps (X only)
MESA_GAMMA - gamma correction coefficients (X only)
MESA_GLX_FORCE_DIRECT - report that the driver is direct rendering, even
though it's not.
</pre>

View File

@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.1
* Version: 7.4
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*

View File

@@ -48,34 +48,49 @@
#define glAsyncMarkerSGIX MANGLE(AsyncMarkerSGIX)
#define glAttachObjectARB MANGLE(AttachObjectARB)
#define glAttachShader MANGLE(AttachShader)
#define glBeginConditionalRender MANGLE(BeginConditionalRender)
#define glBeginConditionalRenderNV MANGLE(BeginConditionalRenderNV)
#define glBeginFragmentShaderATI MANGLE(BeginFragmentShaderATI)
#define glBegin MANGLE(Begin)
#define glBeginOcclusionQueryNV MANGLE(BeginOcclusionQueryNV)
#define glBeginQueryARB MANGLE(BeginQueryARB)
#define glBeginQuery MANGLE(BeginQuery)
#define glBeginTransformFeedbackEXT MANGLE(BeginTransformFeedbackEXT)
#define glBeginTransformFeedback MANGLE(BeginTransformFeedback)
#define glBeginTransformFeedbackNV MANGLE(BeginTransformFeedbackNV)
#define glBeginVertexShaderEXT MANGLE(BeginVertexShaderEXT)
#define glBindAttribLocationARB MANGLE(BindAttribLocationARB)
#define glBindAttribLocation MANGLE(BindAttribLocation)
#define glBindBufferARB MANGLE(BindBufferARB)
#define glBindBufferBaseEXT MANGLE(BindBufferBaseEXT)
#define glBindBufferBase MANGLE(BindBufferBase)
#define glBindBufferBaseNV MANGLE(BindBufferBaseNV)
#define glBindBuffer MANGLE(BindBuffer)
#define glBindBufferOffsetEXT MANGLE(BindBufferOffsetEXT)
#define glBindBufferOffsetNV MANGLE(BindBufferOffsetNV)
#define glBindBufferRangeEXT MANGLE(BindBufferRangeEXT)
#define glBindBufferRange MANGLE(BindBufferRange)
#define glBindBufferRangeNV MANGLE(BindBufferRangeNV)
#define glBindFragDataLocationEXT MANGLE(BindFragDataLocationEXT)
#define glBindFragDataLocation MANGLE(BindFragDataLocation)
#define glBindFragmentShaderATI MANGLE(BindFragmentShaderATI)
#define glBindFramebufferEXT MANGLE(BindFramebufferEXT)
#define glBindFramebuffer MANGLE(BindFramebuffer)
#define glBindLightParameterEXT MANGLE(BindLightParameterEXT)
#define glBindMaterialParameterEXT MANGLE(BindMaterialParameterEXT)
#define glBindMultiTextureEXT MANGLE(BindMultiTextureEXT)
#define glBindParameterEXT MANGLE(BindParameterEXT)
#define glBindProgramARB MANGLE(BindProgramARB)
#define glBindProgramNV MANGLE(BindProgramNV)
#define glBindRenderbufferEXT MANGLE(BindRenderbufferEXT)
#define glBindRenderbuffer MANGLE(BindRenderbuffer)
#define glBindTexGenParameterEXT MANGLE(BindTexGenParameterEXT)
#define glBindTextureEXT MANGLE(BindTextureEXT)
#define glBindTexture MANGLE(BindTexture)
#define glBindTextureUnitParameterEXT MANGLE(BindTextureUnitParameterEXT)
#define glBindTransformFeedbackNV MANGLE(BindTransformFeedbackNV)
#define glBindVertexArrayAPPLE MANGLE(BindVertexArrayAPPLE)
#define glBindVertexArray MANGLE(BindVertexArray)
#define glBindVertexShaderEXT MANGLE(BindVertexShaderEXT)
#define glBinormal3bEXT MANGLE(Binormal3bEXT)
#define glBinormal3bvEXT MANGLE(Binormal3bvEXT)
@@ -101,6 +116,7 @@
#define glBlendFuncSeparateINGR MANGLE(BlendFuncSeparateINGR)
#define glBlendFuncSeparate MANGLE(BlendFuncSeparate)
#define glBlitFramebufferEXT MANGLE(BlitFramebufferEXT)
#define glBlitFramebuffer MANGLE(BlitFramebuffer)
#define glBufferDataARB MANGLE(BufferDataARB)
#define glBufferData MANGLE(BufferData)
#define glBufferParameteriAPPLE MANGLE(BufferParameteriAPPLE)
@@ -109,8 +125,15 @@
#define glCallList MANGLE(CallList)
#define glCallLists MANGLE(CallLists)
#define glCheckFramebufferStatusEXT MANGLE(CheckFramebufferStatusEXT)
#define glCheckFramebufferStatus MANGLE(CheckFramebufferStatus)
#define glCheckNamedFramebufferStatusEXT MANGLE(CheckNamedFramebufferStatusEXT)
#define glClampColorARB MANGLE(ClampColorARB)
#define glClampColor MANGLE(ClampColor)
#define glClearAccum MANGLE(ClearAccum)
#define glClearBufferfi MANGLE(ClearBufferfi)
#define glClearBufferfv MANGLE(ClearBufferfv)
#define glClearBufferiv MANGLE(ClearBufferiv)
#define glClearBufferuiv MANGLE(ClearBufferuiv)
#define glClearColorIiEXT MANGLE(ClearColorIiEXT)
#define glClearColorIuiEXT MANGLE(ClearColorIuiEXT)
#define glClearColor MANGLE(ClearColor)
@@ -123,6 +146,7 @@
#define glClientActiveTextureARB MANGLE(ClientActiveTextureARB)
#define glClientActiveTexture MANGLE(ClientActiveTexture)
#define glClientActiveVertexStreamATI MANGLE(ClientActiveVertexStreamATI)
#define glClientAttribDefaultEXT MANGLE(ClientAttribDefaultEXT)
#define glClipPlane MANGLE(ClipPlane)
#define glColor3b MANGLE(Color3b)
#define glColor3bv MANGLE(Color3bv)
@@ -171,6 +195,7 @@
#define glColorFragmentOp1ATI MANGLE(ColorFragmentOp1ATI)
#define glColorFragmentOp2ATI MANGLE(ColorFragmentOp2ATI)
#define glColorFragmentOp3ATI MANGLE(ColorFragmentOp3ATI)
#define glColorMaski MANGLE(ColorMaski)
#define glColorMaskIndexedEXT MANGLE(ColorMaskIndexedEXT)
#define glColorMask MANGLE(ColorMask)
#define glColorMaterial MANGLE(ColorMaterial)
@@ -196,6 +221,12 @@
#define glCombinerStageParameterfvNV MANGLE(CombinerStageParameterfvNV)
#define glCompileShaderARB MANGLE(CompileShaderARB)
#define glCompileShader MANGLE(CompileShader)
#define glCompressedMultiTexImage1DEXT MANGLE(CompressedMultiTexImage1DEXT)
#define glCompressedMultiTexImage2DEXT MANGLE(CompressedMultiTexImage2DEXT)
#define glCompressedMultiTexImage3DEXT MANGLE(CompressedMultiTexImage3DEXT)
#define glCompressedMultiTexSubImage1DEXT MANGLE(CompressedMultiTexSubImage1DEXT)
#define glCompressedMultiTexSubImage2DEXT MANGLE(CompressedMultiTexSubImage2DEXT)
#define glCompressedMultiTexSubImage3DEXT MANGLE(CompressedMultiTexSubImage3DEXT)
#define glCompressedTexImage1DARB MANGLE(CompressedTexImage1DARB)
#define glCompressedTexImage1D MANGLE(CompressedTexImage1D)
#define glCompressedTexImage2DARB MANGLE(CompressedTexImage2DARB)
@@ -208,6 +239,12 @@
#define glCompressedTexSubImage2D MANGLE(CompressedTexSubImage2D)
#define glCompressedTexSubImage3DARB MANGLE(CompressedTexSubImage3DARB)
#define glCompressedTexSubImage3D MANGLE(CompressedTexSubImage3D)
#define glCompressedTextureImage1DEXT MANGLE(CompressedTextureImage1DEXT)
#define glCompressedTextureImage2DEXT MANGLE(CompressedTextureImage2DEXT)
#define glCompressedTextureImage3DEXT MANGLE(CompressedTextureImage3DEXT)
#define glCompressedTextureSubImage1DEXT MANGLE(CompressedTextureSubImage1DEXT)
#define glCompressedTextureSubImage2DEXT MANGLE(CompressedTextureSubImage2DEXT)
#define glCompressedTextureSubImage3DEXT MANGLE(CompressedTextureSubImage3DEXT)
#define glConvolutionFilter1DEXT MANGLE(ConvolutionFilter1DEXT)
#define glConvolutionFilter1D MANGLE(ConvolutionFilter1D)
#define glConvolutionFilter2DEXT MANGLE(ConvolutionFilter2DEXT)
@@ -228,6 +265,11 @@
#define glCopyConvolutionFilter1D MANGLE(CopyConvolutionFilter1D)
#define glCopyConvolutionFilter2DEXT MANGLE(CopyConvolutionFilter2DEXT)
#define glCopyConvolutionFilter2D MANGLE(CopyConvolutionFilter2D)
#define glCopyMultiTexImage1DEXT MANGLE(CopyMultiTexImage1DEXT)
#define glCopyMultiTexImage2DEXT MANGLE(CopyMultiTexImage2DEXT)
#define glCopyMultiTexSubImage1DEXT MANGLE(CopyMultiTexSubImage1DEXT)
#define glCopyMultiTexSubImage2DEXT MANGLE(CopyMultiTexSubImage2DEXT)
#define glCopyMultiTexSubImage3DEXT MANGLE(CopyMultiTexSubImage3DEXT)
#define glCopyPixels MANGLE(CopyPixels)
#define glCopyTexImage1DEXT MANGLE(CopyTexImage1DEXT)
#define glCopyTexImage1D MANGLE(CopyTexImage1D)
@@ -239,6 +281,11 @@
#define glCopyTexSubImage2D MANGLE(CopyTexSubImage2D)
#define glCopyTexSubImage3DEXT MANGLE(CopyTexSubImage3DEXT)
#define glCopyTexSubImage3D MANGLE(CopyTexSubImage3D)
#define glCopyTextureImage1DEXT MANGLE(CopyTextureImage1DEXT)
#define glCopyTextureImage2DEXT MANGLE(CopyTextureImage2DEXT)
#define glCopyTextureSubImage1DEXT MANGLE(CopyTextureSubImage1DEXT)
#define glCopyTextureSubImage2DEXT MANGLE(CopyTextureSubImage2DEXT)
#define glCopyTextureSubImage3DEXT MANGLE(CopyTextureSubImage3DEXT)
#define glCreateDebugObjectMESA MANGLE(CreateDebugObjectMESA)
#define glCreateProgram MANGLE(CreateProgram)
#define glCreateProgramObjectARB MANGLE(CreateProgramObjectARB)
@@ -258,6 +305,7 @@
#define glDeleteFencesNV MANGLE(DeleteFencesNV)
#define glDeleteFragmentShaderATI MANGLE(DeleteFragmentShaderATI)
#define glDeleteFramebuffersEXT MANGLE(DeleteFramebuffersEXT)
#define glDeleteFramebuffers MANGLE(DeleteFramebuffers)
#define glDeleteLists MANGLE(DeleteLists)
#define glDeleteObjectARB MANGLE(DeleteObjectARB)
#define glDeleteOcclusionQueriesNV MANGLE(DeleteOcclusionQueriesNV)
@@ -267,10 +315,13 @@
#define glDeleteQueriesARB MANGLE(DeleteQueriesARB)
#define glDeleteQueries MANGLE(DeleteQueries)
#define glDeleteRenderbuffersEXT MANGLE(DeleteRenderbuffersEXT)
#define glDeleteRenderbuffers MANGLE(DeleteRenderbuffers)
#define glDeleteShader MANGLE(DeleteShader)
#define glDeleteTexturesEXT MANGLE(DeleteTexturesEXT)
#define glDeleteTextures MANGLE(DeleteTextures)
#define glDeleteTransformFeedbacksNV MANGLE(DeleteTransformFeedbacksNV)
#define glDeleteVertexArraysAPPLE MANGLE(DeleteVertexArraysAPPLE)
#define glDeleteVertexArrays MANGLE(DeleteVertexArrays)
#define glDeleteVertexShaderEXT MANGLE(DeleteVertexShaderEXT)
#define glDepthBoundsdNV MANGLE(DepthBoundsdNV)
#define glDepthBoundsEXT MANGLE(DepthBoundsEXT)
@@ -281,13 +332,16 @@
#define glDetachObjectARB MANGLE(DetachObjectARB)
#define glDetachShader MANGLE(DetachShader)
#define glDetailTexFuncSGIS MANGLE(DetailTexFuncSGIS)
#define glDisableClientStateIndexedEXT MANGLE(DisableClientStateIndexedEXT)
#define glDisableClientState MANGLE(DisableClientState)
#define glDisablei MANGLE(Disablei)
#define glDisableIndexedEXT MANGLE(DisableIndexedEXT)
#define glDisable MANGLE(Disable)
#define glDisableVariantClientStateEXT MANGLE(DisableVariantClientStateEXT)
#define glDisableVertexAttribArrayARB MANGLE(DisableVertexAttribArrayARB)
#define glDisableVertexAttribArray MANGLE(DisableVertexAttribArray)
#define glDrawArraysEXT MANGLE(DrawArraysEXT)
#define glDrawArraysInstancedARB MANGLE(DrawArraysInstancedARB)
#define glDrawArraysInstancedEXT MANGLE(DrawArraysInstancedEXT)
#define glDrawArrays MANGLE(DrawArrays)
#define glDrawBuffer MANGLE(DrawBuffer)
@@ -296,6 +350,7 @@
#define glDrawBuffers MANGLE(DrawBuffers)
#define glDrawElementArrayAPPLE MANGLE(DrawElementArrayAPPLE)
#define glDrawElementArrayATI MANGLE(DrawElementArrayATI)
#define glDrawElementsInstancedARB MANGLE(DrawElementsInstancedARB)
#define glDrawElementsInstancedEXT MANGLE(DrawElementsInstancedEXT)
#define glDrawElements MANGLE(DrawElements)
#define glDrawMeshArraysSUN MANGLE(DrawMeshArraysSUN)
@@ -304,6 +359,7 @@
#define glDrawRangeElementArrayATI MANGLE(DrawRangeElementArrayATI)
#define glDrawRangeElementsEXT MANGLE(DrawRangeElementsEXT)
#define glDrawRangeElements MANGLE(DrawRangeElements)
#define glDrawTransformFeedbackNV MANGLE(DrawTransformFeedbackNV)
#define glEdgeFlag MANGLE(EdgeFlag)
#define glEdgeFlagPointerEXT MANGLE(EdgeFlagPointerEXT)
#define glEdgeFlagPointerListIBM MANGLE(EdgeFlagPointerListIBM)
@@ -311,18 +367,24 @@
#define glEdgeFlagv MANGLE(EdgeFlagv)
#define glElementPointerAPPLE MANGLE(ElementPointerAPPLE)
#define glElementPointerATI MANGLE(ElementPointerATI)
#define glEnableClientStateIndexedEXT MANGLE(EnableClientStateIndexedEXT)
#define glEnableClientState MANGLE(EnableClientState)
#define glEnablei MANGLE(Enablei)
#define glEnableIndexedEXT MANGLE(EnableIndexedEXT)
#define glEnable MANGLE(Enable)
#define glEnableVariantClientStateEXT MANGLE(EnableVariantClientStateEXT)
#define glEnableVertexAttribArrayARB MANGLE(EnableVertexAttribArrayARB)
#define glEnableVertexAttribArray MANGLE(EnableVertexAttribArray)
#define glEndConditionalRender MANGLE(EndConditionalRender)
#define glEndConditionalRenderNV MANGLE(EndConditionalRenderNV)
#define glEndFragmentShaderATI MANGLE(EndFragmentShaderATI)
#define glEndList MANGLE(EndList)
#define glEnd MANGLE(End)
#define glEndOcclusionQueryNV MANGLE(EndOcclusionQueryNV)
#define glEndQueryARB MANGLE(EndQueryARB)
#define glEndQuery MANGLE(EndQuery)
#define glEndTransformFeedbackEXT MANGLE(EndTransformFeedbackEXT)
#define glEndTransformFeedback MANGLE(EndTransformFeedback)
#define glEndTransformFeedbackNV MANGLE(EndTransformFeedbackNV)
#define glEndVertexShaderEXT MANGLE(EndVertexShaderEXT)
#define glEvalCoord1d MANGLE(EvalCoord1d)
@@ -350,6 +412,7 @@
#define glFinishTextureSUNX MANGLE(FinishTextureSUNX)
#define glFlush MANGLE(Flush)
#define glFlushMappedBufferRangeAPPLE MANGLE(FlushMappedBufferRangeAPPLE)
#define glFlushMappedBufferRange MANGLE(FlushMappedBufferRange)
#define glFlushPixelDataRangeNV MANGLE(FlushPixelDataRangeNV)
#define glFlushRasterSGIX MANGLE(FlushRasterSGIX)
#define glFlushVertexArrayRangeAPPLE MANGLE(FlushVertexArrayRangeAPPLE)
@@ -385,13 +448,25 @@
#define glFragmentMaterialfvSGIX MANGLE(FragmentMaterialfvSGIX)
#define glFragmentMaterialiSGIX MANGLE(FragmentMaterialiSGIX)
#define glFragmentMaterialivSGIX MANGLE(FragmentMaterialivSGIX)
#define glFramebufferDrawBufferEXT MANGLE(FramebufferDrawBufferEXT)
#define glFramebufferDrawBuffersEXT MANGLE(FramebufferDrawBuffersEXT)
#define glFramebufferReadBufferEXT MANGLE(FramebufferReadBufferEXT)
#define glFramebufferRenderbufferEXT MANGLE(FramebufferRenderbufferEXT)
#define glFramebufferRenderbuffer MANGLE(FramebufferRenderbuffer)
#define glFramebufferTexture1DEXT MANGLE(FramebufferTexture1DEXT)
#define glFramebufferTexture1D MANGLE(FramebufferTexture1D)
#define glFramebufferTexture2DEXT MANGLE(FramebufferTexture2DEXT)
#define glFramebufferTexture2D MANGLE(FramebufferTexture2D)
#define glFramebufferTexture3DEXT MANGLE(FramebufferTexture3DEXT)
#define glFramebufferTexture3D MANGLE(FramebufferTexture3D)
#define glFramebufferTextureARB MANGLE(FramebufferTextureARB)
#define glFramebufferTextureEXT MANGLE(FramebufferTextureEXT)
#define glFramebufferTextureFaceARB MANGLE(FramebufferTextureFaceARB)
#define glFramebufferTextureFaceEXT MANGLE(FramebufferTextureFaceEXT)
#define glFramebufferTextureLayerARB MANGLE(FramebufferTextureLayerARB)
#define glFramebufferTextureLayerEXT MANGLE(FramebufferTextureLayerEXT)
#define glFramebufferTextureLayer MANGLE(FramebufferTextureLayer)
#define glFrameTerminatorGREMEDY MANGLE(FrameTerminatorGREMEDY)
#define glFrameZoomSGIX MANGLE(FrameZoomSGIX)
#define glFreeObjectBufferATI MANGLE(FreeObjectBufferATI)
#define glFrontFace MANGLE(FrontFace)
@@ -400,10 +475,14 @@
#define glGenBuffersARB MANGLE(GenBuffersARB)
#define glGenBuffers MANGLE(GenBuffers)
#define glGenerateMipmapEXT MANGLE(GenerateMipmapEXT)
#define glGenerateMipmap MANGLE(GenerateMipmap)
#define glGenerateMultiTexMipmapEXT MANGLE(GenerateMultiTexMipmapEXT)
#define glGenerateTextureMipmapEXT MANGLE(GenerateTextureMipmapEXT)
#define glGenFencesAPPLE MANGLE(GenFencesAPPLE)
#define glGenFencesNV MANGLE(GenFencesNV)
#define glGenFragmentShadersATI MANGLE(GenFragmentShadersATI)
#define glGenFramebuffersEXT MANGLE(GenFramebuffersEXT)
#define glGenFramebuffers MANGLE(GenFramebuffers)
#define glGenLists MANGLE(GenLists)
#define glGenOcclusionQueriesNV MANGLE(GenOcclusionQueriesNV)
#define glGenProgramsARB MANGLE(GenProgramsARB)
@@ -411,10 +490,13 @@
#define glGenQueriesARB MANGLE(GenQueriesARB)
#define glGenQueries MANGLE(GenQueries)
#define glGenRenderbuffersEXT MANGLE(GenRenderbuffersEXT)
#define glGenRenderbuffers MANGLE(GenRenderbuffers)
#define glGenSymbolsEXT MANGLE(GenSymbolsEXT)
#define glGenTexturesEXT MANGLE(GenTexturesEXT)
#define glGenTextures MANGLE(GenTextures)
#define glGenTransformFeedbacksNV MANGLE(GenTransformFeedbacksNV)
#define glGenVertexArraysAPPLE MANGLE(GenVertexArraysAPPLE)
#define glGenVertexArrays MANGLE(GenVertexArrays)
#define glGenVertexShadersEXT MANGLE(GenVertexShadersEXT)
#define glGetActiveAttribARB MANGLE(GetActiveAttribARB)
#define glGetActiveAttrib MANGLE(GetActiveAttrib)
@@ -428,6 +510,7 @@
#define glGetAttribLocationARB MANGLE(GetAttribLocationARB)
#define glGetAttribLocation MANGLE(GetAttribLocation)
#define glGetBooleanIndexedvEXT MANGLE(GetBooleanIndexedvEXT)
#define glGetBooleani_v MANGLE(GetBooleani_v)
#define glGetBooleanv MANGLE(GetBooleanv)
#define glGetBufferParameterivARB MANGLE(GetBufferParameterivARB)
#define glGetBufferParameteriv MANGLE(GetBufferParameteriv)
@@ -450,8 +533,10 @@
#define glGetCombinerOutputParameterfvNV MANGLE(GetCombinerOutputParameterfvNV)
#define glGetCombinerOutputParameterivNV MANGLE(GetCombinerOutputParameterivNV)
#define glGetCombinerStageParameterfvNV MANGLE(GetCombinerStageParameterfvNV)
#define glGetCompressedMultiTexImageEXT MANGLE(GetCompressedMultiTexImageEXT)
#define glGetCompressedTexImageARB MANGLE(GetCompressedTexImageARB)
#define glGetCompressedTexImage MANGLE(GetCompressedTexImage)
#define glGetCompressedTextureImageEXT MANGLE(GetCompressedTextureImageEXT)
#define glGetConvolutionFilterEXT MANGLE(GetConvolutionFilterEXT)
#define glGetConvolutionFilter MANGLE(GetConvolutionFilter)
#define glGetConvolutionParameterfvEXT MANGLE(GetConvolutionParameterfvEXT)
@@ -461,19 +546,24 @@
#define glGetDebugLogLengthMESA MANGLE(GetDebugLogLengthMESA)
#define glGetDebugLogMESA MANGLE(GetDebugLogMESA)
#define glGetDetailTexFuncSGIS MANGLE(GetDetailTexFuncSGIS)
#define glGetDoubleIndexedvEXT MANGLE(GetDoubleIndexedvEXT)
#define glGetDoublev MANGLE(GetDoublev)
#define glGetError MANGLE(GetError)
#define glGetFenceivNV MANGLE(GetFenceivNV)
#define glGetFinalCombinerInputParameterfvNV MANGLE(GetFinalCombinerInputParameterfvNV)
#define glGetFinalCombinerInputParameterivNV MANGLE(GetFinalCombinerInputParameterivNV)
#define glGetFloatIndexedvEXT MANGLE(GetFloatIndexedvEXT)
#define glGetFloatv MANGLE(GetFloatv)
#define glGetFogFuncSGIS MANGLE(GetFogFuncSGIS)
#define glGetFragDataLocationEXT MANGLE(GetFragDataLocationEXT)
#define glGetFragDataLocation MANGLE(GetFragDataLocation)
#define glGetFragmentLightfvSGIX MANGLE(GetFragmentLightfvSGIX)
#define glGetFragmentLightivSGIX MANGLE(GetFragmentLightivSGIX)
#define glGetFragmentMaterialfvSGIX MANGLE(GetFragmentMaterialfvSGIX)
#define glGetFragmentMaterialivSGIX MANGLE(GetFragmentMaterialivSGIX)
#define glGetFramebufferAttachmentParameterivEXT MANGLE(GetFramebufferAttachmentParameterivEXT)
#define glGetFramebufferAttachmentParameteriv MANGLE(GetFramebufferAttachmentParameteriv)
#define glGetFramebufferParameterivEXT MANGLE(GetFramebufferParameterivEXT)
#define glGetHandleARB MANGLE(GetHandleARB)
#define glGetHistogramEXT MANGLE(GetHistogramEXT)
#define glGetHistogram MANGLE(GetHistogram)
@@ -486,6 +576,7 @@
#define glGetInfoLogARB MANGLE(GetInfoLogARB)
#define glGetInstrumentsSGIX MANGLE(GetInstrumentsSGIX)
#define glGetIntegerIndexedvEXT MANGLE(GetIntegerIndexedvEXT)
#define glGetIntegeri_v MANGLE(GetIntegeri_v)
#define glGetIntegerv MANGLE(GetIntegerv)
#define glGetInvariantBooleanvEXT MANGLE(GetInvariantBooleanvEXT)
#define glGetInvariantFloatvEXT MANGLE(GetInvariantFloatvEXT)
@@ -513,6 +604,30 @@
#define glGetMinmaxParameterfv MANGLE(GetMinmaxParameterfv)
#define glGetMinmaxParameterivEXT MANGLE(GetMinmaxParameterivEXT)
#define glGetMinmaxParameteriv MANGLE(GetMinmaxParameteriv)
#define glGetMultisamplefvNV MANGLE(GetMultisamplefvNV)
#define glGetMultiTexEnvfvEXT MANGLE(GetMultiTexEnvfvEXT)
#define glGetMultiTexEnvivEXT MANGLE(GetMultiTexEnvivEXT)
#define glGetMultiTexGendvEXT MANGLE(GetMultiTexGendvEXT)
#define glGetMultiTexGenfvEXT MANGLE(GetMultiTexGenfvEXT)
#define glGetMultiTexGenivEXT MANGLE(GetMultiTexGenivEXT)
#define glGetMultiTexImageEXT MANGLE(GetMultiTexImageEXT)
#define glGetMultiTexLevelParameterfvEXT MANGLE(GetMultiTexLevelParameterfvEXT)
#define glGetMultiTexLevelParameterivEXT MANGLE(GetMultiTexLevelParameterivEXT)
#define glGetMultiTexParameterfvEXT MANGLE(GetMultiTexParameterfvEXT)
#define glGetMultiTexParameterIivEXT MANGLE(GetMultiTexParameterIivEXT)
#define glGetMultiTexParameterIuivEXT MANGLE(GetMultiTexParameterIuivEXT)
#define glGetMultiTexParameterivEXT MANGLE(GetMultiTexParameterivEXT)
#define glGetNamedBufferParameterivEXT MANGLE(GetNamedBufferParameterivEXT)
#define glGetNamedBufferPointervEXT MANGLE(GetNamedBufferPointervEXT)
#define glGetNamedBufferSubDataEXT MANGLE(GetNamedBufferSubDataEXT)
#define glGetNamedFramebufferAttachmentParameterivEXT MANGLE(GetNamedFramebufferAttachmentParameterivEXT)
#define glGetNamedProgramivEXT MANGLE(GetNamedProgramivEXT)
#define glGetNamedProgramLocalParameterdvEXT MANGLE(GetNamedProgramLocalParameterdvEXT)
#define glGetNamedProgramLocalParameterfvEXT MANGLE(GetNamedProgramLocalParameterfvEXT)
#define glGetNamedProgramLocalParameterIivEXT MANGLE(GetNamedProgramLocalParameterIivEXT)
#define glGetNamedProgramLocalParameterIuivEXT MANGLE(GetNamedProgramLocalParameterIuivEXT)
#define glGetNamedProgramStringEXT MANGLE(GetNamedProgramStringEXT)
#define glGetNamedRenderbufferParameterivEXT MANGLE(GetNamedRenderbufferParameterivEXT)
#define glGetObjectBufferfvATI MANGLE(GetObjectBufferfvATI)
#define glGetObjectBufferivATI MANGLE(GetObjectBufferivATI)
#define glGetObjectParameterfvARB MANGLE(GetObjectParameterfvARB)
@@ -524,6 +639,7 @@
#define glGetPixelMapusv MANGLE(GetPixelMapusv)
#define glGetPixelTexGenParameterfvSGIS MANGLE(GetPixelTexGenParameterfvSGIS)
#define glGetPixelTexGenParameterivSGIS MANGLE(GetPixelTexGenParameterivSGIS)
#define glGetPointerIndexedvEXT MANGLE(GetPointerIndexedvEXT)
#define glGetPointervEXT MANGLE(GetPointervEXT)
#define glGetPointerv MANGLE(GetPointerv)
#define glGetPolygonStipple MANGLE(GetPolygonStipple)
@@ -555,6 +671,7 @@
#define glGetQueryObjectuivARB MANGLE(GetQueryObjectuivARB)
#define glGetQueryObjectuiv MANGLE(GetQueryObjectuiv)
#define glGetRenderbufferParameterivEXT MANGLE(GetRenderbufferParameterivEXT)
#define glGetRenderbufferParameteriv MANGLE(GetRenderbufferParameteriv)
#define glGetSeparableFilterEXT MANGLE(GetSeparableFilterEXT)
#define glGetSeparableFilter MANGLE(GetSeparableFilter)
#define glGetShaderInfoLog MANGLE(GetShaderInfoLog)
@@ -562,6 +679,7 @@
#define glGetShaderSourceARB MANGLE(GetShaderSourceARB)
#define glGetShaderSource MANGLE(GetShaderSource)
#define glGetSharpenTexFuncSGIS MANGLE(GetSharpenTexFuncSGIS)
#define glGetStringi MANGLE(GetStringi)
#define glGetString MANGLE(GetString)
#define glGetTexBumpParameterfvATI MANGLE(GetTexBumpParameterfvATI)
#define glGetTexBumpParameterivATI MANGLE(GetTexBumpParameterivATI)
@@ -576,9 +694,20 @@
#define glGetTexLevelParameteriv MANGLE(GetTexLevelParameteriv)
#define glGetTexParameterfv MANGLE(GetTexParameterfv)
#define glGetTexParameterIivEXT MANGLE(GetTexParameterIivEXT)
#define glGetTexParameterIiv MANGLE(GetTexParameterIiv)
#define glGetTexParameterIuivEXT MANGLE(GetTexParameterIuivEXT)
#define glGetTexParameterIuiv MANGLE(GetTexParameterIuiv)
#define glGetTexParameteriv MANGLE(GetTexParameteriv)
#define glGetTextureImageEXT MANGLE(GetTextureImageEXT)
#define glGetTextureLevelParameterfvEXT MANGLE(GetTextureLevelParameterfvEXT)
#define glGetTextureLevelParameterivEXT MANGLE(GetTextureLevelParameterivEXT)
#define glGetTextureParameterfvEXT MANGLE(GetTextureParameterfvEXT)
#define glGetTextureParameterIivEXT MANGLE(GetTextureParameterIivEXT)
#define glGetTextureParameterIuivEXT MANGLE(GetTextureParameterIuivEXT)
#define glGetTextureParameterivEXT MANGLE(GetTextureParameterivEXT)
#define glGetTrackMatrixivNV MANGLE(GetTrackMatrixivNV)
#define glGetTransformFeedbackVaryingEXT MANGLE(GetTransformFeedbackVaryingEXT)
#define glGetTransformFeedbackVarying MANGLE(GetTransformFeedbackVarying)
#define glGetTransformFeedbackVaryingNV MANGLE(GetTransformFeedbackVaryingNV)
#define glGetUniformBufferSizeEXT MANGLE(GetUniformBufferSizeEXT)
#define glGetUniformfvARB MANGLE(GetUniformfvARB)
@@ -589,6 +718,7 @@
#define glGetUniformLocation MANGLE(GetUniformLocation)
#define glGetUniformOffsetEXT MANGLE(GetUniformOffsetEXT)
#define glGetUniformuivEXT MANGLE(GetUniformuivEXT)
#define glGetUniformuiv MANGLE(GetUniformuiv)
#define glGetVariantArrayObjectfvATI MANGLE(GetVariantArrayObjectfvATI)
#define glGetVariantArrayObjectivATI MANGLE(GetVariantArrayObjectivATI)
#define glGetVariantBooleanvEXT MANGLE(GetVariantBooleanvEXT)
@@ -605,7 +735,9 @@
#define glGetVertexAttribfv MANGLE(GetVertexAttribfv)
#define glGetVertexAttribfvNV MANGLE(GetVertexAttribfvNV)
#define glGetVertexAttribIivEXT MANGLE(GetVertexAttribIivEXT)
#define glGetVertexAttribIiv MANGLE(GetVertexAttribIiv)
#define glGetVertexAttribIuivEXT MANGLE(GetVertexAttribIuivEXT)
#define glGetVertexAttribIuiv MANGLE(GetVertexAttribIuiv)
#define glGetVertexAttribivARB MANGLE(GetVertexAttribivARB)
#define glGetVertexAttribiv MANGLE(GetVertexAttribiv)
#define glGetVertexAttribivNV MANGLE(GetVertexAttribivNV)
@@ -652,11 +784,13 @@
#define glIsAsyncMarkerSGIX MANGLE(IsAsyncMarkerSGIX)
#define glIsBufferARB MANGLE(IsBufferARB)
#define glIsBuffer MANGLE(IsBuffer)
#define glIsEnabledi MANGLE(IsEnabledi)
#define glIsEnabledIndexedEXT MANGLE(IsEnabledIndexedEXT)
#define glIsEnabled MANGLE(IsEnabled)
#define glIsFenceAPPLE MANGLE(IsFenceAPPLE)
#define glIsFenceNV MANGLE(IsFenceNV)
#define glIsFramebufferEXT MANGLE(IsFramebufferEXT)
#define glIsFramebuffer MANGLE(IsFramebuffer)
#define glIsList MANGLE(IsList)
#define glIsObjectBufferATI MANGLE(IsObjectBufferATI)
#define glIsOcclusionQueryNV MANGLE(IsOcclusionQueryNV)
@@ -666,11 +800,14 @@
#define glIsQueryARB MANGLE(IsQueryARB)
#define glIsQuery MANGLE(IsQuery)
#define glIsRenderbufferEXT MANGLE(IsRenderbufferEXT)
#define glIsRenderbuffer MANGLE(IsRenderbuffer)
#define glIsShader MANGLE(IsShader)
#define glIsTextureEXT MANGLE(IsTextureEXT)
#define glIsTexture MANGLE(IsTexture)
#define glIsTransformFeedbackNV MANGLE(IsTransformFeedbackNV)
#define glIsVariantEnabledEXT MANGLE(IsVariantEnabledEXT)
#define glIsVertexArrayAPPLE MANGLE(IsVertexArrayAPPLE)
#define glIsVertexArray MANGLE(IsVertexArray)
#define glLightEnviSGIX MANGLE(LightEnviSGIX)
#define glLightf MANGLE(Lightf)
#define glLightfv MANGLE(Lightfv)
@@ -707,11 +844,13 @@
#define glMap2f MANGLE(Map2f)
#define glMapBufferARB MANGLE(MapBufferARB)
#define glMapBuffer MANGLE(MapBuffer)
#define glMapBufferRange MANGLE(MapBufferRange)
#define glMapControlPointsNV MANGLE(MapControlPointsNV)
#define glMapGrid1d MANGLE(MapGrid1d)
#define glMapGrid1f MANGLE(MapGrid1f)
#define glMapGrid2d MANGLE(MapGrid2d)
#define glMapGrid2f MANGLE(MapGrid2f)
#define glMapNamedBufferEXT MANGLE(MapNamedBufferEXT)
#define glMapObjectBufferATI MANGLE(MapObjectBufferATI)
#define glMapParameterfvNV MANGLE(MapParameterfvNV)
#define glMapParameterivNV MANGLE(MapParameterivNV)
@@ -719,11 +858,30 @@
#define glMaterialfv MANGLE(Materialfv)
#define glMateriali MANGLE(Materiali)
#define glMaterialiv MANGLE(Materialiv)
#define glMatrixFrustumEXT MANGLE(MatrixFrustumEXT)
#define glMatrixIndexPointerARB MANGLE(MatrixIndexPointerARB)
#define glMatrixIndexubvARB MANGLE(MatrixIndexubvARB)
#define glMatrixIndexuivARB MANGLE(MatrixIndexuivARB)
#define glMatrixIndexusvARB MANGLE(MatrixIndexusvARB)
#define glMatrixLoaddEXT MANGLE(MatrixLoaddEXT)
#define glMatrixLoadfEXT MANGLE(MatrixLoadfEXT)
#define glMatrixLoadIdentityEXT MANGLE(MatrixLoadIdentityEXT)
#define glMatrixLoadTransposedEXT MANGLE(MatrixLoadTransposedEXT)
#define glMatrixLoadTransposefEXT MANGLE(MatrixLoadTransposefEXT)
#define glMatrixMode MANGLE(MatrixMode)
#define glMatrixMultdEXT MANGLE(MatrixMultdEXT)
#define glMatrixMultfEXT MANGLE(MatrixMultfEXT)
#define glMatrixMultTransposedEXT MANGLE(MatrixMultTransposedEXT)
#define glMatrixMultTransposefEXT MANGLE(MatrixMultTransposefEXT)
#define glMatrixOrthoEXT MANGLE(MatrixOrthoEXT)
#define glMatrixPopEXT MANGLE(MatrixPopEXT)
#define glMatrixPushEXT MANGLE(MatrixPushEXT)
#define glMatrixRotatedEXT MANGLE(MatrixRotatedEXT)
#define glMatrixRotatefEXT MANGLE(MatrixRotatefEXT)
#define glMatrixScaledEXT MANGLE(MatrixScaledEXT)
#define glMatrixScalefEXT MANGLE(MatrixScalefEXT)
#define glMatrixTranslatedEXT MANGLE(MatrixTranslatedEXT)
#define glMatrixTranslatefEXT MANGLE(MatrixTranslatefEXT)
#define glMinmaxEXT MANGLE(MinmaxEXT)
#define glMinmax MANGLE(Minmax)
#define glMultiDrawArraysEXT MANGLE(MultiDrawArraysEXT)
@@ -734,6 +892,7 @@
#define glMultiDrawRangeElementArrayAPPLE MANGLE(MultiDrawRangeElementArrayAPPLE)
#define glMultiModeDrawArraysIBM MANGLE(MultiModeDrawArraysIBM)
#define glMultiModeDrawElementsIBM MANGLE(MultiModeDrawElementsIBM)
#define glMultiTexBufferEXT MANGLE(MultiTexBufferEXT)
#define glMultiTexCoord1dARB MANGLE(MultiTexCoord1dARB)
#define glMultiTexCoord1d MANGLE(MultiTexCoord1d)
#define glMultiTexCoord1dvARB MANGLE(MultiTexCoord1dvARB)
@@ -806,12 +965,60 @@
#define glMultiTexCoord4s MANGLE(MultiTexCoord4s)
#define glMultiTexCoord4svARB MANGLE(MultiTexCoord4svARB)
#define glMultiTexCoord4sv MANGLE(MultiTexCoord4sv)
#define glMultiTexCoordPointerEXT MANGLE(MultiTexCoordPointerEXT)
#define glMultiTexEnvfEXT MANGLE(MultiTexEnvfEXT)
#define glMultiTexEnvfvEXT MANGLE(MultiTexEnvfvEXT)
#define glMultiTexEnviEXT MANGLE(MultiTexEnviEXT)
#define glMultiTexEnvivEXT MANGLE(MultiTexEnvivEXT)
#define glMultiTexGendEXT MANGLE(MultiTexGendEXT)
#define glMultiTexGendvEXT MANGLE(MultiTexGendvEXT)
#define glMultiTexGenfEXT MANGLE(MultiTexGenfEXT)
#define glMultiTexGenfvEXT MANGLE(MultiTexGenfvEXT)
#define glMultiTexGeniEXT MANGLE(MultiTexGeniEXT)
#define glMultiTexGenivEXT MANGLE(MultiTexGenivEXT)
#define glMultiTexImage1DEXT MANGLE(MultiTexImage1DEXT)
#define glMultiTexImage2DEXT MANGLE(MultiTexImage2DEXT)
#define glMultiTexImage3DEXT MANGLE(MultiTexImage3DEXT)
#define glMultiTexParameterfEXT MANGLE(MultiTexParameterfEXT)
#define glMultiTexParameterfvEXT MANGLE(MultiTexParameterfvEXT)
#define glMultiTexParameteriEXT MANGLE(MultiTexParameteriEXT)
#define glMultiTexParameterIivEXT MANGLE(MultiTexParameterIivEXT)
#define glMultiTexParameterIuivEXT MANGLE(MultiTexParameterIuivEXT)
#define glMultiTexParameterivEXT MANGLE(MultiTexParameterivEXT)
#define glMultiTexRenderbufferEXT MANGLE(MultiTexRenderbufferEXT)
#define glMultiTexSubImage1DEXT MANGLE(MultiTexSubImage1DEXT)
#define glMultiTexSubImage2DEXT MANGLE(MultiTexSubImage2DEXT)
#define glMultiTexSubImage3DEXT MANGLE(MultiTexSubImage3DEXT)
#define glMultMatrixd MANGLE(MultMatrixd)
#define glMultMatrixf MANGLE(MultMatrixf)
#define glMultTransposeMatrixdARB MANGLE(MultTransposeMatrixdARB)
#define glMultTransposeMatrixd MANGLE(MultTransposeMatrixd)
#define glMultTransposeMatrixfARB MANGLE(MultTransposeMatrixfARB)
#define glMultTransposeMatrixf MANGLE(MultTransposeMatrixf)
#define glNamedBufferDataEXT MANGLE(NamedBufferDataEXT)
#define glNamedBufferSubDataEXT MANGLE(NamedBufferSubDataEXT)
#define glNamedFramebufferRenderbufferEXT MANGLE(NamedFramebufferRenderbufferEXT)
#define glNamedFramebufferTexture1DEXT MANGLE(NamedFramebufferTexture1DEXT)
#define glNamedFramebufferTexture2DEXT MANGLE(NamedFramebufferTexture2DEXT)
#define glNamedFramebufferTexture3DEXT MANGLE(NamedFramebufferTexture3DEXT)
#define glNamedFramebufferTextureEXT MANGLE(NamedFramebufferTextureEXT)
#define glNamedFramebufferTextureFaceEXT MANGLE(NamedFramebufferTextureFaceEXT)
#define glNamedFramebufferTextureLayerEXT MANGLE(NamedFramebufferTextureLayerEXT)
#define glNamedProgramLocalParameter4dEXT MANGLE(NamedProgramLocalParameter4dEXT)
#define glNamedProgramLocalParameter4dvEXT MANGLE(NamedProgramLocalParameter4dvEXT)
#define glNamedProgramLocalParameter4fEXT MANGLE(NamedProgramLocalParameter4fEXT)
#define glNamedProgramLocalParameter4fvEXT MANGLE(NamedProgramLocalParameter4fvEXT)
#define glNamedProgramLocalParameterI4iEXT MANGLE(NamedProgramLocalParameterI4iEXT)
#define glNamedProgramLocalParameterI4ivEXT MANGLE(NamedProgramLocalParameterI4ivEXT)
#define glNamedProgramLocalParameterI4uiEXT MANGLE(NamedProgramLocalParameterI4uiEXT)
#define glNamedProgramLocalParameterI4uivEXT MANGLE(NamedProgramLocalParameterI4uivEXT)
#define glNamedProgramLocalParameters4fvEXT MANGLE(NamedProgramLocalParameters4fvEXT)
#define glNamedProgramLocalParametersI4ivEXT MANGLE(NamedProgramLocalParametersI4ivEXT)
#define glNamedProgramLocalParametersI4uivEXT MANGLE(NamedProgramLocalParametersI4uivEXT)
#define glNamedProgramStringEXT MANGLE(NamedProgramStringEXT)
#define glNamedRenderbufferStorageEXT MANGLE(NamedRenderbufferStorageEXT)
#define glNamedRenderbufferStorageMultisampleCoverageEXT MANGLE(NamedRenderbufferStorageMultisampleCoverageEXT)
#define glNamedRenderbufferStorageMultisampleEXT MANGLE(NamedRenderbufferStorageMultisampleEXT)
#define glNewList MANGLE(NewList)
#define glNewObjectBufferATI MANGLE(NewObjectBufferATI)
#define glNormal3b MANGLE(Normal3b)
@@ -845,6 +1052,7 @@
#define glOrtho MANGLE(Ortho)
#define glPassTexCoordATI MANGLE(PassTexCoordATI)
#define glPassThrough MANGLE(PassThrough)
#define glPauseTransformFeedbackNV MANGLE(PauseTransformFeedbackNV)
#define glPixelDataRangeNV MANGLE(PixelDataRangeNV)
#define glPixelMapfv MANGLE(PixelMapfv)
#define glPixelMapuiv MANGLE(PixelMapuiv)
@@ -926,12 +1134,47 @@
#define glProgramParameter4dvNV MANGLE(ProgramParameter4dvNV)
#define glProgramParameter4fNV MANGLE(ProgramParameter4fNV)
#define glProgramParameter4fvNV MANGLE(ProgramParameter4fvNV)
#define glProgramParameteriARB MANGLE(ProgramParameteriARB)
#define glProgramParameteriEXT MANGLE(ProgramParameteriEXT)
#define glProgramParameters4dvNV MANGLE(ProgramParameters4dvNV)
#define glProgramParameters4fvNV MANGLE(ProgramParameters4fvNV)
#define glProgramStringARB MANGLE(ProgramStringARB)
#define glProgramUniform1fEXT MANGLE(ProgramUniform1fEXT)
#define glProgramUniform1fvEXT MANGLE(ProgramUniform1fvEXT)
#define glProgramUniform1iEXT MANGLE(ProgramUniform1iEXT)
#define glProgramUniform1ivEXT MANGLE(ProgramUniform1ivEXT)
#define glProgramUniform1uiEXT MANGLE(ProgramUniform1uiEXT)
#define glProgramUniform1uivEXT MANGLE(ProgramUniform1uivEXT)
#define glProgramUniform2fEXT MANGLE(ProgramUniform2fEXT)
#define glProgramUniform2fvEXT MANGLE(ProgramUniform2fvEXT)
#define glProgramUniform2iEXT MANGLE(ProgramUniform2iEXT)
#define glProgramUniform2ivEXT MANGLE(ProgramUniform2ivEXT)
#define glProgramUniform2uiEXT MANGLE(ProgramUniform2uiEXT)
#define glProgramUniform2uivEXT MANGLE(ProgramUniform2uivEXT)
#define glProgramUniform3fEXT MANGLE(ProgramUniform3fEXT)
#define glProgramUniform3fvEXT MANGLE(ProgramUniform3fvEXT)
#define glProgramUniform3iEXT MANGLE(ProgramUniform3iEXT)
#define glProgramUniform3ivEXT MANGLE(ProgramUniform3ivEXT)
#define glProgramUniform3uiEXT MANGLE(ProgramUniform3uiEXT)
#define glProgramUniform3uivEXT MANGLE(ProgramUniform3uivEXT)
#define glProgramUniform4fEXT MANGLE(ProgramUniform4fEXT)
#define glProgramUniform4fvEXT MANGLE(ProgramUniform4fvEXT)
#define glProgramUniform4iEXT MANGLE(ProgramUniform4iEXT)
#define glProgramUniform4ivEXT MANGLE(ProgramUniform4ivEXT)
#define glProgramUniform4uiEXT MANGLE(ProgramUniform4uiEXT)
#define glProgramUniform4uivEXT MANGLE(ProgramUniform4uivEXT)
#define glProgramUniformMatrix2fvEXT MANGLE(ProgramUniformMatrix2fvEXT)
#define glProgramUniformMatrix2x3fvEXT MANGLE(ProgramUniformMatrix2x3fvEXT)
#define glProgramUniformMatrix2x4fvEXT MANGLE(ProgramUniformMatrix2x4fvEXT)
#define glProgramUniformMatrix3fvEXT MANGLE(ProgramUniformMatrix3fvEXT)
#define glProgramUniformMatrix3x2fvEXT MANGLE(ProgramUniformMatrix3x2fvEXT)
#define glProgramUniformMatrix3x4fvEXT MANGLE(ProgramUniformMatrix3x4fvEXT)
#define glProgramUniformMatrix4fvEXT MANGLE(ProgramUniformMatrix4fvEXT)
#define glProgramUniformMatrix4x2fvEXT MANGLE(ProgramUniformMatrix4x2fvEXT)
#define glProgramUniformMatrix4x3fvEXT MANGLE(ProgramUniformMatrix4x3fvEXT)
#define glProgramVertexLimitNV MANGLE(ProgramVertexLimitNV)
#define glPushAttrib MANGLE(PushAttrib)
#define glPushClientAttribDefaultEXT MANGLE(PushClientAttribDefaultEXT)
#define glPushClientAttrib MANGLE(PushClientAttrib)
#define glPushMatrix MANGLE(PushMatrix)
#define glPushName MANGLE(PushName)
@@ -972,8 +1215,10 @@
#define glRectsv MANGLE(Rectsv)
#define glReferencePlaneSGIX MANGLE(ReferencePlaneSGIX)
#define glRenderbufferStorageEXT MANGLE(RenderbufferStorageEXT)
#define glRenderbufferStorage MANGLE(RenderbufferStorage)
#define glRenderbufferStorageMultisampleCoverageNV MANGLE(RenderbufferStorageMultisampleCoverageNV)
#define glRenderbufferStorageMultisampleEXT MANGLE(RenderbufferStorageMultisampleEXT)
#define glRenderbufferStorageMultisample MANGLE(RenderbufferStorageMultisample)
#define glRenderMode MANGLE(RenderMode)
#define glReplacementCodePointerSUN MANGLE(ReplacementCodePointerSUN)
#define glReplacementCodeubSUN MANGLE(ReplacementCodeubSUN)
@@ -1004,12 +1249,14 @@
#define glResetMinmaxEXT MANGLE(ResetMinmaxEXT)
#define glResetMinmax MANGLE(ResetMinmax)
#define glResizeBuffersMESA MANGLE(ResizeBuffersMESA)
#define glResumeTransformFeedbackNV MANGLE(ResumeTransformFeedbackNV)
#define glRotated MANGLE(Rotated)
#define glRotatef MANGLE(Rotatef)
#define glSampleCoverageARB MANGLE(SampleCoverageARB)
#define glSampleCoverage MANGLE(SampleCoverage)
#define glSampleMapATI MANGLE(SampleMapATI)
#define glSampleMaskEXT MANGLE(SampleMaskEXT)
#define glSampleMaskIndexedNV MANGLE(SampleMaskIndexedNV)
#define glSampleMaskSGIS MANGLE(SampleMaskSGIS)
#define glSamplePatternEXT MANGLE(SamplePatternEXT)
#define glSamplePatternSGIS MANGLE(SamplePatternSGIS)
@@ -1101,6 +1348,7 @@
#define glTestFenceAPPLE MANGLE(TestFenceAPPLE)
#define glTestFenceNV MANGLE(TestFenceNV)
#define glTestObjectAPPLE MANGLE(TestObjectAPPLE)
#define glTexBufferARB MANGLE(TexBufferARB)
#define glTexBufferEXT MANGLE(TexBufferEXT)
#define glTexBumpParameterfvATI MANGLE(TexBumpParameterfvATI)
#define glTexBumpParameterivATI MANGLE(TexBumpParameterivATI)
@@ -1181,9 +1429,12 @@
#define glTexParameterf MANGLE(TexParameterf)
#define glTexParameterfv MANGLE(TexParameterfv)
#define glTexParameterIivEXT MANGLE(TexParameterIivEXT)
#define glTexParameterIiv MANGLE(TexParameterIiv)
#define glTexParameteri MANGLE(TexParameteri)
#define glTexParameterIuivEXT MANGLE(TexParameterIuivEXT)
#define glTexParameterIuiv MANGLE(TexParameterIuiv)
#define glTexParameteriv MANGLE(TexParameteriv)
#define glTexRenderbufferNV MANGLE(TexRenderbufferNV)
#define glTexSubImage1DEXT MANGLE(TexSubImage1DEXT)
#define glTexSubImage1D MANGLE(TexSubImage1D)
#define glTexSubImage2DEXT MANGLE(TexSubImage2DEXT)
@@ -1191,12 +1442,28 @@
#define glTexSubImage3DEXT MANGLE(TexSubImage3DEXT)
#define glTexSubImage3D MANGLE(TexSubImage3D)
#define glTexSubImage4DSGIS MANGLE(TexSubImage4DSGIS)
#define glTextureBufferEXT MANGLE(TextureBufferEXT)
#define glTextureColorMaskSGIS MANGLE(TextureColorMaskSGIS)
#define glTextureImage1DEXT MANGLE(TextureImage1DEXT)
#define glTextureImage2DEXT MANGLE(TextureImage2DEXT)
#define glTextureImage3DEXT MANGLE(TextureImage3DEXT)
#define glTextureLightEXT MANGLE(TextureLightEXT)
#define glTextureMaterialEXT MANGLE(TextureMaterialEXT)
#define glTextureNormalEXT MANGLE(TextureNormalEXT)
#define glTextureParameterfEXT MANGLE(TextureParameterfEXT)
#define glTextureParameterfvEXT MANGLE(TextureParameterfvEXT)
#define glTextureParameteriEXT MANGLE(TextureParameteriEXT)
#define glTextureParameterIivEXT MANGLE(TextureParameterIivEXT)
#define glTextureParameterIuivEXT MANGLE(TextureParameterIuivEXT)
#define glTextureParameterivEXT MANGLE(TextureParameterivEXT)
#define glTextureRenderbufferEXT MANGLE(TextureRenderbufferEXT)
#define glTextureSubImage1DEXT MANGLE(TextureSubImage1DEXT)
#define glTextureSubImage2DEXT MANGLE(TextureSubImage2DEXT)
#define glTextureSubImage3DEXT MANGLE(TextureSubImage3DEXT)
#define glTrackMatrixNV MANGLE(TrackMatrixNV)
#define glTransformFeedbackAttribsNV MANGLE(TransformFeedbackAttribsNV)
#define glTransformFeedbackVaryingsEXT MANGLE(TransformFeedbackVaryingsEXT)
#define glTransformFeedbackVaryings MANGLE(TransformFeedbackVaryings)
#define glTransformFeedbackVaryingsNV MANGLE(TransformFeedbackVaryingsNV)
#define glTranslated MANGLE(Translated)
#define glTranslatef MANGLE(Translatef)
@@ -1209,7 +1476,9 @@
#define glUniform1ivARB MANGLE(Uniform1ivARB)
#define glUniform1iv MANGLE(Uniform1iv)
#define glUniform1uiEXT MANGLE(Uniform1uiEXT)
#define glUniform1ui MANGLE(Uniform1ui)
#define glUniform1uivEXT MANGLE(Uniform1uivEXT)
#define glUniform1uiv MANGLE(Uniform1uiv)
#define glUniform2fARB MANGLE(Uniform2fARB)
#define glUniform2f MANGLE(Uniform2f)
#define glUniform2fvARB MANGLE(Uniform2fvARB)
@@ -1219,7 +1488,9 @@
#define glUniform2ivARB MANGLE(Uniform2ivARB)
#define glUniform2iv MANGLE(Uniform2iv)
#define glUniform2uiEXT MANGLE(Uniform2uiEXT)
#define glUniform2ui MANGLE(Uniform2ui)
#define glUniform2uivEXT MANGLE(Uniform2uivEXT)
#define glUniform2uiv MANGLE(Uniform2uiv)
#define glUniform3fARB MANGLE(Uniform3fARB)
#define glUniform3f MANGLE(Uniform3f)
#define glUniform3fvARB MANGLE(Uniform3fvARB)
@@ -1229,7 +1500,9 @@
#define glUniform3ivARB MANGLE(Uniform3ivARB)
#define glUniform3iv MANGLE(Uniform3iv)
#define glUniform3uiEXT MANGLE(Uniform3uiEXT)
#define glUniform3ui MANGLE(Uniform3ui)
#define glUniform3uivEXT MANGLE(Uniform3uivEXT)
#define glUniform3uiv MANGLE(Uniform3uiv)
#define glUniform4fARB MANGLE(Uniform4fARB)
#define glUniform4f MANGLE(Uniform4f)
#define glUniform4fvARB MANGLE(Uniform4fvARB)
@@ -1239,7 +1512,9 @@
#define glUniform4ivARB MANGLE(Uniform4ivARB)
#define glUniform4iv MANGLE(Uniform4iv)
#define glUniform4uiEXT MANGLE(Uniform4uiEXT)
#define glUniform4ui MANGLE(Uniform4ui)
#define glUniform4uivEXT MANGLE(Uniform4uivEXT)
#define glUniform4uiv MANGLE(Uniform4uiv)
#define glUniformBufferEXT MANGLE(UniformBufferEXT)
#define glUniformMatrix2fvARB MANGLE(UniformMatrix2fvARB)
#define glUniformMatrix2fv MANGLE(UniformMatrix2fv)
@@ -1256,6 +1531,7 @@
#define glUnlockArraysEXT MANGLE(UnlockArraysEXT)
#define glUnmapBufferARB MANGLE(UnmapBufferARB)
#define glUnmapBuffer MANGLE(UnmapBuffer)
#define glUnmapNamedBufferEXT MANGLE(UnmapNamedBufferEXT)
#define glUnmapObjectBufferATI MANGLE(UnmapObjectBufferATI)
#define glUpdateObjectBufferATI MANGLE(UpdateObjectBufferATI)
#define glUseProgram MANGLE(UseProgram)
@@ -1412,27 +1688,49 @@
#define glVertexAttrib4usvARB MANGLE(VertexAttrib4usvARB)
#define glVertexAttrib4usv MANGLE(VertexAttrib4usv)
#define glVertexAttribArrayObjectATI MANGLE(VertexAttribArrayObjectATI)
#define glVertexAttribDivisor MANGLE(VertexAttribDivisor)
#define glVertexAttribI1iEXT MANGLE(VertexAttribI1iEXT)
#define glVertexAttribI1i MANGLE(VertexAttribI1i)
#define glVertexAttribI1ivEXT MANGLE(VertexAttribI1ivEXT)
#define glVertexAttribI1iv MANGLE(VertexAttribI1iv)
#define glVertexAttribI1uiEXT MANGLE(VertexAttribI1uiEXT)
#define glVertexAttribI1ui MANGLE(VertexAttribI1ui)
#define glVertexAttribI1uivEXT MANGLE(VertexAttribI1uivEXT)
#define glVertexAttribI1uiv MANGLE(VertexAttribI1uiv)
#define glVertexAttribI2iEXT MANGLE(VertexAttribI2iEXT)
#define glVertexAttribI2i MANGLE(VertexAttribI2i)
#define glVertexAttribI2ivEXT MANGLE(VertexAttribI2ivEXT)
#define glVertexAttribI2iv MANGLE(VertexAttribI2iv)
#define glVertexAttribI2uiEXT MANGLE(VertexAttribI2uiEXT)
#define glVertexAttribI2ui MANGLE(VertexAttribI2ui)
#define glVertexAttribI2uivEXT MANGLE(VertexAttribI2uivEXT)
#define glVertexAttribI2uiv MANGLE(VertexAttribI2uiv)
#define glVertexAttribI3iEXT MANGLE(VertexAttribI3iEXT)
#define glVertexAttribI3i MANGLE(VertexAttribI3i)
#define glVertexAttribI3ivEXT MANGLE(VertexAttribI3ivEXT)
#define glVertexAttribI3iv MANGLE(VertexAttribI3iv)
#define glVertexAttribI3uiEXT MANGLE(VertexAttribI3uiEXT)
#define glVertexAttribI3ui MANGLE(VertexAttribI3ui)
#define glVertexAttribI3uivEXT MANGLE(VertexAttribI3uivEXT)
#define glVertexAttribI3uiv MANGLE(VertexAttribI3uiv)
#define glVertexAttribI4bvEXT MANGLE(VertexAttribI4bvEXT)
#define glVertexAttribI4bv MANGLE(VertexAttribI4bv)
#define glVertexAttribI4iEXT MANGLE(VertexAttribI4iEXT)
#define glVertexAttribI4i MANGLE(VertexAttribI4i)
#define glVertexAttribI4ivEXT MANGLE(VertexAttribI4ivEXT)
#define glVertexAttribI4iv MANGLE(VertexAttribI4iv)
#define glVertexAttribI4svEXT MANGLE(VertexAttribI4svEXT)
#define glVertexAttribI4sv MANGLE(VertexAttribI4sv)
#define glVertexAttribI4ubvEXT MANGLE(VertexAttribI4ubvEXT)
#define glVertexAttribI4ubv MANGLE(VertexAttribI4ubv)
#define glVertexAttribI4uiEXT MANGLE(VertexAttribI4uiEXT)
#define glVertexAttribI4ui MANGLE(VertexAttribI4ui)
#define glVertexAttribI4uivEXT MANGLE(VertexAttribI4uivEXT)
#define glVertexAttribI4uiv MANGLE(VertexAttribI4uiv)
#define glVertexAttribI4usvEXT MANGLE(VertexAttribI4usvEXT)
#define glVertexAttribI4usv MANGLE(VertexAttribI4usv)
#define glVertexAttribIPointerEXT MANGLE(VertexAttribIPointerEXT)
#define glVertexAttribIPointer MANGLE(VertexAttribIPointer)
#define glVertexAttribPointerARB MANGLE(VertexAttribPointerARB)
#define glVertexAttribPointer MANGLE(VertexAttribPointer)
#define glVertexAttribPointerNV MANGLE(VertexAttribPointerNV)

View File

@@ -46,9 +46,9 @@ extern "C" {
/*************************************************************/
/* Header file version number, required by OpenGL ABI for Linux */
/* glext.h last updated 2008/11/14 */
/* glext.h last updated 2009/03/19 */
/* Current version at http://www.opengl.org/registry/ */
#define GL_GLEXT_VERSION 44
#define GL_GLEXT_VERSION 48
#ifndef GL_VERSION_1_2
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
@@ -3862,6 +3862,42 @@ extern "C" {
#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
#endif
#ifndef GL_ATI_meminfo
#define GL_VBO_FREE_MEMORY_ATI 0x87FB
#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
#endif
#ifndef GL_AMD_performance_monitor
#define GL_COUNTER_TYPE_AMD 0x8BC0
#define GL_COUNTER_RANGE_AMD 0x8BC1
#define GL_UNSIGNED_INT64_AMD 0x8BC2
#define GL_PERCENTAGE_AMD 0x8BC3
#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
#define GL_PERFMON_RESULT_AMD 0x8BC6
#endif
#ifndef GL_AMD_texture_texture4
#endif
#ifndef GL_AMD_vertex_shader_tesselator
#define GL_SAMPLER_BUFFER_AMD 0x9001
#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
#define GL_TESSELLATION_MODE_AMD 0x9004
#define GL_TESSELLATION_FACTOR_AMD 0x9005
#define GL_DISCRETE_AMD 0x9006
#define GL_CONTINUOUS_AMD 0x9007
#endif
#ifndef GL_EXT_provoking_vertex
#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
#define GL_PROVOKING_VERTEX_EXT 0x8E4F
#endif
/*************************************************************/
@@ -4487,8 +4523,8 @@ GLAPI void APIENTRY glBeginTransformFeedback (GLenum);
GLAPI void APIENTRY glEndTransformFeedback (void);
GLAPI void APIENTRY glBindBufferRange (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
GLAPI void APIENTRY glBindBufferBase (GLenum, GLuint, GLuint);
GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint, GLsizei, const GLint *, GLenum);
GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint, GLuint, GLint *);
GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint, GLsizei, const GLchar* *, GLenum);
GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *);
GLAPI void APIENTRY glClampColor (GLenum, GLenum);
GLAPI void APIENTRY glBeginConditionalRender (GLuint, GLenum);
GLAPI void APIENTRY glEndConditionalRender (void);
@@ -4546,8 +4582,8 @@ typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLint *location);
typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);
@@ -5268,10 +5304,10 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divi
#ifndef GL_ARB_map_buffer_range
#define GL_ARB_map_buffer_range 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glMapBufferRange (GLenum, GLintptr, GLsizeiptr, GLbitfield);
GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum, GLintptr, GLsizeiptr, GLbitfield);
GLAPI void APIENTRY glFlushMappedBufferRange (GLenum, GLintptr, GLsizeiptr);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
#endif
@@ -8011,6 +8047,22 @@ typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
#ifndef GL_NV_present_video
#define GL_NV_present_video 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint, GLuint64EXT, GLuint, GLuint, GLenum, GLenum, GLuint, GLuint, GLenum, GLuint, GLuint);
GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint, GLuint64EXT, GLuint, GLuint, GLenum, GLenum, GLuint, GLenum, GLuint, GLenum, GLuint, GLenum, GLuint);
GLAPI void APIENTRY glGetVideoivNV (GLuint, GLenum, GLint *);
GLAPI void APIENTRY glGetVideouivNV (GLuint, GLenum, GLuint *);
GLAPI void APIENTRY glGetVideoi64vNV (GLuint, GLenum, GLint64EXT *);
GLAPI void APIENTRY glGetVideoui64vNV (GLuint, GLenum, GLuint64EXT *);
GLAPI void APIENTRY glVideoParameterivNV (GLuint, GLenum, const GLint *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params);
typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params);
typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params);
typedef void (APIENTRYP PFNGLVIDEOPARAMETERIVNVPROC) (GLuint video_slot, GLenum pname, const GLint *params);
#endif
#ifndef GL_EXT_transform_feedback
@@ -8021,16 +8073,16 @@ GLAPI void APIENTRY glEndTransformFeedbackEXT (void);
GLAPI void APIENTRY glBindBufferRangeEXT (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum, GLuint, GLuint, GLintptr);
GLAPI void APIENTRY glBindBufferBaseEXT (GLenum, GLuint, GLuint);
GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint, GLsizei, const GLint *, GLenum);
GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint, GLuint, GLint *);
GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint, GLsizei, const GLchar* *, GLenum);
GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLint *location);
typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
#endif
#ifndef GL_EXT_direct_state_access
@@ -8451,6 +8503,60 @@ typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
#endif
#ifndef GL_ATI_meminfo
#define GL_ATI_meminfo 1
#endif
#ifndef GL_AMD_performance_monitor
#define GL_AMD_performance_monitor 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *, GLsizei, GLuint *);
GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint, GLint *, GLint *, GLsizei, GLuint *);
GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint, GLsizei, GLsizei *, GLchar *);
GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint, GLuint, GLsizei, GLsizei *, GLchar *);
GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint, GLuint, GLenum, void *);
GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei, GLuint *);
GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei, GLuint *);
GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint, GLboolean, GLuint, GLint, GLuint *);
GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint);
GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint);
GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint, GLenum, GLsizei, GLuint *, GLint *);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);
typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
#endif
#ifndef GL_AMD_texture_texture4
#define GL_AMD_texture_texture4 1
#endif
#ifndef GL_AMD_vertex_shader_tesselator
#define GL_AMD_vertex_shader_tesselator 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glTessellationFactorAMD (GLfloat);
GLAPI void APIENTRY glTessellationModeAMD (GLenum);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
#endif
#ifndef GL_EXT_provoking_vertex
#define GL_EXT_provoking_vertex 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glProvokingVertexEXT (GLenum);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
#endif
#ifdef __cplusplus
}

54
progs/fbdev/Makefile Normal file
View File

@@ -0,0 +1,54 @@
# Makefile for miniglx demo programs
TOP = ../..
include $(TOP)/configs/current
SOURCES = glfbdevtest.c
OBJECTS = $(SOURCES:.c=.o)
PROGS = $(SOURCES:%.c=%)
INCLUDES = \
-I. \
-I$(TOP)/include
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
##### RULES #####
.SUFFIXES:
.SUFFIXES: .c
.c:
$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
.S.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
##### TARGETS #####
default: depend $(PROGS)
clean:
-rm -f $(PROGS)
-rm -f *.o
depend: $(SOURCES)
touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) > /dev/null
# Emacs tags
tags:
etags `find . -name \*.[ch]` `find ../include`
include depend

599
progs/fbdev/glfbdevtest.c Normal file
View File

@@ -0,0 +1,599 @@
/*
* Test the GLFBDev interface. Only tested with radeonfb driver!!!!
*
* Written by Brian Paul
*/
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <GL/gl.h>
#include <GL/glfbdev.h>
#include <math.h>
/**
* Choose one of these modes
*/
/*static const int XRes = 1280, YRes = 1024, Hz = 75;*/
/*static const int XRes = 1280, YRes = 1024, Hz = 70;*/
/*static const int XRes = 1280, YRes = 1024, Hz = 60;*/
static const int XRes = 1024, YRes = 768, Hz = 70;
static int DesiredDepth = 32;
static int NumFrames = 100;
static struct fb_fix_screeninfo FixedInfo;
static struct fb_var_screeninfo VarInfo, OrigVarInfo;
static int OriginalVT = -1;
static int ConsoleFD = -1;
static int FrameBufferFD = -1;
static caddr_t FrameBuffer = (caddr_t) -1;
static caddr_t MMIOAddress = (caddr_t) -1;
static void
print_fixed_info(const struct fb_fix_screeninfo *fixed, const char *s)
{
static const char *visuals[] = {
"MONO01", "MONO10", "TRUECOLOR", "PSEUDOCOLOR",
"DIRECTCOLOR", "STATIC_PSEUDOCOLOR"
};
printf("%s info -----------------------\n", s);
printf("id = %16s\n", fixed->id);
printf("smem_start = 0x%lx\n", fixed->smem_start);
printf("smem_len = %d (0x%x)\n", fixed->smem_len, fixed->smem_len);
printf("type = 0x%x\n", fixed->type);
printf("type_aux = 0x%x\n", fixed->type_aux);
printf("visual = 0x%x (%s)\n", fixed->visual, visuals[fixed->visual]);
printf("xpanstep = %d\n", fixed->xpanstep);
printf("ypanstep = %d\n", fixed->ypanstep);
printf("ywrapstep = %d\n", fixed->ywrapstep);
printf("line_length = %d\n", fixed->line_length);
printf("mmio_start = 0x%lx\n", fixed->mmio_start);
printf("mmio_len = %d (0x%x)\n", fixed->mmio_len, fixed->mmio_len);
printf("accel = 0x%x\n", fixed->accel);
}
static void
print_var_info(const struct fb_var_screeninfo *var, const char *s)
{
printf("%s info -----------------------\n", s);
printf("xres = %d\n", var->xres);
printf("yres = %d\n", var->yres);
printf("xres_virtual = %d\n", var->xres_virtual);
printf("yres_virtual = %d\n", var->yres_virtual);
printf("xoffset = %d\n", var->xoffset);
printf("yoffset = %d\n", var->yoffset);
printf("bits_per_pixel = %d\n", var->bits_per_pixel);
printf("grayscale = %d\n", var->grayscale);
printf("red.offset = %d length = %d msb_right = %d\n",
var->red.offset, var->red.length, var->red.msb_right);
printf("green.offset = %d length = %d msb_right = %d\n",
var->green.offset, var->green.length, var->green.msb_right);
printf("blue.offset = %d length = %d msb_right = %d\n",
var->blue.offset, var->blue.length, var->blue.msb_right);
printf("transp.offset = %d length = %d msb_right = %d\n",
var->transp.offset, var->transp.length, var->transp.msb_right);
printf("nonstd = %d\n", var->nonstd);
printf("activate = %d\n", var->activate);
printf("height = %d mm\n", var->height);
printf("width = %d mm\n", var->width);
printf("accel_flags = 0x%x\n", var->accel_flags);
printf("pixclock = %d\n", var->pixclock);
printf("left_margin = %d\n", var->left_margin);
printf("right_margin = %d\n", var->right_margin);
printf("upper_margin = %d\n", var->upper_margin);
printf("lower_margin = %d\n", var->lower_margin);
printf("hsync_len = %d\n", var->hsync_len);
printf("vsync_len = %d\n", var->vsync_len);
printf("sync = %d\n", var->sync);
printf("vmode = %d\n", var->vmode);
}
static void
signal_handler(int signumber)
{
signal(signumber, SIG_IGN); /* prevent recursion! */
fprintf(stderr, "error: got signal %d (exiting)\n", signumber);
exit(1);
}
static void
initialize_fbdev( void )
{
char ttystr[1000];
int fd, vtnumber, ttyfd;
int sz;
(void) sz;
if (geteuid()) {
fprintf(stderr, "error: you need to be root\n");
exit(1);
}
#if 1
/* open the framebuffer device */
FrameBufferFD = open("/dev/fb0", O_RDWR);
if (FrameBufferFD < 0) {
fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
exit(1);
}
#endif
/* open /dev/tty0 and get the vt number */
if ((fd = open("/dev/tty0", O_WRONLY, 0)) < 0) {
fprintf(stderr, "error opening /dev/tty0\n");
exit(1);
}
if (ioctl(fd, VT_OPENQRY, &vtnumber) < 0 || vtnumber < 0) {
fprintf(stderr, "error: couldn't get a free vt\n");
exit(1);
}
close(fd);
/* open the console tty */
sprintf(ttystr, "/dev/tty%d", vtnumber); /* /dev/tty1-64 */
ConsoleFD = open(ttystr, O_RDWR | O_NDELAY, 0);
if (ConsoleFD < 0) {
fprintf(stderr, "error couldn't open console fd\n");
exit(1);
}
/* save current vt number */
{
struct vt_stat vts;
if (ioctl(ConsoleFD, VT_GETSTATE, &vts) == 0)
OriginalVT = vts.v_active;
}
/* disconnect from controlling tty */
ttyfd = open("/dev/tty", O_RDWR);
if (ttyfd >= 0) {
ioctl(ttyfd, TIOCNOTTY, 0);
close(ttyfd);
}
/* some magic to restore the vt when we exit */
{
struct vt_mode vt;
if (ioctl(ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
if (ioctl(ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
if (ioctl(ConsoleFD, VT_GETMODE, &vt) < 0) {
fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
exit(1);
}
vt.mode = VT_PROCESS;
vt.relsig = SIGUSR1;
vt.acqsig = SIGUSR1;
if (ioctl(ConsoleFD, VT_SETMODE, &vt) < 0) {
fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n",
strerror(errno));
exit(1);
}
}
/* go into graphics mode */
if (ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) {
fprintf(stderr, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n",
strerror(errno));
exit(1);
}
#if 0
/* open the framebuffer device */
FrameBufferFD = open("/dev/fb0", O_RDWR);
if (FrameBufferFD < 0) {
fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
exit(1);
}
#endif
/* Get the fixed screen info */
if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
strerror(errno));
exit(1);
}
print_fixed_info(&FixedInfo, "Fixed");
/* get the variable screen info */
if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
strerror(errno));
exit(1);
}
print_var_info(&OrigVarInfo, "Orig Var");
/* operate on a copy */
VarInfo = OrigVarInfo;
/* set the depth, resolution, etc */
if (DesiredDepth)
VarInfo.bits_per_pixel = DesiredDepth;
if (VarInfo.bits_per_pixel == 16) {
VarInfo.red.offset = 11;
VarInfo.green.offset = 5;
VarInfo.blue.offset = 0;
VarInfo.red.length = 5;
VarInfo.green.length = 6;
VarInfo.blue.length = 5;
VarInfo.transp.offset = 0;
VarInfo.transp.length = 0;
}
else if (VarInfo.bits_per_pixel == 32) {
VarInfo.red.offset = 16;
VarInfo.green.offset = 8;
VarInfo.blue.offset = 0;
VarInfo.transp.offset = 24;
VarInfo.red.length = 8;
VarInfo.green.length = 8;
VarInfo.blue.length = 8;
VarInfo.transp.length = 8;
}
/* timing values taken from /etc/fb.modes */
if (XRes == 1280 && YRes == 1024) {
VarInfo.xres_virtual = VarInfo.xres = XRes;
VarInfo.yres_virtual = VarInfo.yres = YRes;
if (Hz == 75) {
VarInfo.pixclock = 7408;
VarInfo.left_margin = 248;
VarInfo.right_margin = 16;
VarInfo.upper_margin = 38;
VarInfo.lower_margin = 1;
VarInfo.hsync_len = 144;
VarInfo.vsync_len = 3;
}
else if (Hz == 70) {
VarInfo.pixclock = 7937;
VarInfo.left_margin = 216;
VarInfo.right_margin = 80;
VarInfo.upper_margin = 36;
VarInfo.lower_margin = 1;
VarInfo.hsync_len = 112;
VarInfo.vsync_len = 5;
}
else if (Hz == 60) {
VarInfo.pixclock = 9260;
VarInfo.left_margin = 248;
VarInfo.right_margin = 48;
VarInfo.upper_margin = 38;
VarInfo.lower_margin = 1;
VarInfo.hsync_len = 112;
VarInfo.vsync_len = 3;
}
else {
fprintf(stderr, "invalid rate for 1280x1024\n");
exit(1);
}
}
else if (XRes == 1024 && YRes == 768 && Hz == 70) {
VarInfo.xres_virtual = VarInfo.xres = XRes;
VarInfo.yres_virtual = VarInfo.yres = YRes;
if (Hz == 70) {
VarInfo.pixclock = 13334;
VarInfo.left_margin = 144;
VarInfo.right_margin = 24;
VarInfo.upper_margin = 29;
VarInfo.lower_margin = 3;
VarInfo.hsync_len = 136;
VarInfo.vsync_len = 6;
}
else {
fprintf(stderr, "invalid rate for 1024x768\n");
exit(1);
}
}
VarInfo.xoffset = 0;
VarInfo.yoffset = 0;
VarInfo.nonstd = 0;
VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
/* set new variable screen info */
if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) {
fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
strerror(errno));
exit(1);
}
print_var_info(&VarInfo, "New Var");
if (FixedInfo.visual != FB_VISUAL_TRUECOLOR &&
FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) {
fprintf(stderr, "non-TRUE/DIRECT-COLOR visuals (0x%x) not supported by this demo.\n", FixedInfo.visual);
exit(1);
}
/* initialize colormap */
if (FixedInfo.visual == FB_VISUAL_DIRECTCOLOR) {
struct fb_cmap cmap;
unsigned short red[256], green[256], blue[256];
int i;
/* we're assuming 256 entries here */
printf("initializing directcolor colormap\n");
cmap.start = 0;
cmap.len = 256;
cmap.red = red;
cmap.green = green;
cmap.blue = blue;
cmap.transp = NULL;
for (i = 0; i < cmap.len; i++) {
red[i] = green[i] = blue[i] = (i << 8) | i;
}
if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &cmap) < 0) {
fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i);
}
}
/*
* fbdev says the frame buffer is at offset zero, and the mmio region
* is immediately after.
*/
/* mmap the framebuffer into our address space */
FrameBuffer = (caddr_t) mmap(0, /* start */
FixedInfo.smem_len, /* bytes */
PROT_READ | PROT_WRITE, /* prot */
MAP_SHARED, /* flags */
FrameBufferFD, /* fd */
0 /* offset */);
if (FrameBuffer == (caddr_t) - 1) {
fprintf(stderr, "error: unable to mmap framebuffer: %s\n",
strerror(errno));
exit(1);
}
printf("FrameBuffer = %p\n", FrameBuffer);
#if 1
/* mmap the MMIO region into our address space */
MMIOAddress = (caddr_t) mmap(0, /* start */
FixedInfo.mmio_len, /* bytes */
PROT_READ | PROT_WRITE, /* prot */
MAP_SHARED, /* flags */
FrameBufferFD, /* fd */
FixedInfo.smem_len /* offset */);
if (MMIOAddress == (caddr_t) - 1) {
fprintf(stderr, "error: unable to mmap mmio region: %s\n",
strerror(errno));
}
printf("MMIOAddress = %p\n", MMIOAddress);
/* try out some simple MMIO register reads */
if (0)
{
typedef unsigned int CARD32;
typedef unsigned char CARD8;
#define RADEON_CONFIG_MEMSIZE 0x00f8
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
#define MMIO_IN32(base, offset) \
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
#define INREG(addr) MMIO_IN32(MMIOAddress, addr)
int sz, type;
const char *typeStr[] = {"SDR", "DDR", "64-bit SDR"};
sz = INREG(RADEON_CONFIG_MEMSIZE);
type = INREG(RADEON_MEM_SDRAM_MODE_REG);
printf("RADEON_CONFIG_MEMSIZE = %d (%d MB)\n", sz, sz / 1024 / 1024);
printf("RADEON_MEM_SDRAM_MODE_REG >> 30 = %d (%s)\n",
type >> 30, typeStr[type>>30]);
}
#endif
}
static void
shutdown_fbdev( void )
{
struct vt_mode VT;
printf("cleaning up...\n");
/* restore original variable screen info */
if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &OrigVarInfo)) {
fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
strerror(errno));
exit(1);
}
munmap(MMIOAddress, FixedInfo.mmio_len);
munmap(FrameBuffer, FixedInfo.smem_len);
close(FrameBufferFD);
/* restore text mode */
ioctl(ConsoleFD, KDSETMODE, KD_TEXT);
/* set vt */
if (ioctl(ConsoleFD, VT_GETMODE, &VT) != -1) {
VT.mode = VT_AUTO;
ioctl(ConsoleFD, VT_SETMODE, &VT);
}
/* restore original vt */
if (OriginalVT >= 0) {
ioctl(ConsoleFD, VT_ACTIVATE, OriginalVT);
OriginalVT = -1;
}
close(ConsoleFD);
}
/* Borrowed from GLUT */
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
static void
gltest( void )
{
static const int attribs[] = {
GLFBDEV_DOUBLE_BUFFER,
GLFBDEV_DEPTH_SIZE, 16,
GLFBDEV_NONE
};
GLFBDevContextPtr ctx;
GLFBDevBufferPtr buf;
GLFBDevVisualPtr vis;
int bytes, r, g, b, a;
float ang;
int i;
printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
/* framebuffer size */
bytes = VarInfo.xres_virtual * VarInfo.yres_virtual * VarInfo.bits_per_pixel / 8;
vis = glFBDevCreateVisual( &FixedInfo, &VarInfo, attribs );
assert(vis);
buf = glFBDevCreateBuffer( &FixedInfo, &VarInfo, vis, FrameBuffer, NULL, bytes );
assert(buf);
ctx = glFBDevCreateContext( vis, NULL );
assert(buf);
b = glFBDevMakeCurrent( ctx, buf, buf );
assert(b);
/*printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));*/
glGetIntegerv(GL_RED_BITS, &r);
glGetIntegerv(GL_GREEN_BITS, &g);
glGetIntegerv(GL_BLUE_BITS, &b);
glGetIntegerv(GL_ALPHA_BITS, &a);
printf("RED_BITS=%d GREEN_BITS=%d BLUE_BITS=%d ALPHA_BITS=%d\n",
r, g, b, a);
glClearColor(0.5, 0.5, 1.0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 2, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -15);
glViewport(0, 0, VarInfo.xres_virtual, VarInfo.yres_virtual);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
printf("Drawing %d frames...\n", NumFrames);
ang = 0.0;
for (i = 0; i < NumFrames; i++) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(ang, 1, 0, 0);
doughnut(1, 3, 40, 20);
glPopMatrix();
glFBDevSwapBuffers(buf);
ang += 15.0;
}
/* clean up */
b = glFBDevMakeCurrent( NULL, NULL, NULL);
assert(b);
glFBDevDestroyContext(ctx);
glFBDevDestroyBuffer(buf);
glFBDevDestroyVisual(vis);
}
static void
parse_args(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-f") == 0) {
NumFrames = atoi(argv[i+1]);
i++;
}
}
}
int
main( int argc, char *argv[] )
{
signal(SIGUSR1, signal_handler); /* exit if someone tries a vt switch */
signal(SIGSEGV, signal_handler); /* catch segfaults */
parse_args(argc, argv);
printf("Setting mode to %d x %d @ %d Hz, %d bpp\n", XRes, YRes, Hz, DesiredDepth);
initialize_fbdev();
gltest();
shutdown_fbdev();
return 0;
}

View File

@@ -47,9 +47,12 @@ static const char *TexFiles[2] =
static GLuint Program;
static GLfloat Xrot = -90.0, Yrot = .0, Zrot = 0.0;
static GLfloat Xrot = 0.0, Yrot = .0, Zrot = 0.0;
static GLfloat EyeDist = 10;
static GLboolean Anim = GL_TRUE;
static GLboolean UseArrays = GL_TRUE;
static GLint VertCoord_attr = -1, TexCoord0_attr = -1, TexCoord1_attr = -1;
/* value[0] = tex unit */
@@ -60,32 +63,62 @@ static struct uniform_info Uniforms[] = {
};
static const GLfloat Tex0Coords[4][2] = {
{ 0.0, 0.0 }, { 2.0, 0.0 }, { 2.0, 2.0 }, { 0.0, 2.0 }
};
static const GLfloat Tex1Coords[4][2] = {
{ 0.0, 0.0 }, { 1.0, 0.0 }, { 1.0, 1.0 }, { 0.0, 1.0 }
};
static const GLfloat VertCoords[4][2] = {
{ -3.0, -3.0 }, { 3.0, -3.0 }, { 3.0, 3.0 }, { -3.0, 3.0 }
};
static void
DrawPolygon(GLfloat size)
DrawPolygonArray(void)
{
glPushMatrix();
glRotatef(90, 1, 0, 0);
glNormal3f(0, 0, 1);
glBegin(GL_POLYGON);
if (VertCoord_attr >= 0) {
glVertexAttribPointer_func(VertCoord_attr, 2, GL_FLOAT, GL_FALSE,
0, VertCoords);
glEnableVertexAttribArray_func(VertCoord_attr);
}
else {
glVertexPointer(2, GL_FLOAT, 0, VertCoords);
glEnable(GL_VERTEX_ARRAY);
}
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
glVertex2f(-size, -size);
glVertexAttribPointer_func(TexCoord0_attr, 2, GL_FLOAT, GL_FALSE,
0, Tex0Coords);
glEnableVertexAttribArray_func(TexCoord0_attr);
glMultiTexCoord2f(GL_TEXTURE0, 2, 0);
glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
glVertex2f( size, -size);
glVertexAttribPointer_func(TexCoord1_attr, 2, GL_FLOAT, GL_FALSE,
0, Tex1Coords);
glEnableVertexAttribArray_func(TexCoord1_attr);
glMultiTexCoord2f(GL_TEXTURE0, 2, 2);
glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
glVertex2f( size, size);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
glMultiTexCoord2f(GL_TEXTURE0, 0, 2);
glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
glVertex2f(-size, size);
static void
DrawPolygonVert(void)
{
GLuint i;
glBegin(GL_TRIANGLE_FAN);
for (i = 0; i < 4; i++) {
glVertexAttrib2fv_func(TexCoord0_attr, Tex0Coords[i]);
glVertexAttrib2fv_func(TexCoord1_attr, Tex1Coords[i]);
if (VertCoord_attr >= 0)
glVertexAttrib2fv_func(VertCoord_attr, VertCoords[i]);
else
glVertex2fv(VertCoords[i]);
}
glEnd();
glPopMatrix();
}
@@ -100,7 +133,10 @@ draw(void)
glRotatef(Yrot, 0, 1, 0);
glRotatef(Xrot, 1, 0, 0);
DrawPolygon(3.0);
if (UseArrays)
DrawPolygonArray();
else
DrawPolygonVert();
glPopMatrix();
@@ -123,8 +159,11 @@ key(unsigned char k, int x, int y)
(void) x;
(void) y;
switch (k) {
case ' ':
case 'a':
UseArrays = !UseArrays;
printf("Arrays: %d\n", UseArrays);
break;
case ' ':
Anim = !Anim;
if (Anim)
glutIdleFunc(idle);
@@ -232,6 +271,13 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile,
InitUniforms(program, uniforms);
TexCoord0_attr = glGetAttribLocation_func(program, "TexCoord0");
TexCoord1_attr = glGetAttribLocation_func(program, "TexCoord1");
VertCoord_attr = glGetAttribLocation_func(program, "VertCoord");
printf("TexCoord0_attr = %d\n", TexCoord0_attr);
printf("TexCoord1_attr = %d\n", TexCoord1_attr);
printf("VertCoord_attr = %d\n", VertCoord_attr);
return program;
}

View File

@@ -2,9 +2,13 @@
// Brian Paul
attribute vec4 TexCoord0, TexCoord1;
attribute vec4 VertCoord;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
gl_Position = ftransform();
gl_TexCoord[0] = TexCoord0;
gl_TexCoord[1] = TexCoord1;
// note: may use gl_Vertex or VertCoord here for testing:
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

View File

@@ -46,6 +46,13 @@ static PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_func = NULL;
static PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_func = NULL;
static PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_func = NULL;
static PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_func = NULL;
static PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_func = NULL;
static PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_func = NULL;
static PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_func = NULL;
static PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_func = NULL;
static PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_func = NULL;
static PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_func = NULL;
static PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_func = NULL;
/* OpenGL 2.1 */
static PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv_func = NULL;
@@ -126,6 +133,14 @@ GetExtensionFuncs(void)
glVertexAttrib2f_func = (PFNGLVERTEXATTRIB2FPROC) glutGetProcAddress("glVertexAttrib2f");
glVertexAttrib3f_func = (PFNGLVERTEXATTRIB3FPROC) glutGetProcAddress("glVertexAttrib3f");
glVertexAttrib4f_func = (PFNGLVERTEXATTRIB4FPROC) glutGetProcAddress("glVertexAttrib4f");
glVertexAttrib1fv_func = (PFNGLVERTEXATTRIB1FVPROC) glutGetProcAddress("glVertexAttrib1fv");
glVertexAttrib2fv_func = (PFNGLVERTEXATTRIB2FVPROC) glutGetProcAddress("glVertexAttrib2fv");
glVertexAttrib3fv_func = (PFNGLVERTEXATTRIB3FVPROC) glutGetProcAddress("glVertexAttrib3fv");
glVertexAttrib4fv_func = (PFNGLVERTEXATTRIB4FVPROC) glutGetProcAddress("glVertexAttrib4fv");
glVertexAttribPointer_func = (PFNGLVERTEXATTRIBPOINTERPROC) glutGetProcAddress("glVertexAttribPointer");
glEnableVertexAttribArray_func = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress("glEnableVertexAttribArray");
glDisableVertexAttribArray_func = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress("glDisableVertexAttribArray");
/* OpenGL 2.1 */
glUniformMatrix2x3fv_func = (PFNGLUNIFORMMATRIX2X3FVPROC) glutGetProcAddress("glUniformMatrix2x3fv");

View File

@@ -98,7 +98,7 @@ xrotfontdemo.o: xrotfontdemo.c xuserotfont.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) xrotfontdemo.c
corender: corender.o ipc.o
$(CC) $(CFLAGS) corender.o ipc.o $(LIBS) -o $@
$(CC) $(CFLAGS) $(LDFLAGS) corender.o ipc.o $(LIBS) -o $@
corender.o: corender.c ipc.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) corender.c

View File

@@ -39,6 +39,9 @@
#include <GL/gl.h>
#include <GL/glx.h>
static int is_glx_extension_supported(Display *dpy, const char *query);
static void query_vsync(Display *dpy);
#define BENCHMARK
@@ -560,6 +563,73 @@ make_window( Display *dpy, const char *name,
}
/**
* Determine whether or not a GLX extension is supported.
*/
int
is_glx_extension_supported(Display *dpy, const char *query)
{
const int scrnum = DefaultScreen(dpy);
const char *glx_extensions = NULL;
const size_t len = strlen(query);
const char *ptr;
if (glx_extensions == NULL) {
glx_extensions = glXQueryExtensionsString(dpy, scrnum);
}
ptr = strstr(glx_extensions, query);
return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
}
/**
* Attempt to determine whether or not the display is synched to vblank.
*/
void
query_vsync(Display *dpy)
{
int interval = 0;
#ifdef GLX_MESA_swap_control
if ((interval <= 0)
&& is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) {
PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA =
(PFNGLXGETSWAPINTERVALMESAPROC)
glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA");
interval = (*pglXGetSwapIntervalMESA)();
}
#endif
#ifdef GLX_SGI_video_sync
if ((interval <= 0)
&& is_glx_extension_supported(dpy, "GLX_SGI_video_sync")) {
PFNGLXGETVIDEOSYNCSGIPROC pglXGetVideoSyncSGI =
(PFNGLXGETVIDEOSYNCSGIPROC)
glXGetProcAddressARB((const GLubyte *) "glXGetVideoSyncSGI");
unsigned count;
if ((*pglXGetVideoSyncSGI)(& count) == 0) {
interval = (int) count;
}
}
#endif
if (interval > 0) {
printf("Running synchronized to the vertical refresh. The framerate should be\n");
if (interval == 1) {
printf("approximately the same as the monitor refresh rate.\n");
} else if (interval > 1) {
printf("approximately 1/%d the monitor refresh rate.\n",
interval);
}
}
}
/**
* Handle one X event.
* \return NOP, EXIT or DRAW
@@ -567,6 +637,9 @@ make_window( Display *dpy, const char *name,
static int
handle_event(Display *dpy, Window win, XEvent *event)
{
(void) dpy;
(void) win;
switch (event->type) {
case Expose:
return DRAW;
@@ -686,6 +759,7 @@ main(int argc, char *argv[])
make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx);
XMapWindow(dpy, win);
glXMakeCurrent(dpy, win, ctx);
query_vsync(dpy);
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));

View File

@@ -178,6 +178,7 @@ int main( int argc, char *argv[] )
glColor3f( 0.0, 1.0, 1.0 );
glRectf( -0.75, -0.75, 0.75, 0.75 );
glFlush();
glXWaitGL();
XMapWindow( dpy, win );

View File

@@ -286,7 +286,7 @@ EventLoop(void)
XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
switch (keySym) {
case XK_Escape:
exit(0);
return;
break;
case XK_d:
case XK_D:

View File

@@ -1,24 +0,0 @@
# src/egl/Makefile
TOP = ../..
SUBDIRS = main drivers/demo drivers/dri
default: subdirs
subdirs:
@for dir in $(SUBDIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE)) || exit 1 ; \
fi \
done
clean:
-@for dir in $(SUBDIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE) clean) ; \
fi \
done

View File

@@ -1,564 +0,0 @@
Name
MESA_screen_surface
Name Strings
EGL_MESA_screen_surface
Contact
Brian Paul
To discuss, join the dri-egl@lists.freedesktop.org list.
Status
Preliminary - totally subject to change.
Version
11 (27 January 2006)
Number
TBD
Dependencies
EGL 1.0 or later.
Overview
EGL 1.1 supports three types of drawing surfaces:
* Window surfaces
* Pixmap surfaces
* Pbuffer surfaces
This extension defines a fourth type of drawing surface:
* Screen surface
A screen surface is a surface for which the (front) color buffer can
be directly displayed (i.e. scanned out) on a monitor (such as a flat
panel or CRT). In particular the color buffer memory will be allocated
at a location in VRAM (and in a suitable format) which can be displayed
by the graphics hardware.
Note that the width and height of the screen surface need not exactly
match the monitor's current resolution. For example, while the monitor
may be configured to to show 1024x768 pixels, the associated screen
surface may be larger, such as 1200x1000. The "screen origin" attribute
will specify which region of the screen surface which is visible on the
monitor. The screen surface can be scrolled by changing this origin.
This extension also defines functions for controlling the monitor's
display mode (width, height, refresh rate, etc), and specifing which
screen surface is to be displayed on a monitor.
The new EGLModeMESA type and related functions are very similar to the
EGLConfig type and related functions. The user may get a list of
supported modes for a screen and specify the mode to be used when
displaying a screen surface.
Issues
1. Should EGL_INTERLACE be a supported mode attribute?
Arguments against:
No, this should be provided by another extension which would
also provide the mechanisms needed to play back interlaced video
material correctly on hardware that supports it.
This extension should prefer non-interlaced modes. [M. Danzer]
Arguments for:
An interlaced display can be of use without considering video
material. Being able to query whether a screen is operating in
interlaced mode can be used by applications to control their
drawing. For example: avoid drawing 1-pixel-wide horizontal lines
if screen is interlaced. [B. Paul]
Resolution: Defer for future extension?
2. Should EGL_REFRESH_RATE be a supported mode attribute?
Arguments for:
Yes, it's been shown that applications and/or users need to select
modes by this. [M. Danzer]
Many examples have been given in which it's desirable to let the
user choose from a variety of refresh rates without having to
restart/reconfigure. [B. Paul]
Arguments against:
TBD.
Resolution: Yes.
3. Exactly how should the list of modes returned by eglChooseConfigMESA
be sorted?
Current method is described in the text below. Subject to change.
Alternately, leave the sorting order undefined so that each
implementation can return the modes in order of "most desirable"
to "least desirable" which may depend on the display technology
(CRT vs LCD, etc) or other factors.
4. How should screen blanking be supported? Note that a screen can be
disabled or turned off by calling eglShowSurface(dpy, scrn,
EGL_NO_SURFACE, EGL_NO_MODE_MESA). But what about power-save mode?
I would defer this to other extensions that depend on this one.
I can imagine people wanting different semantics not just in
relation to the power management API being exposed (DPMS or whatever)
but also relating to what events can trigger EGL_CONTEXT_LOST. Also
I'm not sure whether power management commands are properly operations
on the Display or on a screen surface. [A. Jackson]
5. Should the EGL_PHYSICAL_SIZE_EGL query be kept? The size information
isn't always reliable (consider video projectors) but can still be
used to determine the pixel aspect ratio.
Resolution: Omit. The EGL 1.2 specification includes queries for
the display resolution and pixel aspect ratio.
6. Should detailed mode timing information be exposed by this API?
Probably not. Instead, offer that information in a layered extension.
7. How should the notion of a screen's "native" mode be expressed?
For example, LCD panels have a native resolution and refresh rate
that looks best but other sub-optimal resolutions may be supported.
The mode attribute EGL_OPTIMAL_MESA will be set for modes which
best match the screen. [M. Danzer]
8. Should eglQueryModeStringMESA() be included? This function returns
a human-readable string which corresponds to an EGLMode.
Arguments for:
A mode name such as "HDTV-720P" might mean more to users than
"1280x720@60Hz" if the later were generated via code.
Arguments against:
There's no standard syntax for the strings. May cause more
trouble than it's worth.
Postpone for future extension. [A. Jackson]
Latest discussion leaning toward omitting this function.
9. Should we use "Get" or "Query" for functions which return state?
The EGL 1.x specification doesn't seem to be totally consistent
in this regard, but "Query" is used more often.
Use "Get" for mode-related queries (as for EGLConfigs) but "Query"
for everything else.
10. What should be the default size for screen surfaces?
For Pbuffer surfaces the default width and height are zero.
We'll do the same for screen surfaces. Since there's no function
to resize surfaces it's useless to have a 0x0 screen, but this isn't
a situation that'll normally be encountered.
11. Should there be a function for resizing a screen surface?
Suppose one wants to change the screen's size in the EGL application.
Also suppose there's a hardware restriction such that only one screen
surface can exist at a time (either for lack of memory or because of
memory layout restrictions).
The basic idea is that the currently displayed screen surface must
be deallocated before a new one can be created. Perhaps a resize
function would work better?
12. How should sub-pixel LCD color information be made available?
What about the display's gamma value?
Perhaps expose as additional read-only mode attributes.
Perhaps postpone for a layered extension.
13. What happens if the user attempts to delete a screen surface that
is currently being shown?
Spec currently says that's illegal and that an error (TBD) will be
generated.
14. What if the physical screen size can't be determined? Should
a query of EGL_PHYSICAL_SIZE_MESA return [0,0]?
Obsolete: EGL_PHYSICAL_SIZE_MESA not used.
15. Suppose the device's number of RAMDACs is different from the
number of output ports. For example, a graphics card with
two RAMDACs but three ports (VGA, DVI, TV).
Address this in a follow-on extension. [Matthias Hopf]
16. How should we deal with on-the-fly device changes? For example,
the monitor being unplugged and replaced by another with different
characteristics?
A HAL event could be received via DBUS in the application [J. Smirl,
A. Jackson].
Should there be an EGL mechanism for detecting this? Maybe an
EGL_SCREEN_LOST error (similar to EGL_CONTEXT_LOST) can be recorded
when there's a screen change. At least then the application can
poll to detect this situation.
Maybe leave that to a future extension.
See also the EGL_SCREEN_COUNT_MESA query.
17. What if pixel-accurate panning is not supported (see
eglScreenPositionMESA)? [M. Danzer]
Is this a common problem? Can we ignore it for now?
18. Should eglShowSurfaceMESA be renamed to eglShowScreenSurfaceMESA?
Probably.
New Procedures and Functions
EGLBoolean eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list,
EGLModeMESA *modes, EGLint modes_size,
EGLint *num_modes)
EGLBoolean eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *modes, EGLint modes_size,
EGLint *num_modes)
EGLBoolean eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
EGLint attrib, EGLint *value)
EGLBoolean eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
EGLint screens_size, EGLint *num_screens)
EGLSurface eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
EGLBoolean eglShowSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLSurface surface, EGLModeMESA mode)
EGLBoolean eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLint x, EGLint y)
EGLBoolean eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLint attrib, EGLint *value);
EGLBoolean eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLSurface *surface)
EGLBoolean eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *mode)
const char *eglQueryModeStringMESA(EGLDisplay dpy, EGLMode mode);
New Types
EGLModeMESA
EGLScreenMESA
New Tokens
New error codes:
EGL_BAD_SCREEN_MESA
EGL_BAD_MODE_MESA
Screen-related tokens:
EGL_SCREEN_COUNT_MESA
EGL_SCREEN_POSITION_MESA
EGL_SCREEN_BIT_MESA
EGL_SCREEN_POSITION_GRANULARITY_MESA
Mode-related tokens:
EGL_MODE_ID_MESA
EGL_REFRESH_RATE_MESA
EGL_INTERLACED_MESA
EGL_OPTIMAL_MESA
EGL_NO_MODE_MESA
Additions to Chapter X of the EGL 1.1 Specification
[XXX this all has to be rewritten to fit into the EGL specification
and match the conventions of an EGL extension. For now, just list
all the functions with brief descriptions.]
EGLBoolean eglChooseModeMESA(EGLDisplay dpy, const EGLScreenMESA screen,
EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
Like eglChooseConfig, returns a list of EGLModes which match the given
attribute list. This does not set the screen's current display mode.
The attribute list is a list of token/value pairs terminated with
EGL_NONE. Supported attributes include:
Name Description
--------------------- ---------------------------------------------
EGL_WIDTH Mode width (resolution)
EGL_HEIGHT Mode height (resolution)
EGL_REFRESH_RATE_MESA The mode's refresh rate, multiplied by 1000
EGL_INTERLACED_MESA 1 indicates an interlaced mode, 0 otherwise
EGL_OPTIMAL_MESA Set if the most is especially optimal for the
screen (ex. for particular LCD resolutions)
Any other token will generate the error EGL_BAD_ATTRIBUTE.
The list of modes returned by eglChooseModeMESA will be sorted
according to the following criteria. See the discussion of table 3.3
in the EGL specification for more information.
Selection Sort Sort
Attribute Default Criteria Order Priority
-------------------- -------------- ----------- ------ --------
EGL_OPTIMAL_MESA EGL_DONT_CARE Exact 1,0 1
EGL_INTERLACED_MESA EGL_DONT_CARE Exact 0,1 2
EGL_REFRESH_RATE EGL_DONT_CARE AtLeast Larger 3
EGL_WIDTH EGL_DONT_CARE AtLeast Larger 4
EGL_HEIGHT EGL_DONT_CARE AtLeast Larger 5
EGL_MODE_ID_MESA EGL_DONT_CARE Exact Smaller 6
EGLBoolean eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *modes, EGLint modes_size,
EGLint *num_modes)
Like eglGetConfigs, returns a list of all modes supported by the
given screen. The returned modes will be sorted in the same manner
as for eglChooseModeMESA().
EGLBoolean eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
EGLint attrib, EGLint *value)
Used to query mode attributes. The following attributes are supported:
Name Return value description
--------------------- ----------------------------------------------
EGL_OPTIMAL_MESA 1 indicates an optimal mode, 0 otherwise
EGL_INTERLACED_MESA 1 indicates an interlaced mode, 0 otherwise
EGL_REFRESH_RATE_MESA The mode's refresh rate, multiplied by 1000
EGL_WIDTH Mode width (resolution)
EGL_HEIGHT Mode height (resolution)
EGL_MODE_ID_MESA A unique small integer identifier for the mode
Any other token will generate the error EGL_BAD_ATTRIBUTE.
EGLBoolean eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
EGLint screens_size, EGLint *num_screens)
This function returns an array of all available screen handles.
<screens_size> is the maximum number of screens to return in the
<screens> array. <num_screens> will return the number of screen handles
placed in the array, even if <screens> is NULL.
The number of screens and the availability of each may change over
time (hot-plugging). Screen handles will not be reused. When a
screen handle becomes invalid, function calls which reference an
invalid handle will generate EGL_BAD_SCREEN_MESA.
The first screen handle returned will be considered to be the primary
one.
EGLSurface eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
Create a surface that can be displayed on a screen. <attrib_list> is
an array of token/value pairs terminated with EGL_NONE. Valid tokens
include:
Name Description
---------------- --------------------------------
EGL_WIDTH desired surface width in pixels
EGL_HEIGHT desired surface height in pixels
Any other token will generate the error EGL_BAD_ATTRIBUTE.
The default width and height are zero.
EGLBoolean eglShowSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLSurface surface, EGLModeMESA mode)
This function causes a screen to show the given surface (or more
precisely, the surface's front color buffer) with the given mode.
If the surface is in any way incompatible with the mode, the error
EGL_BAD_MATCH will be generated, EGL_FALSE will be returned, and the
previous screen state will remain in effect. This might occur when
the bandwidth of the video-out subsystem is exceeded, or if the mode
specifies a width or height that's greater than the width or height
of the surface.
To disable a screen, the values EGL_NO_SURFACE and EGL_NO_MODE_MESA
be passed as the <surface> and <mode> parameters.
The values of EGL_SCREEN_POSITION_MESA are clamped to the new valid
range computed from the screen size and surface size. If the new
surface is EGL_NO_SURFACE, EGL_SCREEN_POSITION_MESA is set to [0, 0].
Attempting to delete a screen surface which is currently being
displayed will result in the error EGL_BAD_ACCESS being generated.
EGLBoolean eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLint x, EGLint y)
Specifies the origin of the screen's view into the surface, if the
surface is larger than the screen. Valid values for x and y are
[0, surfaceWidth - screenWidth] and [0, surfaceHeight - screenHeight],
respectively.
The x and y values are also constrained to be integer multiples of the
EGL_SCREEN_POSITION_GRANULARITY_MESA values.
EGLBoolean eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLint attrib, EGLint *value);
Used to query screen attributes. <attrib> may be one of the following:
Name Return value description
------------------------ ---------------------------------------------
EGL_SCREEN_POSITION_MESA x, y position of the screen's origin with
respect to the surface. If no surface is
attached to the screen, [0, 0] is returned.
EGL_SCREEN_POSITION_GRANULARITY_MESA
Returns the granularity, in pixels, for
which the screen position is constrained.
Any other token will generate the error EGL_BAD_ATTRIBUTE.
EGLBoolean eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLSurface *surface)
Returns the surface currently displayed on the given screen. <surface>
may be EGL_NO_SURFACE if the screen isn't currently showing any surface.
EGLBoolean eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *mode)
Returns the given screen's current display mode. The mode may be
EGL_NO_MODE_MESA if the screen is currently disabled.
const char *eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
Returns a human-readable string for the given mode. The string is a
zero-terminated C string which the user should not attempt to free.
There is no standard syntax for mode strings. Applications should
not directly rely on mode strings.
Version History
1. 15 March 2005 - BrianP
Initial version
2. 16 March 2005 - BrianP
Removed EGL_DEPTH_MESA
Added EGL_PHYSICAL_WIDTH_MESA, EGL_PHYSICAL_HEIGHT_MESA queries
Added EGL_OPTIMAL_MESA for width/height/refresh rate selection
Added possible eglQueryModeStringMESA() function
More details of the new functions explained.
3. 18 March 2005 - BrianP
Added screen_number to eglChooseModeMESA().
Fix off by one mistake in value range for ORIGIN attributes
Added Issues section
4. 21 March 2005 - BrianP
Removed eglScreenAttribsMESA().
Added eglScreenPositionMESA() to set screen origin.
Replaced EGL_SCREEN_X/Y_OFFSET_MESA with EGL_SCREEN_POSITION_MESA.
Replaced EGL_PHYSICAL_WIDTH/HEIGHT_MESA with EGL_PHYSICAL_SIZE_MESA.
Use EGL_OPTIMAL_MESA as a new mode attribute. (Michel Danzer)
Added a few more issues.
5. 6 April 2005 - BrianP
More language for eglGetModeStringMESA().
Added issues 10, 11, 12, 13, 14.
Updated issue 3 discussion about mode sorting.
6. 22 April 2005 - BrianP
Fixed "LDC" typo.
Added issues 15, 16.
Changed dependency on EGL 1.1 to EGL 1.0
s/EGL_NUM_SCREENS_MESA/EGL_SCREEN_COUNT_MESA/
Added eglQueryDisplayMESA() to New Functions section.
Clarified language for the EGL_SCREEN_COUNT_MESA query.
7. 29 April 2005 - BrianP
Added EGLScreenMESA type and eglGetScreensMESA() function. [J. Smirl].
Replaced EGLint screen_number parameters with EGLScreenMESA screen.
Added issue 17 (pixel-accurate panning)
8. 2 May 2005 - BrianP
Removed eglQueryDisplayMESA.
Fixed a few more EGLint -> EGLScreenMESA changes.
9. 20 May 2005 - BrianP
Fixed a few typos.
Updated some open issues text.
10. 10 August 2005 - BrianP
Added EGL_SCREEN_POSITION_GRANULARITY_MESA.
11. 27 January 2006 - BrianP
EGL_PHYSICAL_SIZE_MESA removed since EGL 1.2 has a similar feature.

View File

@@ -1,32 +0,0 @@
# src/egl/drivers/demo/Makefile
TOP = ../../../..
include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main
SOURCES = demo.c
OBJECTS = $(SOURCES:.c=.o)
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: $(TOP)/$(LIB_DIR)/demodriver.so
$(TOP)/$(LIB_DIR)/demodriver.so: $(OBJECTS)
$(MKLIB) -o demodriver.so -noprefix -linker '$(CC)' \
-ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \
$(OBJECTS)
clean:
-rm -f *.o
-rm -f *.so

View File

@@ -1,316 +0,0 @@
/*
* Sample driver: Demo
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
/**
* Demo driver-specific driver class derived from _EGLDriver
*/
typedef struct demo_driver
{
_EGLDriver Base; /* base class/object */
GLuint DemoStuff;
} DemoDriver;
#define DEMO_DRIVER(D) ((DemoDriver *) (D))
/**
* Demo driver-specific surface class derived from _EGLSurface
*/
typedef struct demo_surface
{
_EGLSurface Base; /* base class/object */
GLuint DemoStuff;
} DemoSurface;
/**
* Demo driver-specific context class derived from _EGLContext
*/
typedef struct demo_context
{
_EGLContext Base; /* base class/object */
GLuint DemoStuff;
} DemoContext;
static EGLBoolean
demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLScreen *scrn;
EGLint i;
/* Create a screen */
scrn = calloc(1, sizeof(*scrn));
_eglAddScreen(disp, scrn);
/* Create the screen's modes - silly example */
_eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72");
_eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70");
_eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70");
_eglAddNewMode(scrn, 1024, 768, 72 * 1000, "1024x768-72");
/* Create the display's visual configs - silly example */
for (i = 0; i < 4; i++) {
_EGLConfig config;
_eglInitConfig(&config, i + 1);
_eglSetConfigAttrib(&config, EGL_RED_SIZE, 8);
_eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8);
_eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8);
_eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8);
_eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32);
if (i & 1) {
_eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 32);
}
if (i & 2) {
_eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8);
}
_eglSetConfigAttrib(&config, EGL_SURFACE_TYPE,
(EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
_eglAddConfig(disp, &config);
}
drv->Initialized = EGL_TRUE;
*major = 1;
*minor = 0;
return EGL_TRUE;
}
static EGLBoolean
demoTerminate(_EGLDriver *drv, EGLDisplay dpy)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
free(drv);
return EGL_TRUE;
}
static DemoContext *
LookupDemoContext(EGLContext ctx)
{
_EGLContext *c = _eglLookupContext(ctx);
return (DemoContext *) c;
}
static DemoSurface *
LookupDemoSurface(EGLSurface surf)
{
_EGLSurface *s = _eglLookupSurface(surf);
return (DemoSurface *) s;
}
static EGLContext
demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
_EGLConfig *conf;
DemoContext *c;
int i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_NO_CONTEXT;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
return EGL_NO_CONTEXT;
}
}
c = (DemoContext *) calloc(1, sizeof(DemoContext));
if (!c)
return EGL_NO_CONTEXT;
_eglInitContext(drv, dpy, &c->Base, config, attrib_list);
c->DemoStuff = 1;
printf("demoCreateContext\n");
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
assert(c->Base.Handle);
return c->Base.Handle;
}
static EGLSurface
demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
int i;
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
return EGL_NO_SURFACE;
}
}
printf("eglCreateWindowSurface()\n");
/* XXX unfinished */
return EGL_NO_SURFACE;
}
static EGLSurface
demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLConfig *conf;
EGLint i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
}
if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
_eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
printf("eglCreatePixmapSurface()\n");
return EGL_NO_SURFACE;
}
static EGLSurface
demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT,
config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
/* a real driver would allocate the pbuffer memory here */
return surf->Base.Handle;
}
static EGLBoolean
demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
DemoSurface *fs = LookupDemoSurface(surface);
_eglRemoveSurface(&fs->Base);
if (fs->Base.IsBound) {
fs->Base.DeletePending = EGL_TRUE;
}
else {
free(fs);
}
return EGL_TRUE;
}
static EGLBoolean
demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
DemoContext *fc = LookupDemoContext(context);
_eglRemoveContext(&fc->Base);
if (fc->Base.IsBound) {
fc->Base.DeletePending = EGL_TRUE;
}
else {
free(fc);
}
return EGL_TRUE;
}
static EGLBoolean
demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
DemoSurface *readSurf = LookupDemoSurface(read);
DemoSurface *drawSurf = LookupDemoSurface(draw);
DemoContext *ctx = LookupDemoContext(context);
EGLBoolean b;
b = _eglMakeCurrent(drv, dpy, draw, read, context);
if (!b)
return EGL_FALSE;
/* XXX this is where we'd do the hardware context switch */
(void) drawSurf;
(void) readSurf;
(void) ctx;
printf("eglMakeCurrent()\n");
return EGL_TRUE;
}
/**
* The bootstrap function. Return a new DemoDriver object and
* plug in API functions.
*/
_EGLDriver *
_eglMain(_EGLDisplay *dpy)
{
DemoDriver *demo;
demo = (DemoDriver *) calloc(1, sizeof(DemoDriver));
if (!demo) {
return NULL;
}
/* First fill in the dispatch table with defaults */
_eglInitDriverFallbacks(&demo->Base);
/* then plug in our Demo-specific functions */
demo->Base.API.Initialize = demoInitialize;
demo->Base.API.Terminate = demoTerminate;
demo->Base.API.CreateContext = demoCreateContext;
demo->Base.API.MakeCurrent = demoMakeCurrent;
demo->Base.API.CreateWindowSurface = demoCreateWindowSurface;
demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface;
demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface;
demo->Base.API.DestroySurface = demoDestroySurface;
demo->Base.API.DestroyContext = demoDestroyContext;
/* enable supported extensions */
demo->Base.Extensions.MESA_screen_surface = EGL_TRUE;
demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
return &demo->Base;
}

View File

@@ -1,62 +0,0 @@
# src/egl/drivers/dri/Makefile
TOP = ../../../..
include $(TOP)/configs/current
### Include directories
INCLUDE_DIRS = \
-I. \
-I/usr/include \
-I/usr/include/drm \
-I$(TOP)/include \
-I$(TOP)/include/GL/internal \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/main \
-I$(TOP)/src/mesa/glapi \
-I$(TOP)/src/mesa/math \
-I$(TOP)/src/mesa/transform \
-I$(TOP)/src/mesa/shader \
-I$(TOP)/src/mesa/swrast \
-I$(TOP)/src/mesa/swrast_setup \
-I$(TOP)/src/egl/main \
-I$(TOP)/src/mesa/drivers/dri/common
HEADERS = egldri.h
SOURCES = egldri.c
OBJECTS = $(SOURCES:.c=.o)
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend library Makefile
# EGLdri Library
library: $(TOP)/$(LIB_DIR)/libEGLdri.so
$(TOP)/$(LIB_DIR)/libEGLdri.so: $(OBJECTS)
$(MKLIB) -o EGLdri -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major 1 -minor 0 \
-install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS)
clean:
-rm -f *.o
-rm -f *.so
depend: $(SOURCES) $(HEADERS)
@ echo "running $(MKDEP)"
@ touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
$(SOURCES) $(HEADERS) > /dev/null
include depend
# DO NOT DELETE

File diff suppressed because it is too large Load Diff

View File

@@ -1,113 +0,0 @@
#ifndef EGLDRI_INCLUDED
#define EGLDRI_INCLUDED
#include "egldisplay.h"
#include "eglscreen.h"
#include "eglsurface.h"
#include "eglcontext.h"
#include "mtypes.h"
#include "dri_util.h"
#include "drm_sarea.h"
/**
* dri display-specific driver class derived from _EGLDisplay
*/
typedef struct dri_display
{
_EGLDisplay Base; /* base class/object */
void *pFB;
int drmFD; /**< \brief DRM device file descriptor */
int minor;
unsigned long hFrameBuffer;
int virtualWidth;
int virtualHeight;
int fbSize;
int bpp;
int cpp;
int card_type;
int SAREASize;
drm_sarea_t *pSAREA;
unsigned int serverContext; /**< \brief DRM context only active on server */
unsigned long FBStart; /**< \brief physical address of the framebuffer */
void *driverClientMsg;
int driverClientMsgSize;
int chipset;
void *driverPrivate;
drm_magic_t magic;
__DRIscreen driScreen;
} driDisplay;
/**
* dri driver-specific screen class derived from _EGLScreen
*/
typedef struct dri_screen
{
_EGLScreen Base;
char fb[NAME_MAX]; /** the screen name, like "fb0" */
} driScreen;
/**
* dri driver-specific surface class derived from _EGLSurface
*/
typedef struct dri_surface
{
_EGLSurface Base; /* base class/object */
__DRIdrawable drawable;
} driSurface;
/**
* dri driver-specific context class derived from _EGLContext
*/
typedef struct dri_context
{
_EGLContext Base; /* base class/object */
__DRIcontext driContext; /**< \brief context dependent methods */
} driContext;
static inline driDisplay *
Lookup_driDisplay(EGLDisplay dpy)
{
_EGLDisplay *d = _eglLookupDisplay(dpy);
return (driDisplay *) d;
}
static inline driScreen *
Lookup_driScreen(EGLDisplay dpy, EGLScreenMESA screen)
{
_EGLScreen *s = _eglLookupScreen(dpy, screen);
return (driScreen *) s;
}
static inline driContext *
Lookup_driContext(EGLContext ctx)
{
_EGLContext *c = _eglLookupContext(ctx);
return (driContext *) c;
}
static inline driSurface *
Lookup_driSurface(EGLSurface surf)
{
_EGLSurface *s = _eglLookupSurface(surf);
return (driSurface *) s;
}
extern void _eglDRIInitDriverFallbacks(_EGLDriver *drv);
extern EGLBoolean _eglDRIShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA m);
extern EGLBoolean _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor);
extern EGLBoolean _eglDRIGetDisplayInfo(driDisplay *dpy);
extern EGLBoolean _eglDRICreateDisplay(driDisplay *dpy, __DRIframebuffer *framebuffer);
extern EGLBoolean _eglDRICreateScreens(driDisplay *dpy);
#endif /* EGLDRI_INCLUDED */

View File

@@ -1,67 +0,0 @@
# src/egl/main/Makefile
TOP = ../../..
include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi
HEADERS = \
eglconfig.h \
eglcontext.h \
egldisplay.h \
egldriver.h \
eglglobals.h \
egllog.h \
eglhash.h \
eglmode.h \
eglscreen.h \
eglsurface.h
SOURCES = \
eglapi.c \
eglconfig.c \
eglcontext.c \
egldisplay.c \
egldriver.c \
eglglobals.c \
egllog.c \
eglhash.c \
eglmode.c \
eglscreen.c \
eglsurface.c
OBJECTS = $(SOURCES:.c=.o)
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend library
# EGL Library
library: $(TOP)/$(LIB_DIR)/libEGL.so
$(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS)
$(MKLIB) -o EGL -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major 1 -minor 0 \
-install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS)
clean:
-rm -f *.o *.so*
-rm -f core.*
depend: $(SOURCES) $(HEADERS)
@ echo "running $(MKDEP)"
@ touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
$(SOURCES) $(HEADERS) > /dev/null
include depend
# DO NOT DELETE

View File

@@ -1,586 +0,0 @@
/**
* Public EGL API entrypoints
*
* Generally, we use the EGLDisplay parameter as a key to lookup the
* appropriate device driver handle, then jump though the driver's
* dispatch table to handle the function.
*
* That allows us the option of supporting multiple, simultaneous,
* heterogeneous hardware devices in the future.
*
* The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
* opaque handles implemented with 32-bit unsigned integers.
* It's up to the driver function or fallback function to look up the
* handle and get an object.
* By using opaque handles, we leave open the possibility of having
* indirect rendering in the future, like GLX.
*
*
* Notes on naming conventions:
*
* eglFooBar - public EGL function
* EGL_FOO_BAR - public EGL token
* EGLDatatype - public EGL datatype
*
* _eglFooBar - private EGL function
* _EGLDatatype - private EGL datatype, typedef'd struct
* _egl_struct - private EGL struct, non-typedef'd
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
#include "egldisplay.h"
#include "egltypedefs.h"
#include "eglglobals.h"
#include "egldriver.h"
#include "eglsurface.h"
/**
* NOTE: displayName is treated as a string in _eglChooseDriver()!!!
* This will probably change!
* See _eglChooseDriver() for details!
*/
EGLDisplay APIENTRY
eglGetDisplay(NativeDisplayType displayName)
{
_EGLDisplay *dpy;
_eglInitGlobals();
dpy = _eglNewDisplay(displayName);
if (dpy)
return dpy->Handle;
else
return EGL_NO_DISPLAY;
}
EGLBoolean APIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
if (dpy) {
_EGLDriver *drv = _eglChooseDriver(dpy);
if (drv)
return drv->API.Initialize(drv, dpy, major, minor);
}
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglTerminate(EGLDisplay dpy)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return _eglCloseDriver(drv, dpy);
else
return EGL_FALSE;
}
const char * APIENTRY
eglQueryString(EGLDisplay dpy, EGLint name)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->API.QueryString(drv, dpy, name);
else
return NULL;
}
EGLBoolean APIENTRY
eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
/* XXX check drv for null in remaining functions */
return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
}
EGLBoolean APIENTRY
eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
}
EGLBoolean APIENTRY
eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
}
EGLContext APIENTRY
eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
}
EGLBoolean APIENTRY
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.DestroyContext(drv, dpy, ctx);
}
EGLBoolean APIENTRY
eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
}
EGLBoolean APIENTRY
eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
}
EGLSurface APIENTRY
eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
}
EGLSurface APIENTRY
eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
}
EGLSurface APIENTRY
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
}
EGLBoolean APIENTRY
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.DestroySurface(drv, dpy, surface);
}
EGLBoolean APIENTRY
eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
}
EGLBoolean APIENTRY
eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
}
EGLBoolean APIENTRY
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.BindTexImage(drv, dpy, surface, buffer);
}
EGLBoolean APIENTRY
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
}
EGLBoolean APIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.SwapInterval(drv, dpy, interval);
}
EGLBoolean APIENTRY
eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.SwapBuffers(drv, dpy, draw);
}
EGLBoolean APIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CopyBuffers(drv, dpy, surface, target);
}
EGLBoolean APIENTRY
eglWaitGL(void)
{
EGLDisplay dpy = eglGetCurrentDisplay();
if (dpy != EGL_NO_DISPLAY) {
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.WaitGL(drv, dpy);
}
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglWaitNative(EGLint engine)
{
EGLDisplay dpy = eglGetCurrentDisplay();
if (dpy != EGL_NO_DISPLAY) {
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.WaitNative(drv, dpy, engine);
}
else
return EGL_FALSE;
}
EGLDisplay APIENTRY
eglGetCurrentDisplay(void)
{
_EGLDisplay *dpy = _eglGetCurrentDisplay();
if (dpy)
return dpy->Handle;
else
return EGL_NO_DISPLAY;
}
EGLContext APIENTRY
eglGetCurrentContext(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx)
return ctx->Handle;
else
return EGL_NO_CONTEXT;
}
EGLSurface APIENTRY
eglGetCurrentSurface(EGLint readdraw)
{
_EGLSurface *s = _eglGetCurrentSurface(readdraw);
if (s)
return s->Handle;
else
return EGL_NO_SURFACE;
}
EGLint APIENTRY
eglGetError(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLint e = t->LastError;
t->LastError = EGL_SUCCESS;
return e;
}
void (* APIENTRY eglGetProcAddress(const char *procname))()
{
typedef void (*genericFunc)();
struct name_function {
const char *name;
_EGLProc function;
};
static struct name_function egl_functions[] = {
/* alphabetical order */
{ "eglBindTexImage", (_EGLProc) eglBindTexImage },
{ "eglChooseConfig", (_EGLProc) eglChooseConfig },
{ "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
{ "eglCreateContext", (_EGLProc) eglCreateContext },
{ "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
{ "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
{ "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
{ "eglDestroyContext", (_EGLProc) eglDestroyContext },
{ "eglDestroySurface", (_EGLProc) eglDestroySurface },
{ "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
{ "eglGetConfigs", (_EGLProc) eglGetConfigs },
{ "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
{ "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
{ "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
{ "eglGetDisplay", (_EGLProc) eglGetDisplay },
{ "eglGetError", (_EGLProc) eglGetError },
{ "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
{ "eglInitialize", (_EGLProc) eglInitialize },
{ "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
{ "eglQueryContext", (_EGLProc) eglQueryContext },
{ "eglQueryString", (_EGLProc) eglQueryString },
{ "eglQuerySurface", (_EGLProc) eglQuerySurface },
{ "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
{ "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
{ "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
{ "eglSwapInterval", (_EGLProc) eglSwapInterval },
{ "eglTerminate", (_EGLProc) eglTerminate },
{ "eglWaitGL", (_EGLProc) eglWaitGL },
{ "eglWaitNative", (_EGLProc) eglWaitNative },
/* Extensions */
#ifdef EGL_MESA_screen_surface
{ "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
{ "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
{ "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
{ "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
{ "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
{ "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
{ "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
{ "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
{ "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
{ "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
{ "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
{ "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
#endif /* EGL_MESA_screen_surface */
#ifdef EGL_VERSION_1_2
{ "eglBindAPI", (_EGLProc) eglBindAPI },
{ "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
{ "eglQueryAPI", (_EGLProc) eglQueryAPI },
{ "eglReleaseThread", (_EGLProc) eglReleaseThread },
{ "eglWaitClient", (_EGLProc) eglWaitClient },
#endif /* EGL_VERSION_1_2 */
{ NULL, NULL }
};
EGLint i;
for (i = 0; egl_functions[i].name; i++) {
if (strcmp(egl_functions[i].name, procname) == 0) {
return (genericFunc) egl_functions[i].function;
}
}
#if 0
/* XXX enable this code someday */
return (genericFunc) _glapi_get_proc_address(procname);
#else
return NULL;
#endif
}
/*
* EGL_MESA_screen extension
*/
EGLBoolean APIENTRY
eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
else
return EGL_FALSE;
}
EGLBoolean
eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
else
return EGL_FALSE;
}
EGLSurface
eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
}
EGLBoolean
eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
}
EGLBoolean
eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
}
EGLBoolean
eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
}
EGLBoolean
eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
}
EGLBoolean
eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
}
const char *
eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.QueryModeStringMESA(drv, dpy, mode);
}
/**
** EGL 1.2
**/
#ifdef EGL_VERSION_1_2
EGLBoolean
eglBindAPI(EGLenum api)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
switch (api) {
case EGL_OPENGL_ES_API:
if (_eglGlobal.OpenGLESAPISupported) {
t->CurrentAPI = api;
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
case EGL_OPENVG_API:
if (_eglGlobal.OpenVGAPISupported) {
t->CurrentAPI = api;
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
default:
return EGL_FALSE;
}
return EGL_TRUE;
}
EGLSurface
eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLClientBuffer buffer, EGLConfig config,
const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
config, attrib_list);
}
EGLenum
eglQueryAPI(void)
{
/* returns one of EGL_OPENGL_ES_API or EGL_OPENVG_API */
_EGLThreadInfo *t = _eglGetCurrentThread();
return t->CurrentAPI;
}
EGLBoolean
eglReleaseThread(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLDisplay dpy = eglGetCurrentDisplay();
if (dpy) {
_EGLDriver *drv = _eglLookupDriver(dpy);
/* unbind context */
(void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
_eglDeleteThreadData(t);
return EGL_TRUE;
}
EGLBoolean
eglWaitClient(void)
{
EGLDisplay dpy = eglGetCurrentDisplay();
if (dpy != EGL_NO_DISPLAY) {
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->API.WaitClient(drv, dpy);
}
else
return EGL_FALSE;
}
#endif /* EGL_VERSION_1_2 */

View File

@@ -1,119 +0,0 @@
#ifndef EGLAPI_INCLUDED
#define EGLAPI_INCLUDED
/**
* Typedefs for all EGL API entrypoint functions.
*/
/* driver funcs */
typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy);
/* config funcs */
typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
/* context funcs */
typedef EGLContext (*CreateContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
/* surface funcs */
typedef EGLSurface (*CreateWindowSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
typedef EGLSurface (*CreatePixmapSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
typedef EGLSurface (*CreatePbufferSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
/* misc funcs */
typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy);
typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
#ifdef EGL_MESA_screen_surface
typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
typedef EGLSurface (*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
#endif /* EGL_MESA_screen_surface */
#ifdef EGL_VERSION_1_2
typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, EGLDisplay dpy);
typedef EGLSurface (*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
#endif /* EGL_VERSION_1_2 */
/**
* The API dispatcher jumps through these functions
*/
struct _egl_api
{
Initialize_t Initialize;
Terminate_t Terminate;
GetConfigs_t GetConfigs;
ChooseConfig_t ChooseConfig;
GetConfigAttrib_t GetConfigAttrib;
CreateContext_t CreateContext;
DestroyContext_t DestroyContext;
MakeCurrent_t MakeCurrent;
QueryContext_t QueryContext;
CreateWindowSurface_t CreateWindowSurface;
CreatePixmapSurface_t CreatePixmapSurface;
CreatePbufferSurface_t CreatePbufferSurface;
DestroySurface_t DestroySurface;
QuerySurface_t QuerySurface;
SurfaceAttrib_t SurfaceAttrib;
BindTexImage_t BindTexImage;
ReleaseTexImage_t ReleaseTexImage;
SwapInterval_t SwapInterval;
SwapBuffers_t SwapBuffers;
CopyBuffers_t CopyBuffers;
QueryString_t QueryString;
WaitGL_t WaitGL;
WaitNative_t WaitNative;
/* EGL_MESA_screen extension */
ChooseModeMESA_t ChooseModeMESA;
GetModesMESA_t GetModesMESA;
GetModeAttribMESA_t GetModeAttribMESA;
CopyContextMESA_t CopyContextMESA;
GetScreensMESA_t GetScreensMESA;
CreateScreenSurfaceMESA_t CreateScreenSurfaceMESA;
ShowScreenSurfaceMESA_t ShowScreenSurfaceMESA;
ScreenPositionMESA_t ScreenPositionMESA;
QueryScreenMESA_t QueryScreenMESA;
QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA;
QueryScreenModeMESA_t QueryScreenModeMESA;
QueryModeStringMESA_t QueryModeStringMESA;
#ifdef EGL_VERSION_1_2
WaitClient_t WaitClient;
CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer;
#endif
};
#endif /* EGLAPI_INCLUDED */

View File

@@ -1,638 +0,0 @@
/**
* EGL Configuration (pixel format) functions.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "eglconfig.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "egllog.h"
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
/**
* Convert an _EGLConfig to a __GLcontextModes object.
* NOTE: This routine may be incomplete - we're only making sure that
* the fields needed by Mesa (for _mesa_create_context/framebuffer) are
* set correctly.
*/
void
_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode)
{
memset(mode, 0, sizeof(*mode));
mode->rgbMode = GL_TRUE; /* no color index */
mode->colorIndexMode = GL_FALSE;
mode->doubleBufferMode = GL_TRUE; /* always DB for now */
mode->stereoMode = GL_FALSE;
mode->redBits = GET_CONFIG_ATTRIB(config, EGL_RED_SIZE);
mode->greenBits = GET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE);
mode->blueBits = GET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE);
mode->alphaBits = GET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE);
mode->rgbBits = GET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE);
/* no rgba masks - fix? */
mode->depthBits = GET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE);
mode->haveDepthBuffer = mode->depthBits > 0;
mode->stencilBits = GET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE);
mode->haveStencilBuffer = mode->stencilBits > 0;
/* no accum */
mode->level = GET_CONFIG_ATTRIB(config, EGL_LEVEL);
mode->samples = GET_CONFIG_ATTRIB(config, EGL_SAMPLES);
mode->sampleBuffers = GET_CONFIG_ATTRIB(config, EGL_SAMPLE_BUFFERS);
/* surface type - not really needed */
mode->visualType = GLX_TRUE_COLOR;
mode->renderType = GLX_RGBA_BIT;
}
void
_eglSetConfigAttrib(_EGLConfig *config, EGLint attr, EGLint val)
{
assert(attr >= FIRST_ATTRIB);
assert(attr < FIRST_ATTRIB + MAX_ATTRIBS);
config->Attrib[attr - FIRST_ATTRIB] = val;
}
/**
* Init the given _EGLconfig to default values.
* \param id the configuration's ID.
*/
void
_eglInitConfig(_EGLConfig *config, EGLint id)
{
memset(config, 0, sizeof(*config));
config->Handle = id;
_eglSetConfigAttrib(config, EGL_CONFIG_ID, id);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_CONFIG_CAVEAT, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_NATIVE_RENDERABLE, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE,
EGL_SCREEN_BIT_MESA | EGL_PBUFFER_BIT |
EGL_PIXMAP_BIT | EGL_WINDOW_BIT);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_TYPE, EGL_NONE);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE);
#ifdef EGL_VERSION_1_2
_eglSetConfigAttrib(config, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
_eglSetConfigAttrib(config, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT);
#endif /* EGL_VERSION_1_2 */
}
/**
* Given an EGLConfig handle, return the corresponding _EGLConfig object.
*/
_EGLConfig *
_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
{
EGLint i;
_EGLDisplay *disp = _eglLookupDisplay(dpy);
for (i = 0; i < disp->NumConfigs; i++) {
if (disp->Configs[i].Handle == config) {
return disp->Configs + i;
}
}
return NULL;
}
/**
* Add the given _EGLConfig to the given display.
*/
_EGLConfig *
_eglAddConfig(_EGLDisplay *display, const _EGLConfig *config)
{
_EGLConfig *newConfigs;
EGLint n;
n = display->NumConfigs;
newConfigs = (_EGLConfig *) realloc(display->Configs,
(n + 1) * sizeof(_EGLConfig));
if (newConfigs) {
display->Configs = newConfigs;
display->Configs[n] = *config; /* copy struct */
display->Configs[n].Handle = n;
display->NumConfigs++;
return display->Configs + n;
}
else {
return NULL;
}
}
/**
* Parse the attrib_list to fill in the fields of the given _eglConfig
* Return EGL_FALSE if any errors, EGL_TRUE otherwise.
*/
EGLBoolean
_eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list)
{
EGLint i;
/* set all config attribs to EGL_DONT_CARE */
for (i = 0; i < MAX_ATTRIBS; i++) {
config->Attrib[i] = EGL_DONT_CARE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
const EGLint attr = attrib_list[i];
if (attr >= EGL_BUFFER_SIZE &&
attr <= EGL_MAX_SWAP_INTERVAL) {
EGLint k = attr - FIRST_ATTRIB;
assert(k >= 0);
assert(k < MAX_ATTRIBS);
config->Attrib[k] = attrib_list[++i];
}
#ifdef EGL_VERSION_1_2
else if (attr == EGL_COLOR_BUFFER_TYPE) {
EGLint bufType = attrib_list[++i];
if (bufType != EGL_RGB_BUFFER && bufType != EGL_LUMINANCE_BUFFER) {
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
return EGL_FALSE;
}
_eglSetConfigAttrib(config, EGL_COLOR_BUFFER_TYPE, bufType);
}
else if (attr == EGL_RENDERABLE_TYPE) {
EGLint renType = attrib_list[++i];
if (renType & ~(EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT)) {
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
return EGL_FALSE;
}
_eglSetConfigAttrib(config, EGL_RENDERABLE_TYPE, renType);
}
else if (attr == EGL_ALPHA_MASK_SIZE ||
attr == EGL_LUMINANCE_SIZE) {
EGLint value = attrib_list[++i];
_eglSetConfigAttrib(config, attr, value);
}
#endif /* EGL_VERSION_1_2 */
else {
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
return EGL_FALSE;
}
}
return EGL_TRUE;
}
#define EXACT 1
#define ATLEAST 2
#define MASK 3
#define SMALLER 4
#define SPECIAL 5
#define NONE 6
struct sort_info {
EGLint Attribute;
EGLint MatchCriteria;
EGLint SortOrder;
};
/* This encodes the info from Table 3.5 of the EGL spec, ordered by
* Sort Priority.
*
* XXX To do: EGL 1.2 attribs
*/
static struct sort_info SortInfo[] = {
{ EGL_CONFIG_CAVEAT, EXACT, SPECIAL },
{ EGL_RED_SIZE, ATLEAST, SPECIAL },
{ EGL_GREEN_SIZE, ATLEAST, SPECIAL },
{ EGL_BLUE_SIZE, ATLEAST, SPECIAL },
{ EGL_ALPHA_SIZE, ATLEAST, SPECIAL },
{ EGL_BUFFER_SIZE, ATLEAST, SMALLER },
{ EGL_SAMPLE_BUFFERS, ATLEAST, SMALLER },
{ EGL_SAMPLES, ATLEAST, SMALLER },
{ EGL_DEPTH_SIZE, ATLEAST, SMALLER },
{ EGL_STENCIL_SIZE, ATLEAST, SMALLER },
{ EGL_NATIVE_VISUAL_TYPE, EXACT, SPECIAL },
{ EGL_CONFIG_ID, EXACT, SMALLER },
{ EGL_BIND_TO_TEXTURE_RGB, EXACT, NONE },
{ EGL_BIND_TO_TEXTURE_RGBA, EXACT, NONE },
{ EGL_LEVEL, EXACT, NONE },
{ EGL_NATIVE_RENDERABLE, EXACT, NONE },
{ EGL_MAX_SWAP_INTERVAL, EXACT, NONE },
{ EGL_MIN_SWAP_INTERVAL, EXACT, NONE },
{ EGL_SURFACE_TYPE, MASK, NONE },
{ EGL_TRANSPARENT_TYPE, EXACT, NONE },
{ EGL_TRANSPARENT_RED_VALUE, EXACT, NONE },
{ EGL_TRANSPARENT_GREEN_VALUE, EXACT, NONE },
{ EGL_TRANSPARENT_BLUE_VALUE, EXACT, NONE },
{ 0, 0, 0 }
};
/**
* Return EGL_TRUE if the attributes of c meet or exceed the minimums
* specified by min.
*/
static EGLBoolean
_eglConfigQualifies(const _EGLConfig *c, const _EGLConfig *min)
{
EGLint i;
for (i = 0; SortInfo[i].Attribute != 0; i++) {
const EGLint mv = GET_CONFIG_ATTRIB(min, SortInfo[i].Attribute);
if (mv != EGL_DONT_CARE) {
const EGLint cv = GET_CONFIG_ATTRIB(c, SortInfo[i].Attribute);
if (SortInfo[i].MatchCriteria == EXACT) {
if (cv != mv) {
return EGL_FALSE;
}
}
else if (SortInfo[i].MatchCriteria == ATLEAST) {
if (cv < mv) {
return EGL_FALSE;
}
}
else {
assert(SortInfo[i].MatchCriteria == MASK);
if ((mv & cv) != mv) {
return EGL_FALSE;
}
}
}
}
return EGL_TRUE;
}
/**
* Compare configs 'a' and 'b' and return -1 if a belongs before b,
* 1 if a belongs after b, or 0 if they're equal.
* Used by qsort().
*/
static int
_eglCompareConfigs(const void *a, const void *b)
{
const _EGLConfig *aConfig = (const _EGLConfig *) a;
const _EGLConfig *bConfig = (const _EGLConfig *) b;
EGLint i;
for (i = 0; SortInfo[i].Attribute != 0; i++) {
const EGLint aVal = GET_CONFIG_ATTRIB(aConfig, SortInfo[i].Attribute);
const EGLint bVal = GET_CONFIG_ATTRIB(bConfig, SortInfo[i].Attribute);
if (SortInfo[i].SortOrder == SMALLER) {
if (aVal < bVal)
return -1;
else if (aVal > bVal)
return 1;
/* else, continue examining attribute values */
}
else if (SortInfo[i].SortOrder == SPECIAL) {
if (SortInfo[i].Attribute == EGL_CONFIG_CAVEAT) {
/* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */
if (aVal < bVal)
return -1;
else if (aVal > bVal)
return 1;
}
else if (SortInfo[i].Attribute == EGL_RED_SIZE ||
SortInfo[i].Attribute == EGL_GREEN_SIZE ||
SortInfo[i].Attribute == EGL_BLUE_SIZE ||
SortInfo[i].Attribute == EGL_ALPHA_SIZE) {
if (aVal > bVal)
return -1;
else if (aVal < bVal)
return 1;
}
else {
assert(SortInfo[i].Attribute == EGL_NATIVE_VISUAL_TYPE);
if (aVal < bVal)
return -1;
else if (aVal > bVal)
return 1;
}
}
else {
assert(SortInfo[i].SortOrder == NONE);
/* continue examining attribute values */
}
}
/* all attributes identical */
return 0;
}
/**
* Typical fallback routine for eglChooseConfig
*/
EGLBoolean
_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size, EGLint *num_configs)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLConfig **configList, criteria;
EGLint i, count;
/* parse the attrib_list to initialize criteria */
if (!_eglParseConfigAttribs(&criteria, attrib_list)) {
return EGL_FALSE;
}
/* allocate array of config pointers */
configList = (_EGLConfig **) malloc(config_size * sizeof(_EGLConfig *));
if (!configList) {
_eglError(EGL_BAD_CONFIG, "eglChooseConfig(out of memory)");
return EGL_FALSE;
}
/* make array of pointers to qualifying configs */
for (i = count = 0; i < disp->NumConfigs && count < config_size; i++) {
if (_eglConfigQualifies(disp->Configs + i, &criteria)) {
configList[count++] = disp->Configs + i;
}
}
/* sort array of pointers */
qsort(configList, count, sizeof(_EGLConfig *), _eglCompareConfigs);
/* copy config handles to output array */
for (i = 0; i < count; i++) {
configs[i] = configList[i]->Handle;
}
free(configList);
*num_configs = count;
return EGL_TRUE;
}
/**
* Fallback for eglGetConfigAttrib.
*/
EGLBoolean
_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
EGLint attribute, EGLint *value)
{
const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
const EGLint k = attribute - FIRST_ATTRIB;
if (k >= 0 && k < MAX_ATTRIBS) {
*value = conf->Attrib[k];
return EGL_TRUE;
}
else {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
return EGL_FALSE;
}
}
/**
* Fallback for eglGetConfigs.
*/
EGLBoolean
_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs,
EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
if (!drv->Initialized) {
_eglError(EGL_NOT_INITIALIZED, "eglGetConfigs");
return EGL_FALSE;
}
if (configs) {
EGLint i;
*num_config = MIN2(disp->NumConfigs, config_size);
for (i = 0; i < *num_config; i++) {
configs[i] = disp->Configs[i].Handle;
}
}
else {
/* just return total number of supported configs */
*num_config = disp->NumConfigs;
}
return EGL_TRUE;
}
/**
* Creates a set of \c __GLcontextModes that a driver will expose.
*
* A set of \c __GLcontextModes will be created based on the supplied
* parameters. The number of modes processed will be 2 *
* \c num_depth_stencil_bits * \c num_db_modes.
*
* For the most part, data is just copied from \c depth_bits, \c stencil_bits,
* \c db_modes, and \c visType into each \c __GLcontextModes element.
* However, the meanings of \c fb_format and \c fb_type require further
* explanation. The \c fb_format specifies which color components are in
* each pixel and what the default order is. For example, \c GL_RGB specifies
* that red, green, blue are available and red is in the "most significant"
* position and blue is in the "least significant". The \c fb_type specifies
* the bit sizes of each component and the actual ordering. For example, if
* \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
* are the blue value, bits [10:5] are the green value, and bits [4:0] are
* the red value.
*
* One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
* of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
* \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
* \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
* far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
* still uses 32-bits.
*
* If in doubt, look at the tables used in the function.
*
* \param ptr_to_modes Pointer to a pointer to a linked list of
* \c __GLcontextModes. Upon completion, a pointer to
* the next element to be process will be stored here.
* If the function fails and returns \c GL_FALSE, this
* value will be unmodified, but some elements in the
* linked list may be modified.
* \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
* \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
* \param fb_type Type of the pixels in the framebuffer. Currently only
* \c GL_UNSIGNED_SHORT_5_6_5,
* \c GL_UNSIGNED_SHORT_5_6_5_REV,
* \c GL_UNSIGNED_INT_8_8_8_8, and
* \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
* \param depth_bits Array of depth buffer sizes to be exposed.
* \param stencil_bits Array of stencil buffer sizes to be exposed.
* \param num_depth_stencil_bits Number of entries in both \c depth_bits and
* \c stencil_bits.
* \param db_modes Array of buffer swap modes. If an element has a
* value of \c GLX_NONE, then it represents a
* single-buffered mode. Other valid values are
* \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
* \c GLX_SWAP_UNDEFINED_OML. See the
* GLX_OML_swap_method extension spec for more details.
* \param num_db_modes Number of entries in \c db_modes.
* \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
* \c GLX_DIRECT_COLOR.
*
* \returns
* \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
* cause of failure is a bad parameter (i.e., unsupported \c fb_format or
* \c fb_type).
*
* \todo
* There is currently no way to support packed RGB modes (i.e., modes with
* exactly 3 bytes per pixel) or floating-point modes. This could probably
* be done by creating some new, private enums with clever names likes
* \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
* \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
*/
GLboolean
_eglFillInConfigs(_EGLConfig * configs,
GLenum fb_format, GLenum fb_type,
const uint8_t * depth_bits, const uint8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
int visType)
{
static const uint8_t bits_table[3][4] = {
/* R G B A */
{ 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
{ 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
{ 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
};
/* The following arrays are all indexed by the fb_type masked with 0x07.
* Given the four supported fb_type values, this results in valid array
* indices of 3, 4, 5, and 7.
*/
static const uint32_t masks_table_rgb[8][4] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
{0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
{0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
};
static const uint32_t masks_table_rgba[8][4] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
{0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
{0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
};
static const uint32_t masks_table_bgr[8][4] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
{0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
{0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
};
static const uint32_t masks_table_bgra[8][4] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
{0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
{0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
};
static const uint8_t bytes_per_pixel[8] = {
0, 0, 0, 2, 2, 4, 0, 4
};
const uint8_t * bits;
const uint32_t * masks;
const int index = fb_type & 0x07;
_EGLConfig *config;
unsigned i;
unsigned j;
unsigned k;
if ( bytes_per_pixel[index] == 0 ) {
_eglLog(_EGL_INFO,
"[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.",
__FUNCTION__, __LINE__, fb_type);
return GL_FALSE;
}
/* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
* the _REV versions.
*
* Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
*/
switch ( fb_format ) {
case GL_RGB:
bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
masks = masks_table_rgb[index];
break;
case GL_RGBA:
bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
masks = masks_table_rgba[index];
break;
case GL_BGR:
bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
masks = masks_table_bgr[index];
break;
case GL_BGRA:
bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
masks = masks_table_bgra[index];
break;
default:
_eglLog(_EGL_WARNING,
"[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.",
__FUNCTION__, __LINE__, fb_format);
return GL_FALSE;
}
config = configs;
for (k = 0; k < num_depth_stencil_bits; k++) {
for (i = 0; i < num_db_modes; i++) {
for (j = 0; j < 2; j++) {
_eglSetConfigAttrib(config, EGL_RED_SIZE, bits[0]);
_eglSetConfigAttrib(config, EGL_GREEN_SIZE, bits[1]);
_eglSetConfigAttrib(config, EGL_BLUE_SIZE, bits[2]);
_eglSetConfigAttrib(config, EGL_ALPHA_SIZE, bits[3]);
_eglSetConfigAttrib(config, EGL_BUFFER_SIZE,
bits[0] + bits[1] + bits[2] + bits[3]);
_eglSetConfigAttrib(config, EGL_STENCIL_SIZE, stencil_bits[k]);
_eglSetConfigAttrib(config, EGL_DEPTH_SIZE, depth_bits[i]);
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_SCREEN_BIT_MESA |
EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT);
config++;
}
}
}
return GL_TRUE;
}

View File

@@ -1,67 +0,0 @@
#ifndef EGLCONFIG_INCLUDED
#define EGLCONFIG_INCLUDED
#include "egltypedefs.h"
#include "GL/internal/glcore.h"
#define MAX_ATTRIBS 100
#define FIRST_ATTRIB EGL_BUFFER_SIZE
struct _egl_config
{
EGLConfig Handle; /* the public/opaque handle which names this config */
EGLint Attrib[MAX_ATTRIBS];
};
#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL)
#define GET_CONFIG_ATTRIB(CONF, ATTR) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB])
extern void
_eglInitConfig(_EGLConfig *config, EGLint id);
extern _EGLConfig *
_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config);
extern _EGLConfig *
_eglAddConfig(_EGLDisplay *display, const _EGLConfig *config);
extern EGLBoolean
_eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list);
extern EGLBoolean
_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern EGLBoolean
_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
extern EGLBoolean
_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern void
_eglSetConfigAttrib(_EGLConfig *config, EGLint attr, EGLint val);
extern GLboolean
_eglFillInConfigs( _EGLConfig *configs,
GLenum fb_format, GLenum fb_type,
const uint8_t * depth_bits, const uint8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
int visType );
extern void
_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode);
#endif /* EGLCONFIG_INCLUDED */

View File

@@ -1,276 +0,0 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglhash.h"
#include "eglsurface.h"
/**
* Initialize the given _EGLContext object to defaults.
*/
EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
EGLConfig config, const EGLint *attrib_list)
{
_EGLConfig *conf;
_EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_FALSE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
return EGL_NO_CONTEXT;
}
}
memset(ctx, 0, sizeof(_EGLContext));
ctx->Display = display;
ctx->Config = conf;
ctx->DrawSurface = EGL_NO_SURFACE;
ctx->ReadSurface = EGL_NO_SURFACE;
return EGL_TRUE;
}
/*
* Assign an EGLContext handle to the _EGLContext object then put it into
* the hash table.
*/
void
_eglSaveContext(_EGLContext *ctx)
{
assert(ctx);
ctx->Handle = _eglHashGenKey(_eglGlobal.Contexts);
_eglHashInsert(_eglGlobal.Contexts, ctx->Handle, ctx);
}
/**
* Remove the given _EGLContext object from the hash table.
*/
void
_eglRemoveContext(_EGLContext *ctx)
{
_eglHashRemove(_eglGlobal.Contexts, ctx->Handle);
}
/**
* Return the _EGLContext object that corresponds to the given
* EGLContext handle.
*/
_EGLContext *
_eglLookupContext(EGLContext ctx)
{
_EGLContext *c = (_EGLContext *) _eglHashLookup(_eglGlobal.Contexts, ctx);
return c;
}
/**
* Return the currently bound _EGLContext object, or NULL.
*/
_EGLContext *
_eglGetCurrentContext(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
return t->CurrentContext;
}
/**
* Just a placeholder/demo function. Real driver will never use this!
*/
EGLContext
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
EGLContext share_list, const EGLint *attrib_list)
{
#if 0 /* example code */
_EGLContext *context;
context = (_EGLContext *) calloc(1, sizeof(_EGLContext));
if (!context)
return EGL_NO_CONTEXT;
if (!_eglInitContext(drv, dpy, context, config, attrib_list)) {
free(context);
return EGL_NO_CONTEXT;
}
_eglSaveContext(context);
return context->Handle;
#endif
return EGL_NO_CONTEXT;
}
/**
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
{
_EGLContext *context = _eglLookupContext(ctx);
if (context) {
_eglHashRemove(_eglGlobal.Contexts, ctx);
if (context->IsBound) {
context->DeletePending = EGL_TRUE;
}
else {
free(context);
}
return EGL_TRUE;
}
else {
_eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
return EGL_TRUE;
}
}
EGLBoolean
_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value)
{
_EGLContext *c = _eglLookupContext(ctx);
(void) drv;
(void) dpy;
if (!c) {
_eglError(EGL_BAD_CONTEXT, "eglQueryContext");
return EGL_FALSE;
}
switch (attribute) {
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
return EGL_TRUE;
#ifdef EGL_VERSION_1_2
case EGL_CONTEXT_CLIENT_TYPE:
*value = c->ClientAPI;
return EGL_FALSE;
#endif /* EGL_VERSION_1_2 */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
return EGL_FALSE;
}
}
/**
* Drivers will typically call this to do the error checking and
* update the various IsBound and DeletePending flags.
* Then, the driver will do its device-dependent Make-Current stuff.
*/
EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
EGLSurface r, EGLContext context)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
_EGLContext *ctx = _eglLookupContext(context);
_EGLSurface *draw = _eglLookupSurface(d);
_EGLSurface *read = _eglLookupSurface(r);
_EGLContext *oldContext = _eglGetCurrentContext();
_EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW);
_EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ);
/* error checking */
if (ctx) {
if (draw == NULL || read == NULL) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
if (draw->Config != ctx->Config) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
if (read->Config != ctx->Config) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
}
/*
* check if the old context or surfaces need to be deleted
*/
if (oldDrawSurface != NULL) {
oldDrawSurface->IsBound = EGL_FALSE;
if (oldDrawSurface->DeletePending) {
/* make sure we don't try to rebind a deleted surface */
if (draw == oldDrawSurface || draw == oldReadSurface) {
draw = NULL;
}
/* really delete surface now */
drv->API.DestroySurface(drv, dpy, oldDrawSurface->Handle);
}
}
if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
oldReadSurface->IsBound = EGL_FALSE;
if (oldReadSurface->DeletePending) {
/* make sure we don't try to rebind a deleted surface */
if (read == oldDrawSurface || read == oldReadSurface) {
read = NULL;
}
/* really delete surface now */
drv->API.DestroySurface(drv, dpy, oldReadSurface->Handle);
}
}
if (oldContext != NULL) {
oldContext->IsBound = EGL_FALSE;
if (oldContext->DeletePending) {
/* make sure we don't try to rebind a deleted context */
if (ctx == oldContext) {
ctx = NULL;
}
/* really delete context now */
drv->API.DestroyContext(drv, dpy, oldContext->Handle);
}
}
if (ctx) {
/* check read/draw again, in case we deleted them above */
if (draw == NULL || read == NULL) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
ctx->DrawSurface = draw;
ctx->ReadSurface = read;
ctx->IsBound = EGL_TRUE;
draw->IsBound = EGL_TRUE;
read->IsBound = EGL_TRUE;
}
t->CurrentContext = ctx;
return EGL_TRUE;
}
/**
* This is defined by the EGL_MESA_copy_context extension.
*/
EGLBoolean
_eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source,
EGLContext dest, EGLint mask)
{
/* This function will always have to be overridden/implemented in the
* device driver. If the driver is based on Mesa, use _mesa_copy_context().
*/
return EGL_FALSE;
}

View File

@@ -1,71 +0,0 @@
#ifndef EGLCONTEXT_INCLUDED
#define EGLCONTEXT_INCLUDED
#include "egltypedefs.h"
/**
* "Base" class for device driver contexts.
*/
struct _egl_context
{
EGLContext Handle; /* The public/opaque handle which names this object */
_EGLDisplay *Display; /* who do I belong to? */
_EGLConfig *Config;
_EGLSurface *DrawSurface;
_EGLSurface *ReadSurface;
EGLBoolean IsBound;
EGLBoolean DeletePending;
#ifdef EGL_VERSION_1_2
EGLint ClientAPI; /* Either EGL_OPENGL_ES_API or EGL_OPENVG_API */
#endif /* EGL_VERSION_1_2 */
};
extern EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
EGLConfig config, const EGLint *attrib_list);
extern void
_eglSaveContext(_EGLContext *ctx);
extern void
_eglRemoveContext(_EGLContext *ctx);
extern _EGLContext *
_eglLookupContext(EGLContext ctx);
extern _EGLContext *
_eglGetCurrentContext(void);
extern EGLContext
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
extern EGLBoolean
_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
extern EGLBoolean
_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
extern EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
extern EGLBoolean
_eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
#endif /* EGLCONTEXT_INCLUDED */

View File

@@ -1,71 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
#include "egldisplay.h"
#include "eglglobals.h"
#include "eglhash.h"
static char *
my_strdup(const char *s)
{
int l = strlen(s);
char *s2 = malloc(l + 1);
strcpy(s2, s);
return s2;
}
/**
* We're assuming that the NativeDisplayType parameter is actually
* a string.
* Return a new _EGLDisplay object for the given displayName
*/
_EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName)
{
_EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
if (dpy) {
dpy->Handle = _eglHashGenKey(_eglGlobal.Displays);
_eglHashInsert(_eglGlobal.Displays, dpy->Handle, dpy);
if (displayName)
dpy->Name = my_strdup(displayName);
else
dpy->Name = NULL;
dpy->Driver = NULL; /* this gets set later */
}
return dpy;
}
/**
* Return the _EGLDisplay object that corresponds to the given public/
* opaque display handle.
*/
_EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy)
{
_EGLDisplay *d = (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, dpy);
return d;
}
_EGLDisplay *
_eglGetCurrentDisplay(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx)
return ctx->Display;
else
return NULL;
}
void
_eglCleanupDisplay(_EGLDisplay *disp)
{
/* XXX incomplete */
free(disp->Configs);
free(disp->Name);
/* driver deletes _EGLDisplay */
}

View File

@@ -1,44 +0,0 @@
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
#include "egltypedefs.h"
struct _egl_display
{
EGLDisplay Handle;
char *Name;
_EGLDriver *Driver;
EGLint NumScreens;
_EGLScreen **Screens; /* array [NumScreens] */
EGLint NumConfigs;
_EGLConfig *Configs; /* array [NumConfigs] */
};
extern _EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName);
extern _EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy);
extern _EGLDisplay *
_eglGetCurrentDisplay(void);
extern void
_eglCleanupDisplay(_EGLDisplay *disp);
extern EGLBoolean
_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attrib, EGLint *value);
#endif /* EGLDISPLAY_INCLUDED */

View File

@@ -1,272 +0,0 @@
#include <assert.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "egllog.h"
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
const char *DefaultDriverName = "demodriver";
/**
* Choose and open/init the hardware driver for the given EGLDisplay.
* Previously, the EGLDisplay was created with _eglNewDisplay() where
* we recorded the user's NativeDisplayType parameter.
*
* Now we'll use the NativeDisplayType value.
*
* Currently, the native display value is treated as a string.
* If the first character is ':' we interpret it as a screen or card index
* number (i.e. ":0" or ":1", etc)
* Else if the first character is '!' we interpret it as specific driver name
* (i.e. "!r200" or "!i830".
*/
_EGLDriver *
_eglChooseDriver(EGLDisplay display)
{
_EGLDisplay *dpy = _eglLookupDisplay(display);
_EGLDriver *drv;
const char *driverName = DefaultDriverName;
const char *name;
assert(dpy);
name = dpy->Name;
if (!name) {
/* use default */
}
else if (name[0] == ':' && (name[1] >= '0' && name[1] <= '9') && !name[2]) {
/* XXX probe hardware here to determine which driver to open */
driverName = "libEGLdri";
}
else if (name[0] == '!') {
/* use specified driver name */
driverName = name + 1;
}
else {
/* Maybe display was returned by XOpenDisplay? */
_eglLog(_EGL_FATAL, "eglChooseDriver() bad name");
}
_eglLog(_EGL_INFO, "eglChooseDriver() choosing %s", driverName);
drv = _eglOpenDriver(dpy, driverName);
dpy->Driver = drv;
return drv;
}
/**
* Open/load the named driver and call its bootstrap function: _eglMain().
* \return new _EGLDriver object.
*/
_EGLDriver *
_eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
{
_EGLDriver *drv;
_EGLMain_t mainFunc;
void *lib;
char driverFilename[1000];
/* XXX also prepend a directory path??? */
sprintf(driverFilename, "%s.so", driverName);
_eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
lib = dlopen(driverFilename, RTLD_NOW);
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open %s (%s)",
driverFilename, dlerror());
return NULL;
}
mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
if (!mainFunc) {
_eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
dlclose(lib);
return NULL;
}
drv = mainFunc(dpy);
if (!drv) {
dlclose(lib);
return NULL;
}
/* with a recurvise open you want the inner most handle */
if (!drv->LibHandle)
drv->LibHandle = lib;
else
dlclose(lib);
drv->Display = dpy;
return drv;
}
EGLBoolean
_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
{
void *handle = drv->LibHandle;
EGLBoolean b;
_eglLog(_EGL_INFO, "Closing driver");
/*
* XXX check for currently bound context/surfaces and delete them?
*/
b = drv->API.Terminate(drv, dpy);
dlclose(handle);
return b;
}
/**
* Given a display handle, return the _EGLDriver for that display.
*/
_EGLDriver *
_eglLookupDriver(EGLDisplay dpy)
{
_EGLDisplay *d = _eglLookupDisplay(dpy);
if (d)
return d->Driver;
else
return NULL;
}
/**
* Plug all the available fallback routines into the given driver's
* dispatch table.
*/
void
_eglInitDriverFallbacks(_EGLDriver *drv)
{
/* If a pointer is set to NULL, then the device driver _really_ has
* to implement it.
*/
drv->API.Initialize = NULL;
drv->API.Terminate = NULL;
drv->API.GetConfigs = _eglGetConfigs;
drv->API.ChooseConfig = _eglChooseConfig;
drv->API.GetConfigAttrib = _eglGetConfigAttrib;
drv->API.CreateContext = _eglCreateContext;
drv->API.DestroyContext = _eglDestroyContext;
drv->API.MakeCurrent = _eglMakeCurrent;
drv->API.QueryContext = _eglQueryContext;
drv->API.CreateWindowSurface = _eglCreateWindowSurface;
drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
drv->API.DestroySurface = _eglDestroySurface;
drv->API.QuerySurface = _eglQuerySurface;
drv->API.SurfaceAttrib = _eglSurfaceAttrib;
drv->API.BindTexImage = _eglBindTexImage;
drv->API.ReleaseTexImage = _eglReleaseTexImage;
drv->API.SwapInterval = _eglSwapInterval;
drv->API.SwapBuffers = _eglSwapBuffers;
drv->API.CopyBuffers = _eglCopyBuffers;
drv->API.QueryString = _eglQueryString;
drv->API.WaitGL = _eglWaitGL;
drv->API.WaitNative = _eglWaitNative;
#ifdef EGL_MESA_screen_surface
drv->API.ChooseModeMESA = _eglChooseModeMESA;
drv->API.GetModesMESA = _eglGetModesMESA;
drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
drv->API.GetScreensMESA = _eglGetScreensMESA;
drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
drv->API.QueryScreenMESA = _eglQueryScreenMESA;
drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
#endif /* EGL_MESA_screen_surface */
#ifdef EGL_VERSION_1_2
drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
#endif /* EGL_VERSION_1_2 */
}
/**
* Examine the individual extension enable/disable flags and recompute
* the driver's Extensions string.
*/
static void
_eglUpdateExtensionsString(_EGLDriver *drv)
{
drv->Extensions.String[0] = 0;
if (drv->Extensions.MESA_screen_surface)
strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
if (drv->Extensions.MESA_copy_context)
strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
assert(strlen(drv->Extensions.String) < MAX_EXTENSIONS_LEN);
}
const char *
_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
{
(void) drv;
(void) dpy;
switch (name) {
case EGL_VENDOR:
return "Mesa Project";
case EGL_VERSION:
return "1.0";
case EGL_EXTENSIONS:
_eglUpdateExtensionsString(drv);
return drv->Extensions.String;
#ifdef EGL_VERSION_1_2
case EGL_CLIENT_APIS:
/* XXX need to initialize somewhere */
return drv->ClientAPIs;
#endif
default:
_eglError(EGL_BAD_PARAMETER, "eglQueryString");
return NULL;
}
}
EGLBoolean
_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
{
/* just a placeholder */
(void) drv;
(void) dpy;
return EGL_TRUE;
}
EGLBoolean
_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
{
/* just a placeholder */
(void) drv;
(void) dpy;
switch (engine) {
case EGL_CORE_NATIVE_ENGINE:
break;
default:
_eglError(EGL_BAD_PARAMETER, "eglWaitNative(engine)");
return EGL_FALSE;
}
return EGL_TRUE;
}

View File

@@ -1,81 +0,0 @@
#ifndef EGLDRIVER_INCLUDED
#define EGLDRIVER_INCLUDED
#include "egltypedefs.h"
#include "eglapi.h"
/* should probably use a dynamic-length string, but this will do */
#define MAX_EXTENSIONS_LEN 1000
/**
* Optional EGL extensions info.
*/
struct _egl_extensions
{
EGLBoolean MESA_screen_surface;
EGLBoolean MESA_copy_context;
char String[MAX_EXTENSIONS_LEN];
};
/**
* Base class for device drivers.
*/
struct _egl_driver
{
EGLBoolean Initialized; /* set by driver after initialized */
void *LibHandle; /* dlopen handle */
_EGLDisplay *Display;
int ABIversion;
int APImajor, APIminor; /* returned through eglInitialize */
const char *ClientAPIs;
_EGLAPI API;
_EGLExtensions Extensions;
};
extern _EGLDriver *_eglMain(_EGLDisplay *dpy);
extern _EGLDriver *
_eglChooseDriver(EGLDisplay dpy);
extern _EGLDriver *
_eglOpenDriver(_EGLDisplay *dpy, const char *driverName);
extern EGLBoolean
_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy);
extern _EGLDriver *
_eglLookupDriver(EGLDisplay d);
extern void
_eglInitDriverFallbacks(_EGLDriver *drv);
extern const char *
_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
extern EGLBoolean
_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
extern EGLBoolean
_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
#endif /* EGLDRIVER_INCLUDED */

View File

@@ -1,148 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "eglglobals.h"
struct _egl_global _eglGlobal = { .Initialized = EGL_FALSE };
/**
* Init the fields in the _eglGlobal struct
* May be safely called more than once.
*/
void
_eglInitGlobals(void)
{
if (!_eglGlobal.Initialized) {
_eglGlobal.Displays = _eglNewHashTable();
_eglGlobal.Contexts = _eglNewHashTable();
_eglGlobal.Surfaces = _eglNewHashTable();
_eglGlobal.FreeScreenHandle = 1;
_eglGlobal.Initialized = EGL_TRUE;
_eglGlobal.OpenGLESAPISupported = EGL_TRUE;
_eglGlobal.OpenVGAPISupported = EGL_FALSE;
/* XXX temporary */
_eglGlobal.ThreadInfo = _eglNewThreadInfo();
}
}
/**
* Should call this via an atexit handler.
*/
void
_eglDestroyGlobals(void)
{
/* XXX TODO walk over table entries, deleting each */
_eglDeleteHashTable(_eglGlobal.Displays);
_eglDeleteHashTable(_eglGlobal.Contexts);
_eglDeleteHashTable(_eglGlobal.Surfaces);
}
/**
* Allocate and init a new _EGLThreadInfo object.
*/
_EGLThreadInfo *
_eglNewThreadInfo(void)
{
_EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo));
if (t) {
t->CurrentContext = EGL_NO_CONTEXT;
t->LastError = EGL_SUCCESS;
t->CurrentAPI = EGL_NONE;
}
return t;
}
/**
* Delete/free a _EGLThreadInfo object.
*/
void
_eglDeleteThreadData(_EGLThreadInfo *t)
{
free(t);
}
/**
* Return pointer to calling thread's _EGLThreadInfo object.
* Create a new one if needed.
* Should never return NULL.
*/
_EGLThreadInfo *
_eglGetCurrentThread(void)
{
_eglInitGlobals();
/* XXX temporary */
return _eglGlobal.ThreadInfo;
}
/**
* Record EGL error code.
*/
void
_eglError(EGLint errCode, const char *msg)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
const char *s;
if (t->LastError == EGL_SUCCESS) {
t->LastError = errCode;
switch (errCode) {
case EGL_BAD_ACCESS:
s = "EGL_BAD_ACCESS";
break;
case EGL_BAD_ALLOC:
s = "EGL_BAD_ALLOC";
break;
case EGL_BAD_ATTRIBUTE:
s = "EGL_BAD_ATTRIBUTE";
break;
case EGL_BAD_CONFIG:
s = "EGL_BAD_CONFIG";
break;
case EGL_BAD_CONTEXT:
s = "EGL_BAD_CONTEXT";
break;
case EGL_BAD_CURRENT_SURFACE:
s = "EGL_BAD_CURRENT_SURFACE";
break;
case EGL_BAD_DISPLAY:
s = "EGL_BAD_DISPLAY";
break;
case EGL_BAD_MATCH:
s = "EGL_BAD_MATCH";
break;
case EGL_BAD_NATIVE_PIXMAP:
s = "EGL_BAD_NATIVE_PIXMAP";
break;
case EGL_BAD_NATIVE_WINDOW:
s = "EGL_BAD_NATIVE_WINDOW";
break;
case EGL_BAD_PARAMETER:
s = "EGL_BAD_PARAMETER";
break;
case EGL_BAD_SURFACE:
s = "EGL_BAD_SURFACE";
break;
case EGL_BAD_SCREEN_MESA:
s = "EGL_BAD_SCREEN_MESA";
break;
case EGL_BAD_MODE_MESA:
s = "EGL_BAD_MODE_MESA";
break;
default:
s = "other";
}
/* XXX temporary */
fprintf(stderr, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
}
}

View File

@@ -1,68 +0,0 @@
#ifndef EGLGLOBALS_INCLUDED
#define EGLGLOBALS_INCLUDED
#include "egltypedefs.h"
#include "eglhash.h"
/**
* Per-thread info
*/
struct _egl_thread_info
{
EGLint LastError;
_EGLContext *CurrentContext;
EGLenum CurrentAPI;
};
/**
* Global library data
*/
struct _egl_global
{
EGLBoolean Initialized;
_EGLHashtable *Displays;
_EGLHashtable *Contexts;
_EGLHashtable *Surfaces;
EGLScreenMESA FreeScreenHandle;
/* XXX these may be temporary */
EGLBoolean OpenGLESAPISupported;
EGLBoolean OpenVGAPISupported;
/* XXX temporary - should be thread-specific data (TSD) */
_EGLThreadInfo *ThreadInfo;
};
extern struct _egl_global _eglGlobal;
extern void
_eglInitGlobals(void);
extern void
_eglDestroyGlobals(void);
extern _EGLThreadInfo *
_eglNewThreadInfo(void);
extern void
_eglDeleteThreadData(_EGLThreadInfo *t);
extern _EGLThreadInfo *
_eglGetCurrentThread(void);
extern void
_eglError(EGLint errCode, const char *msg);
#endif /* EGLGLOBALS_INCLUDED */

View File

@@ -1,347 +0,0 @@
/**
* \file hash.c
* Generic hash table.
*
* This code taken from Mesa and adapted.
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "eglhash.h"
#define TABLE_SIZE 1023 /**< Size of lookup table/array */
#define HASH_FUNC(K) ((K) % TABLE_SIZE)
/*
* Unfinished mutex stuff
*/
typedef int _EGLMutex;
static void
_eglInitMutex(_EGLMutex m)
{
}
static void
_eglDestroyMutex(_EGLMutex m)
{
}
static void
_eglLockMutex(_EGLMutex m)
{
}
static void
_eglUnlockMutex(_EGLMutex m)
{
}
typedef struct _egl_hashentry _EGLHashentry;
struct _egl_hashentry
{
EGLuint Key; /**< the entry's key */
void *Data; /**< the entry's data */
_EGLHashentry *Next; /**< pointer to next entry */
};
struct _egl_hashtable
{
_EGLHashentry *Table[TABLE_SIZE]; /**< the lookup table */
EGLuint MaxKey; /**< highest key inserted so far */
_EGLMutex Mutex; /**< mutual exclusion lock */
};
/**
* Create a new hash table.
*
* \return pointer to a new, empty hash table.
*/
_EGLHashtable *
_eglNewHashTable(void)
{
_EGLHashtable *table = (_EGLHashtable *) calloc(1, sizeof(_EGLHashtable));
if (table) {
_eglInitMutex(table->Mutex);
table->MaxKey = 1;
}
return table;
}
/**
* Delete a hash table.
* Frees each entry on the hash table and then the hash table structure itself.
* Note that the caller should have already traversed the table and deleted
* the objects in the table (i.e. We don't free the entries' data pointer).
*
* \param table the hash table to delete.
*/
void
_eglDeleteHashTable(_EGLHashtable *table)
{
EGLuint i;
assert(table);
for (i = 0; i < TABLE_SIZE; i++) {
_EGLHashentry *entry = table->Table[i];
while (entry) {
_EGLHashentry *next = entry->Next;
free(entry);
entry = next;
}
}
_eglDestroyMutex(table->Mutex);
free(table);
}
/**
* Lookup an entry in the hash table.
*
* \param table the hash table.
* \param key the key.
*
* \return pointer to user's data or NULL if key not in table
*/
void *
_eglHashLookup(const _EGLHashtable *table, EGLuint key)
{
EGLuint pos;
const _EGLHashentry *entry;
assert(table);
if (!key)
return NULL;
pos = HASH_FUNC(key);
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
return entry->Data;
}
entry = entry->Next;
}
return NULL;
}
/**
* Insert a key/pointer pair into the hash table.
* If an entry with this key already exists we'll replace the existing entry.
*
* \param table the hash table.
* \param key the key (not zero).
* \param data pointer to user data.
*/
void
_eglHashInsert(_EGLHashtable *table, EGLuint key, void *data)
{
/* search for existing entry with this key */
EGLuint pos;
_EGLHashentry *entry;
assert(table);
assert(key);
_eglLockMutex(table->Mutex);
if (key > table->MaxKey)
table->MaxKey = key;
pos = HASH_FUNC(key);
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
/* replace entry's data */
entry->Data = data;
_eglUnlockMutex(table->Mutex);
return;
}
entry = entry->Next;
}
/* alloc and insert new table entry */
entry = (_EGLHashentry *) malloc(sizeof(_EGLHashentry));
entry->Key = key;
entry->Data = data;
entry->Next = table->Table[pos];
table->Table[pos] = entry;
_eglUnlockMutex(table->Mutex);
}
/**
* Remove an entry from the hash table.
*
* \param table the hash table.
* \param key key of entry to remove.
*
* While holding the hash table's lock, searches the entry with the matching
* key and unlinks it.
*/
void
_eglHashRemove(_EGLHashtable *table, EGLuint key)
{
EGLuint pos;
_EGLHashentry *entry, *prev;
assert(table);
assert(key);
_eglLockMutex(table->Mutex);
pos = HASH_FUNC(key);
prev = NULL;
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
/* found it! */
if (prev) {
prev->Next = entry->Next;
}
else {
table->Table[pos] = entry->Next;
}
free(entry);
_eglUnlockMutex(table->Mutex);
return;
}
prev = entry;
entry = entry->Next;
}
_eglUnlockMutex(table->Mutex);
}
/**
* Get the key of the "first" entry in the hash table.
*
* This is used in the course of deleting all display lists when
* a context is destroyed.
*
* \param table the hash table
*
* \return key for the "first" entry in the hash table.
*
* While holding the lock, walks through all table positions until finding
* the first entry of the first non-empty one.
*/
EGLuint
_eglHashFirstEntry(_EGLHashtable *table)
{
EGLuint pos;
assert(table);
_eglLockMutex(table->Mutex);
for (pos = 0; pos < TABLE_SIZE; pos++) {
if (table->Table[pos]) {
_eglUnlockMutex(table->Mutex);
return table->Table[pos]->Key;
}
}
_eglUnlockMutex(table->Mutex);
return 0;
}
/**
* Given a hash table key, return the next key. This is used to walk
* over all entries in the table. Note that the keys returned during
* walking won't be in any particular order.
* \return next hash key or 0 if end of table.
*/
EGLuint
_eglHashNextEntry(const _EGLHashtable *table, EGLuint key)
{
const _EGLHashentry *entry;
EGLuint pos;
assert(table);
assert(key);
/* Find the entry with given key */
pos = HASH_FUNC(key);
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
break;
}
entry = entry->Next;
}
if (!entry) {
/* the key was not found, we can't find next entry */
return 0;
}
if (entry->Next) {
/* return next in linked list */
return entry->Next->Key;
}
else {
/* look for next non-empty table slot */
pos++;
while (pos < TABLE_SIZE) {
if (table->Table[pos]) {
return table->Table[pos]->Key;
}
pos++;
}
return 0;
}
}
/**
* Dump contents of hash table for debugging.
*
* \param table the hash table.
*/
void
_eglHashPrint(const _EGLHashtable *table)
{
EGLuint i;
assert(table);
for (i = 0; i < TABLE_SIZE; i++) {
const _EGLHashentry *entry = table->Table[i];
while (entry) {
printf("%u %p\n", entry->Key, entry->Data);
entry = entry->Next;
}
}
}
/**
* Return a new, unused hash key.
*/
EGLuint
_eglHashGenKey(_EGLHashtable *table)
{
EGLuint k;
_eglLockMutex(table->Mutex);
k = table->MaxKey;
table->MaxKey++;
_eglUnlockMutex(table->Mutex);
return k;
}

View File

@@ -1,39 +0,0 @@
/**
* \file eglhash.h
* Generic hash table.
*/
#ifndef EGLHASH_INCLUDED
#define EGLHASH_INCLUDED
/* XXX move this? */
typedef unsigned int EGLuint;
typedef struct _egl_hashtable _EGLHashtable;
extern _EGLHashtable *_eglNewHashTable(void);
extern void _eglDeleteHashTable(_EGLHashtable *table);
extern void *_eglHashLookup(const _EGLHashtable *table, EGLuint key);
extern void _eglHashInsert(_EGLHashtable *table, EGLuint key, void *data);
extern void _eglHashRemove(_EGLHashtable *table, EGLuint key);
extern EGLuint _eglHashFirstEntry(_EGLHashtable *table);
extern EGLuint _eglHashNextEntry(const _EGLHashtable *table, EGLuint key);
extern void _eglHashPrint(const _EGLHashtable *table);
extern EGLuint _eglHashGenKey(_EGLHashtable *table);
extern void _egltest_hash_functions(void);
#endif /* EGLHASH_INCLUDED */

View File

@@ -1,94 +0,0 @@
/**
* Logging facility for debug/info messages.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "egllog.h"
#define MAXSTRING 1000
#define FALLBACK_LOG_LEVEL _EGL_DEBUG
#define FALLBACK_LOG_LEVEL_STR "debug"
static EGLint ReportingLevel = -1;
static void
log_level_initialize (void)
{
char *log_env = getenv ("EGL_LOG_LEVEL");
if (log_env == NULL) {
ReportingLevel = FALLBACK_LOG_LEVEL;
}
else if (strcasecmp (log_env, "fatal") == 0) {
ReportingLevel = _EGL_FATAL;
}
else if (strcasecmp (log_env, "warning") == 0) {
ReportingLevel = _EGL_WARNING;
}
else if (strcasecmp (log_env, "info") == 0) {
ReportingLevel = _EGL_INFO;
}
else if (strcasecmp (log_env, "debug") == 0) {
ReportingLevel = _EGL_DEBUG;
}
else {
fprintf (stderr, "Unrecognized EGL_LOG_LEVEL environment variable value. "
"Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
"Got \"%s\". Falling back to \"%s\".\n",
log_env, FALLBACK_LOG_LEVEL_STR);
ReportingLevel = FALLBACK_LOG_LEVEL;
}
}
/**
* Log a message to stderr.
* \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
*/
void
_eglLog(EGLint level, const char *fmtStr, ...)
{
va_list args;
char msg[MAXSTRING];
const char *levelStr;
static int log_level_initialized = 0;
if (!log_level_initialized) {
log_level_initialize ();
log_level_initialized = 1;
}
if (level <= ReportingLevel) {
switch (level) {
case _EGL_FATAL:
levelStr = "Fatal";
break;
case _EGL_WARNING:
levelStr = "Warning";
break;
case _EGL_INFO:
levelStr = "Info";
break;
case _EGL_DEBUG:
levelStr = "Debug";
break;
default:
levelStr = "";
}
va_start(args, fmtStr);
vsnprintf(msg, MAXSTRING, fmtStr, args);
va_end(args);
fprintf(stderr, "EGL %s: %s\n", levelStr, msg);
if (level == _EGL_FATAL) {
exit(1); /* or abort()? */
}
}
}

View File

@@ -1,16 +0,0 @@
#ifndef EGLLOG_INCLUDED
#define EGLLOG_INCLUDED
#include "egltypedefs.h"
#define _EGL_FATAL 0 /* unrecoverable error */
#define _EGL_WARNING 1 /* recoverable error/problem */
#define _EGL_INFO 2 /* just useful info */
#define _EGL_DEBUG 3 /* useful info for debugging */
extern void
_eglLog(EGLint level, const char *fmtStr, ...);
#endif /* EGLLOG_INCLUDED */

View File

@@ -1,431 +0,0 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "egldisplay.h"
#include "egldriver.h"
#include "eglmode.h"
#include "eglglobals.h"
#include "eglscreen.h"
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
static char *
my_strdup(const char *s)
{
if (s) {
int l = strlen(s);
char *s2 = malloc(l + 1);
if (s2)
strcpy(s2, s);
return s2;
}
else {
return NULL;
}
}
/**
* Given an EGLModeMESA handle, return the corresponding _EGLMode object
* or null if non-existant.
*/
_EGLMode *
_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode)
{
const _EGLDisplay *disp = _eglLookupDisplay(dpy);
EGLint scrnum;
/* loop over all screens on the display */
for (scrnum = 0; scrnum < disp->NumScreens; scrnum++) {
const _EGLScreen *scrn = disp->Screens[scrnum];
EGLint i;
/* search list of modes for handle */
for (i = 0; i < scrn->NumModes; i++) {
if (scrn->Modes[i].Handle == mode) {
return scrn->Modes + i;
}
}
}
return NULL;
}
/**
* Add a new mode with the given attributes (width, height, depth, refreshRate)
* to the given screen.
* Assign a new mode ID/handle to the mode as well.
* \return pointer to the new _EGLMode
*/
_EGLMode *
_eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
EGLint refreshRate, const char *name)
{
EGLint n;
_EGLMode *newModes;
assert(screen);
assert(width > 0);
assert(height > 0);
assert(refreshRate > 0);
n = screen->NumModes;
newModes = (_EGLMode *) realloc(screen->Modes, (n+1) * sizeof(_EGLMode));
if (newModes) {
screen->Modes = newModes;
screen->Modes[n].Handle = n + 1;
screen->Modes[n].Width = width;
screen->Modes[n].Height = height;
screen->Modes[n].RefreshRate = refreshRate;
screen->Modes[n].Optimal = EGL_FALSE;
screen->Modes[n].Interlaced = EGL_FALSE;
screen->Modes[n].Name = my_strdup(name);
screen->NumModes++;
return screen->Modes + n;
}
else {
return NULL;
}
}
/**
* Parse the attrib_list to fill in the fields of the given _eglMode
* Return EGL_FALSE if any errors, EGL_TRUE otherwise.
*/
static EGLBoolean
_eglParseModeAttribs(_EGLMode *mode, const EGLint *attrib_list)
{
EGLint i;
/* init all attribs to EGL_DONT_CARE */
mode->Handle = EGL_DONT_CARE;
mode->Width = EGL_DONT_CARE;
mode->Height = EGL_DONT_CARE;
mode->RefreshRate = EGL_DONT_CARE;
mode->Optimal = EGL_DONT_CARE;
mode->Interlaced = EGL_DONT_CARE;
mode->Name = NULL;
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_MODE_ID_MESA:
mode->Handle = attrib_list[++i];
if (mode->Handle <= 0) {
_eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(handle)");
return EGL_FALSE;
}
break;
case EGL_WIDTH:
mode->Width = attrib_list[++i];
if (mode->Width <= 0) {
_eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(width)");
return EGL_FALSE;
}
break;
case EGL_HEIGHT:
mode->Height = attrib_list[++i];
if (mode->Height <= 0) {
_eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(height)");
return EGL_FALSE;
}
break;
case EGL_REFRESH_RATE_MESA:
mode->RefreshRate = attrib_list[++i];
if (mode->RefreshRate <= 0) {
_eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(refresh rate)");
return EGL_FALSE;
}
break;
case EGL_INTERLACED_MESA:
mode->Interlaced = attrib_list[++i];
if (mode->Interlaced != EGL_TRUE && mode->Interlaced != EGL_FALSE) {
_eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(interlaced)");
return EGL_FALSE;
}
break;
case EGL_OPTIMAL_MESA:
mode->Optimal = attrib_list[++i];
if (mode->Optimal != EGL_TRUE && mode->Optimal != EGL_FALSE) {
_eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(optimal)");
return EGL_FALSE;
}
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseModeMESA");
return EGL_FALSE;
}
}
return EGL_TRUE;
}
/**
* Determine if the candidate mode's attributes are at least as good
* as the minimal mode's.
* \return EGL_TRUE if qualifies, EGL_FALSE otherwise
*/
static EGLBoolean
_eglModeQualifies(const _EGLMode *c, const _EGLMode *min)
{
if (min->Handle != EGL_DONT_CARE && c->Handle != min->Handle)
return EGL_FALSE;
if (min->Width != EGL_DONT_CARE && c->Width < min->Width)
return EGL_FALSE;
if (min->Height != EGL_DONT_CARE && c->Height < min->Height)
return EGL_FALSE;
if (min->RefreshRate != EGL_DONT_CARE && c->RefreshRate < min->RefreshRate)
return EGL_FALSE;
if (min->Optimal != EGL_DONT_CARE && c->Optimal != min->Optimal)
return EGL_FALSE;
if (min->Interlaced != EGL_DONT_CARE && c->Interlaced != min->Interlaced)
return EGL_FALSE;
return EGL_TRUE;
}
/**
* Return value of given mode attribute, or -1 if bad attrib.
*/
static EGLint
getModeAttrib(const _EGLMode *m, EGLint attrib)
{
switch (attrib) {
case EGL_MODE_ID_MESA:
return m->Handle;
case EGL_WIDTH:
return m->Width;
case EGL_HEIGHT:
return m->Height;
case EGL_REFRESH_RATE_MESA:
return m->RefreshRate;
case EGL_OPTIMAL_MESA:
return m->Optimal;
case EGL_INTERLACED_MESA:
return m->Interlaced;
default:
return -1;
}
}
#define SMALLER 1
#define LARGER 2
struct sort_info {
EGLint Attrib;
EGLint Order; /* SMALLER or LARGER */
};
/* the order of these entries is the priority */
static struct sort_info SortInfo[] = {
{ EGL_OPTIMAL_MESA, LARGER },
{ EGL_INTERLACED_MESA, SMALLER },
{ EGL_WIDTH, LARGER },
{ EGL_HEIGHT, LARGER },
{ EGL_REFRESH_RATE_MESA, LARGER },
{ EGL_MODE_ID_MESA, SMALLER },
{ 0, 0 }
};
/**
* Compare modes 'a' and 'b' and return -1 if a belongs before b, or 1 if a
* belongs after b, or 0 if they're equal.
* Used by qsort().
*/
static int
_eglCompareModes(const void *a, const void *b)
{
const _EGLMode *aMode = *((const _EGLMode **) a);
const _EGLMode *bMode = *((const _EGLMode **) b);
EGLint i;
for (i = 0; SortInfo[i].Attrib; i++) {
const EGLint aVal = getModeAttrib(aMode, SortInfo[i].Attrib);
const EGLint bVal = getModeAttrib(bMode, SortInfo[i].Attrib);
if (aVal == bVal) {
/* a tie */
continue;
}
else if (SortInfo[i].Order == SMALLER) {
return (aVal < bVal) ? -1 : 1;
}
else if (SortInfo[i].Order == LARGER) {
return (aVal > bVal) ? -1 : 1;
}
}
/* all attributes identical */
return 0;
}
/**
* Search for EGLModes which match the given attribute list.
* Called via eglChooseModeMESA API function.
*/
EGLBoolean
_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
_EGLMode **modeList, min;
EGLint i, count;
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglChooseModeMESA");
return EGL_FALSE;
}
if (!_eglParseModeAttribs(&min, attrib_list)) {
/* error code will have been recorded */
return EGL_FALSE;
}
/* allocate array of mode pointers */
modeList = (_EGLMode **) malloc(modes_size * sizeof(_EGLMode *));
if (!modeList) {
_eglError(EGL_BAD_MODE_MESA, "eglChooseModeMESA(out of memory)");
return EGL_FALSE;
}
/* make array of pointers to qualifying modes */
for (i = count = 0; i < scrn->NumModes && count < modes_size; i++) {
if (_eglModeQualifies(scrn->Modes + i, &min)) {
modeList[count++] = scrn->Modes + i;
}
}
/* sort array of pointers */
qsort(modeList, count, sizeof(_EGLMode *), _eglCompareModes);
/* copy mode handles to output array */
for (i = 0; i < count; i++) {
modes[i] = modeList[i]->Handle;
}
free(modeList);
*num_modes = count;
return EGL_TRUE;
}
/**
* Return all possible modes for the given screen. No sorting of results.
* Called via eglGetModesMESA() API function.
*/
EGLBoolean
_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglGetModesMESA");
return EGL_FALSE;
}
if (modes) {
EGLint i;
*num_modes = MIN2(scrn->NumModes, modes_size);
for (i = 0; i < *num_modes; i++) {
modes[i] = scrn->Modes[i].Handle;
}
}
else {
/* just return total number of supported modes */
*num_modes = scrn->NumModes;
}
return EGL_TRUE;
}
/**
* Query an attribute of a mode.
*/
EGLBoolean
_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLModeMESA mode, EGLint attribute, EGLint *value)
{
_EGLMode *m = _eglLookupMode(dpy, mode);
EGLint v;
if (!m) {
_eglError(EGL_BAD_MODE_MESA, "eglGetModeAttribMESA");
return EGL_FALSE;
}
v = getModeAttrib(m, attribute);
if (v < 0) {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA");
return EGL_FALSE;
}
*value = v;
return EGL_TRUE;
}
/**
* Return human-readable string for given mode.
* This is the default function called by eglQueryModeStringMESA().
*/
const char *
_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode)
{
_EGLMode *m = _eglLookupMode(dpy, mode);
if (!m) {
_eglError(EGL_BAD_MODE_MESA, "eglQueryModeStringMESA");
return NULL;
}
return m->Name;
}
#if 0
static int
_eglRand(int max)
{
return rand() % max;
}
void
_eglTestModeModule(void)
{
EGLint count = 30;
_EGLMode *modes = (_EGLMode *) malloc(count * sizeof(_EGLMode));
_EGLMode **modeList = (_EGLMode **) malloc(count * sizeof(_EGLMode*));
EGLint i;
for (i = 0; i < count; i++) {
modes[i].Handle = _eglRand(20);
modes[i].Width = 512 + 256 * _eglRand(2);
modes[i].Height = 512 + 256 * _eglRand(2);
modes[i].RefreshRate = 50 + 5 * _eglRand(3);
modes[i].Interlaced = _eglRand(2);
modes[i].Optimal = _eglRand(4) == 0;
modeList[i] = modes + i;
}
/* sort array of pointers */
qsort(modeList, count, sizeof(_EGLMode *), compareModes);
for (i = 0; i < count; i++) {
_EGLMode *m = modeList[i];
printf("%2d: %3d %4d x %4d @ %3d opt %d int %d\n", i,
m->Handle, m->Width, m->Height, m->RefreshRate,
m->Optimal, m->Interlaced);
}
}
#endif

View File

@@ -1,54 +0,0 @@
#ifndef EGLMODE_INCLUDED
#define EGLMODE_INCLUDED
#include "egltypedefs.h"
/**
* Data structure which corresponds to an EGLModeMESA.
*/
struct _egl_mode
{
EGLModeMESA Handle; /* the public/opaque handle which names this mode */
EGLint Width, Height; /* size in pixels */
EGLint RefreshRate; /* rate * 1000.0 */
EGLint Optimal;
EGLint Interlaced;
const char *Name;
/* Other possible attributes */
/* interlaced */
/* external sync */
};
extern _EGLMode *
_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode);
extern _EGLMode *
_eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
EGLint refreshRate, const char *name);
extern EGLBoolean
_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode,
EGLint attribute, EGLint *value);
extern const char *
_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
#endif /* EGLMODE_INCLUDED */

View File

@@ -1,328 +0,0 @@
/*
* Ideas for screen management extension to EGL.
*
* Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
* The screens' handles can be obtained with eglGetScreensMESA().
*
* A new kind of EGLSurface is possible- one which can be directly scanned
* out on a screen. Such a surface is created with eglCreateScreenSurface().
*
* To actually display a screen surface on a screen, the eglShowSurface()
* function is called.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "egldisplay.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglconfig.h"
#include "eglsurface.h"
#include "eglscreen.h"
/**
* Return a new screen handle/ID.
* NOTE: we never reuse these!
*/
EGLScreenMESA
_eglAllocScreenHandle(void)
{
EGLScreenMESA s = _eglGlobal.FreeScreenHandle;
_eglGlobal.FreeScreenHandle++;
return s;
}
/**
* Initialize an _EGLScreen object to default values.
*/
void
_eglInitScreen(_EGLScreen *screen)
{
memset(screen, 0, sizeof(_EGLScreen));
screen->StepX = 1;
screen->StepY = 1;
}
/**
* Given a public screen handle, return the internal _EGLScreen object.
*/
_EGLScreen *
_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen)
{
EGLint i;
_EGLDisplay *display = _eglLookupDisplay(dpy);
if (!display)
return NULL;
for (i = 0; i < display->NumScreens; i++) {
if (display->Screens[i]->Handle == screen)
return display->Screens[i];
}
return NULL;
}
/**
* Add the given _EGLScreen to the display's list of screens.
*/
void
_eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
{
EGLint n;
assert(display);
assert(screen);
screen->Handle = _eglAllocScreenHandle();
n = display->NumScreens;
display->Screens = realloc(display->Screens, (n+1) * sizeof(_EGLScreen *));
display->Screens[n] = screen;
display->NumScreens++;
}
EGLBoolean
_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
EGLint max_screens, EGLint *num_screens)
{
_EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint n;
if (!display) {
_eglError(EGL_BAD_DISPLAY, "eglGetScreensMESA");
return EGL_FALSE;
}
if (display->NumScreens > max_screens) {
n = max_screens;
}
else {
n = display->NumScreens;
}
if (screens) {
EGLint i;
for (i = 0; i < n; i++)
screens[i] = display->Screens[i]->Handle;
}
if (num_screens)
*num_screens = n;
return EGL_TRUE;
}
/**
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA,
config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
/**
* Show the given surface on the named screen.
* If surface is EGL_NO_SURFACE, disable the screen's output.
*
* This is just a placeholder function; drivers will always override
* this with code that _really_ shows the surface.
*/
EGLBoolean
_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLScreenMESA screen, EGLSurface surface,
EGLModeMESA m)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen);
_EGLMode *mode = _eglLookupMode(dpy, m);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA");
return EGL_FALSE;
}
if (!mode && (m != EGL_NO_MODE_MESA )) {
_eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA");
return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE) {
scrn->CurrentSurface = NULL;
}
else {
_EGLSurface *surf = _eglLookupSurface(surface);
if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) {
_eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
return EGL_FALSE;
}
if (surf->Width < mode->Width || surf->Height < mode->Height) {
_eglError(EGL_BAD_SURFACE,
"eglShowSurfaceMESA(surface smaller than screen size)");
return EGL_FALSE;
}
scrn->CurrentSurface = surf;
scrn->CurrentMode = mode;
}
return EGL_TRUE;
}
/**
* Set a screen's current display mode.
* Note: mode = EGL_NO_MODE is valid (turns off the screen)
*
* This is just a placeholder function; drivers will always override
* this with code that _really_ sets the mode.
*/
EGLBoolean
_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA mode)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA");
return EGL_FALSE;
}
scrn->CurrentMode = _eglLookupMode(dpy, mode);
return EGL_TRUE;
}
/**
* Set a screen's surface origin.
*/
EGLBoolean
_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLScreenMESA screen, EGLint x, EGLint y)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA");
return EGL_FALSE;
}
scrn->OriginX = x;
scrn->OriginY = y;
return EGL_TRUE;
}
/**
* Query a screen's current surface.
*/
EGLBoolean
_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLScreenMESA screen, EGLSurface *surface)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
if (scrn->CurrentSurface)
*surface = scrn->CurrentSurface->Handle;
else
*surface = EGL_NO_SURFACE;
return EGL_TRUE;
}
/**
* Query a screen's current mode.
*/
EGLBoolean
_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
EGLModeMESA *mode)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
if (scrn->CurrentMode)
*mode = scrn->CurrentMode->Handle;
else
*mode = EGL_NO_MODE_MESA;
return EGL_TRUE;
}
EGLBoolean
_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
EGLint attribute, EGLint *value)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA");
return EGL_FALSE;
}
switch (attribute) {
case EGL_SCREEN_POSITION_MESA:
value[0] = scrn->OriginX;
value[1] = scrn->OriginY;
break;
case EGL_SCREEN_POSITION_GRANULARITY_MESA:
value[0] = scrn->StepX;
value[1] = scrn->StepY;
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
return EGL_FALSE;
}
return EGL_TRUE;
}
/**
* Delete the modes associated with given screen.
*/
void
_eglDestroyScreenModes(_EGLScreen *scrn)
{
EGLint i;
for (i = 0; i < scrn->NumModes; i++) {
if (scrn->Modes[i].Name)
free((char *) scrn->Modes[i].Name); /* cast away const */
}
if (scrn->Modes)
free(scrn->Modes);
scrn->Modes = NULL;
scrn->NumModes = 0;
}
/**
* Default fallback routine - drivers should usually override this.
*/
void
_eglDestroyScreen(_EGLScreen *scrn)
{
_eglDestroyScreenModes(scrn);
free(scrn);
}

View File

@@ -1,90 +0,0 @@
#ifndef EGLSCREEN_INCLUDED
#define EGLSCREEN_INCLUDED
/**
* Per-screen information.
* Note that an EGL screen doesn't have a size. A screen may be set to
* one of several display modes (width/height/scanrate). The screen
* then displays a drawing surface. The drawing surface must be at least
* as large as the display mode's resolution. If it's larger, the
* OriginX and OriginY fields control what part of the surface is visible
* on the screen.
*/
struct _egl_screen
{
EGLScreenMESA Handle; /* The public/opaque handle which names this object */
_EGLMode *CurrentMode;
_EGLSurface *CurrentSurface;
EGLint OriginX, OriginY; /**< Origin of scan-out region w.r.t. surface */
EGLint StepX, StepY; /**< Screen position/origin granularity */
EGLint NumModes;
_EGLMode *Modes; /**< array [NumModes] */
};
extern EGLScreenMESA
_eglAllocScreenHandle(void);
extern void
_eglInitScreen(_EGLScreen *screen);
extern _EGLScreen *
_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen);
extern void
_eglAddScreen(_EGLDisplay *display, _EGLScreen *screen);
extern EGLBoolean
_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
extern EGLSurface
_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
extern EGLBoolean
_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
extern EGLBoolean
_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA mode);
extern EGLBoolean
_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
extern EGLBoolean
_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attribute, EGLint *value);
extern EGLBoolean
_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLScreenMESA screen, EGLSurface *surface);
extern EGLBoolean
_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
extern EGLBoolean
_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
extern void
_eglDestroyScreenModes(_EGLScreen *scrn);
extern void
_eglDestroyScreen(_EGLScreen *scrn);
#endif /* EGLSCREEN_INCLUDED */

View File

@@ -1,530 +0,0 @@
/**
* Surface-related functions.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
#include "eglconfig.h"
#include "eglglobals.h"
#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
/**
* Do error check on parameters and initialize the given _EGLSurface object.
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
*/
EGLBoolean
_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
_EGLSurface *surf, EGLint type, EGLConfig config,
const EGLint *attrib_list)
{
const char *func;
_EGLConfig *conf;
EGLint width = 0, height = 0, largest = 0;
EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
EGLint renderBuffer = EGL_BACK_BUFFER;
#ifdef EGL_VERSION_1_2
EGLint colorspace = EGL_COLORSPACE_sRGB;
EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE;
#endif
EGLint i;
switch (type) {
case EGL_WINDOW_BIT:
func = "eglCreateWindowSurface";
break;
case EGL_PIXMAP_BIT:
func = "eglCreatePixmapSurface";
renderBuffer = EGL_SINGLE_BUFFER;
break;
case EGL_PBUFFER_BIT:
func = "eglCreatePBufferSurface";
break;
case EGL_SCREEN_BIT_MESA:
func = "eglCreateScreenSurface";
renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
break;
default:
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
return EGL_FALSE;
}
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, func);
return EGL_FALSE;
}
/*
* Parse attribute list. Different kinds of surfaces support different
* attributes.
*/
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
width = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_HEIGHT:
if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
height = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_LARGEST_PBUFFER:
if (type == EGL_PBUFFER_BIT) {
largest = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_TEXTURE_FORMAT:
if (type == EGL_PBUFFER_BIT) {
texFormat = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_TEXTURE_TARGET:
if (type == EGL_PBUFFER_BIT) {
texTarget = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_MIPMAP_TEXTURE:
if (type == EGL_PBUFFER_BIT) {
mipmapTex = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
#ifdef EGL_VERSION_1_2
case EGL_RENDER_BUFFER:
if (type == EGL_WINDOW_BIT) {
renderBuffer = attrib_list[++i];
if (renderBuffer != EGL_BACK_BUFFER &&
renderBuffer != EGL_SINGLE_BUFFER) {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_COLORSPACE:
if (type == EGL_WINDOW_BIT ||
type == EGL_PBUFFER_BIT ||
type == EGL_PIXMAP_BIT) {
colorspace = attrib_list[++i];
if (colorspace != EGL_COLORSPACE_sRGB &&
colorspace != EGL_COLORSPACE_LINEAR) {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_ALPHA_FORMAT:
if (type == EGL_WINDOW_BIT ||
type == EGL_PBUFFER_BIT ||
type == EGL_PIXMAP_BIT) {
alphaFormat = attrib_list[++i];
if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE &&
alphaFormat != EGL_ALPHA_FORMAT_PRE) {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
#endif /* EGL_VERSION_1_2 */
default:
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
}
if (width <= 0 || height <= 0) {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
memset(surf, 0, sizeof(_EGLSurface));
surf->Config = conf;
surf->Type = type;
surf->Width = width;
surf->Height = height;
surf->TextureFormat = texFormat;
surf->TextureTarget = texTarget;
surf->MipmapTexture = mipmapTex;
surf->MipmapLevel = 0;
surf->SwapInterval = 0;
#ifdef EGL_VERSION_1_2
surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */
surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */
surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */
surf->AspectRatio = EGL_UNKNOWN; /* set by caller */
surf->RenderBuffer = renderBuffer;
surf->AlphaFormat = alphaFormat;
surf->Colorspace = colorspace;
#endif
return EGL_TRUE;
}
void
_eglSaveSurface(_EGLSurface *surf)
{
assert(surf);
assert(!surf->Handle);
surf->Handle = _eglHashGenKey(_eglGlobal.Contexts);
assert(surf->Handle);
_eglHashInsert(_eglGlobal.Surfaces, surf->Handle, surf);
}
void
_eglRemoveSurface(_EGLSurface *surf)
{
_eglHashRemove(_eglGlobal.Surfaces, surf->Handle);
}
_EGLSurface *
_eglLookupSurface(EGLSurface surf)
{
_EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, surf);
return c;
}
_EGLSurface *
_eglGetCurrentSurface(EGLint readdraw)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx) {
switch (readdraw) {
case EGL_DRAW:
return ctx->DrawSurface;
case EGL_READ:
return ctx->ReadSurface;
default:
return NULL;
}
}
return NULL;
}
EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
/* Basically just do error checking here. Drivers have to do the
* actual buffer swap.
*/
_EGLContext *context = _eglGetCurrentContext();
_EGLSurface *surface = _eglLookupSurface(draw);
if (context && context->DrawSurface != surface) {
_eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
return EGL_FALSE;
}
if (surface == NULL) {
_eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
return EGL_FALSE;
}
return EGL_TRUE;
}
EGLBoolean
_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
NativePixmapType target)
{
/* copy surface to native pixmap */
/* All implementation burdon for this is in the device driver */
return EGL_FALSE;
}
EGLBoolean
_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLint attribute, EGLint *value)
{
_EGLSurface *surface = _eglLookupSurface(surf);
if (surface == NULL) {
_eglError(EGL_BAD_SURFACE, "eglQuerySurface");
return EGL_FALSE;
}
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
return EGL_TRUE;
case EGL_HEIGHT:
*value = surface->Height;
return EGL_TRUE;
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
return EGL_TRUE;
/*XXX case EGL_LARGEST_PBUFFER:*/
case EGL_SURFACE_TYPE:
*value = surface->Type;
return EGL_TRUE;
#ifdef EGL_VERSION_1_1
case EGL_TEXTURE_FORMAT:
/* texture attributes: only for pbuffers, no error otherwise */
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureFormat;
return EGL_TRUE;
case EGL_TEXTURE_TARGET:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureTarget;
return EGL_TRUE;
case EGL_MIPMAP_TEXTURE:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapTexture;
return EGL_TRUE;
case EGL_MIPMAP_LEVEL:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapLevel;
return EGL_TRUE;
#endif /* EGL_VERSION_1_1 */
#ifdef EGL_VERSION_1_2
case EGL_SWAP_BEHAVIOR:
*value = surface->SwapBehavior;
return EGL_TRUE;
case EGL_RENDER_BUFFER:
*value = surface->RenderBuffer;
return EGL_TRUE;
case EGL_PIXEL_ASPECT_RATIO:
*value = surface->AspectRatio;
return EGL_TRUE;
case EGL_HORIZONTAL_RESOLUTION:
*value = surface->HorizontalResolution;
return EGL_TRUE;
case EGL_VERTICAL_RESOLUTION:
*value = surface->VerticalResolution;
return EGL_TRUE;
case EGL_ALPHA_FORMAT:
*value = surface->AlphaFormat;
return EGL_TRUE;
case EGL_COLORSPACE:
*value = surface->Colorspace;
return EGL_TRUE;
#endif /* EGL_VERSION_1_2 */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
return EGL_FALSE;
}
}
/**
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
NativeWindowType window, const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
/**
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
NativePixmapType pixmap, const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
/**
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
/**
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
_EGLSurface *surf = _eglLookupSurface(surface);
if (surf) {
_eglHashRemove(_eglGlobal.Surfaces, surface);
if (surf->IsBound) {
surf->DeletePending = EGL_TRUE;
}
else {
free(surf);
}
return EGL_TRUE;
}
else {
_eglError(EGL_BAD_SURFACE, "eglDestroySurface");
return EGL_FALSE;
}
}
/**
* Default fallback routine - drivers might override this.
*/
EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attribute, EGLint value)
{
_EGLSurface *surface = _eglLookupSurface(surf);
if (surface == NULL) {
_eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
return EGL_FALSE;
}
switch (attribute) {
case EGL_MIPMAP_LEVEL:
surface->MipmapLevel = value;
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
return EGL_FALSE;
}
return EGL_TRUE;
}
EGLBoolean
_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
/* XXX unfinished */
return EGL_FALSE;
}
EGLBoolean
_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
/* XXX unfinished */
return EGL_FALSE;
}
EGLBoolean
_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
{
_EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
if (surf == NULL) {
_eglError(EGL_BAD_SURFACE, "eglSwapInterval");
return EGL_FALSE;
}
surf->SwapInterval = interval;
return EGL_TRUE;
}
#ifdef EGL_VERSION_1_2
/**
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
EGLenum buftype, EGLClientBuffer buffer,
EGLConfig config, const EGLint *attrib_list)
{
if (buftype != EGL_OPENVG_IMAGE) {
_eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
return EGL_NO_SURFACE;
}
return EGL_NO_SURFACE;
}
#endif /* EGL_VERSION_1_2 */

View File

@@ -1,117 +0,0 @@
#ifndef EGLSURFACE_INCLUDED
#define EGLSURFACE_INCLUDED
#include "egltypedefs.h"
/**
* "Base" class for device driver surfaces.
*/
struct _egl_surface
{
EGLSurface Handle; /* The public/opaque handle which names this object */
_EGLConfig *Config;
/* May need reference counting here */
EGLBoolean IsBound;
EGLBoolean DeletePending;
EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */
EGLint Width, Height;
EGLint TextureFormat, TextureTarget;
EGLint MipmapTexture, MipmapLevel;
EGLint SwapInterval;
/* If type == EGL_SCREEN_BIT: */
EGLint VisibleRefCount; /* number of screens I'm displayed on */
#ifdef EGL_VERSION_1_2
EGLint SwapBehavior; /* one of EGL_BUFFER_PRESERVED/DESTROYED */
EGLint HorizontalResolution, VerticalResolution;
EGLint AspectRatio;
EGLint RenderBuffer; /* EGL_BACK_BUFFER or EGL_SINGLE_BUFFER */
EGLint AlphaFormat; /* EGL_ALPHA_FORMAT_NONPRE or EGL_ALPHA_FORMAT_PRE */
EGLint Colorspace; /* EGL_COLORSPACE_sRGB or EGL_COLORSPACE_LINEAR */
#endif /* EGL_VERSION_1_2 */
};
extern EGLBoolean
_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
_EGLSurface *surf, EGLint type, EGLConfig config,
const EGLint *attrib_list);
extern void
_eglSaveSurface(_EGLSurface *surf);
extern void
_eglRemoveSurface(_EGLSurface *surf);
extern _EGLSurface *
_eglLookupSurface(EGLSurface surf);
extern _EGLSurface *
_eglGetCurrentSurface(EGLint readdraw);
extern EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
extern EGLBoolean
_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
extern EGLBoolean
_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
extern EGLSurface
_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
extern EGLSurface
_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
extern EGLSurface
_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
extern EGLBoolean
_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
extern EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
extern EGLBoolean
_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
extern EGLBoolean
_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
extern EGLBoolean
_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
#ifdef EGL_VERSION_1_2
extern EGLSurface
_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
EGLenum buftype, EGLClientBuffer buffer,
EGLConfig config, const EGLint *attrib_list);
#endif /* EGL_VERSION_1_2 */
#endif /* EGLSURFACE_INCLUDED */

View File

@@ -1,34 +0,0 @@
#ifndef EGLTYPEDEFS_INCLUDED
#define EGLTYPEDEFS_INCLUDED
#include <GLES/egl.h>
typedef struct _egl_api _EGLAPI;
typedef struct _egl_config _EGLConfig;
typedef struct _egl_context _EGLContext;
typedef struct _egl_display _EGLDisplay;
typedef struct _egl_driver _EGLDriver;
typedef struct _egl_extensions _EGLExtensions;
typedef struct _egl_mode _EGLMode;
typedef struct _egl_screen _EGLScreen;
typedef struct _egl_surface _EGLSurface;
typedef struct _egl_thread_info _EGLThreadInfo;
typedef void (*_EGLProc)();
typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy);
#endif /* EGLTYPEDEFS_INCLUDED */

View File

@@ -1,56 +0,0 @@
# src/glu/mesa/Makefile
TOP = ../../..
include $(TOP)/configs/current
GLU_MAJOR = 1
GLU_MINOR = 1
GLU_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
C_SOURCES = \
glu.c \
mipmap.c \
nurbs.c \
nurbscrv.c \
nurbssrf.c \
nurbsutl.c \
polytest.c \
project.c \
quadric.c \
tess.c \
tesselat.c
OBJECTS = $(C_SOURCES:.c=.o)
INCLUDES = -I. -I$(TOP)/include
##### RULES #####
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
##### TARGETS #####
default:
@if [ "${CONFIG_NAME}" = "beos" ] ; then \
echo "$(GLU_LIB_NAME) not build under BeOS, but integrated into ${GL_LIB_NAME}." ; \
exit 0 ; \
else \
$(MAKE) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) || exit 1 ; \
fi
$(TOP)/$(LIB_DIR):
-mkdir $(TOP)/$(LIB_DIR)
# Make the library:
$(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME): $(OBJECTS)
@ $(MKLIB) -o $(GLU_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major $(GLU_MAJOR) -minor $(GLU_MINOR) -patch $(GLU_TINY) \
$(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \
$(GLU_LIB_DEPS) $(OBJECTS)
clean:
-rm -f *.o */*.o */*/*.o
-rm -f *.lo */*.lo */*/*.lo
-rm -f *.la */*.la */*/*.la

View File

@@ -1,100 +0,0 @@
# Mesa 3-D graphics library
# Version: 4.0
#
# Copyright (C) 1999 Brian Paul All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# DOS/DJGPP glu makefile v1.5 for Mesa
#
# Copyright (C) 2002 - Daniel Borca
# Email : dborca@users.sourceforge.net
# Web : http://www.geocities.com/dborca
#
# Available options:
#
# Environment variables:
# CFLAGS
#
# Targets:
# all: build GLU
# clean: remove object files
#
.PHONY: all clean
TOP = ../../..
LIBDIR = $(TOP)/lib
GLU_LIB = libglu.a
GLU_DXE = glu.dxe
GLU_IMP = libiglu.a
export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH);$(LIBDIR);$(GLIDE)/lib
CC = gcc
CFLAGS += -I$(TOP)/include
AR = ar
ARFLAGS = crus
HAVEDXE3 = $(wildcard $(DJDIR)/bin/dxe3gen.exe)
ifeq ($(wildcard $(addsuffix /rm.exe,$(subst ;, ,$(PATH)))),)
UNLINK = del $(subst /,\,$(1))
else
UNLINK = $(RM) $(1)
endif
CORE_SOURCES = \
glu.c \
mipmap.c \
nurbs.c \
nurbscrv.c \
nurbssrf.c \
nurbsutl.c \
polytest.c \
project.c \
quadric.c \
tess.c \
tesselat.c
SOURCES = $(CORE_SOURCES)
OBJECTS = $(SOURCES:.c=.o)
.c.o:
$(CC) -o $@ $(CFLAGS) -c $<
all: $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLU_DXE) $(LIBDIR)/$(GLU_IMP)
$(LIBDIR)/$(GLU_LIB): $(OBJECTS)
$(AR) $(ARFLAGS) $@ $^
$(LIBDIR)/$(GLU_DXE) $(LIBDIR)/$(GLU_IMP): $(OBJECTS)
ifeq ($(HAVEDXE3),)
$(warning Missing DXE3 package... Skipping $(GLU_DXE))
else
-dxe3gen -o $(LIBDIR)/$(GLU_DXE) -Y $(LIBDIR)/$(GLU_IMP) -D "MesaGLU DJGPP" -E _glu -P gl.dxe -U $^
endif
clean:
-$(call UNLINK,*.o)

View File

@@ -1,63 +0,0 @@
# Makefile for GLU for GCC-2.95.2/Mingw32 contributed by
# Paul Garceau <pgarceau@teleport.com>
# Mesa 3-D graphics library
# Version: 3.3
# Copyright (C) 1995-1999 Brian Paul
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
MESA_MAJOR=3
MESA_MINOR=3
MESA_TINY=0
VERSION=$(MESA_MAJOR).$(MESA_MINOR)
CFLAGS = -I. -DWIN32 -D__WIN32__ -D_WINDOWS \
-O2 -funroll-loops \
-fexpensive-optimizations -fomit-frame-pointer -ffast-math \
-malign-loops=2 -malign-jumps=2 -malign-functions=2 \
-mwindows
CC = gcc
MAKELIB = ar ru
GLU_LIB = libGLU.a
##### MACROS #####
VPATH = RCS
INCDIR = ../include
LIBDIR = ../lib
SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
polytest.c project.c quadric.c tess.c tesselat.c
OBJECTS = $(SOURCES:.c=.o)
##### RULES #####
.c.o:
$(CC) -c -I$(INCDIR) $(CFLAGS) $<
##### TARGETS #####
# Make the library:
$(LIBDIR)/$(GLU_LIB): $(OBJECTS)
$(MAKELIB) $(GLU_LIB) $(MAJOR) $(MINOR) $(TINY) $(OBJECTS)

View File

@@ -1,96 +0,0 @@
# Mesa 3-D graphics library
# Version: 3.5
#
# Copyright (C) 2001 Wind River Systems, Inc
# The MIT License
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
# Makefile for GLU library
##### MACROS #####
GLU_MAJOR = 1
GLU_MINOR = 3
GLU_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
##### RULES #####
include ../rules.windml
GLU_SOURCES = \
glu.c \
mipmap.c \
nurbs.c \
nurbscrv.c \
nurbssrf.c \
nurbsutl.c \
polytest.c \
project.c \
quadric.c \
tess.c \
tesselat.c \
../src/windml/tornado/torMesaGLUInit.c
GLU_OBJECTS = $(GLU_SOURCES:.c=.o)
GLU_OBJNAME = $(MESA_LIBDIR)/objMesaGLU.o
SOURCES = $(GLU_SOURCES)
##### TARGETS #####
all: depend.$(CPU)$(TOOL) $(GLU_OBJNAME)
# Make the GLU library
$(GLU_OBJNAME): $(GLU_OBJECTS)
# $(LD) -r $(GLU_OBJECTS) -o $(MESA_OBJNAME)
$(LD) -r $(GLU_OBJECTS) -o $(GLU_OBJNAME)
# $(AR) rus $(MESA_LIBNAME) $(GLU_OBJNAME)
# $(AR) rus $(VX_LIBNAME) $(GLU_OBJNAME)
depend.$(CPU)$(TOOL):
ifeq ($(WIND_HOST_TYPE),x86-win32)
@ $(RM) $@
@ $(ECHO) Creating depend.$(CPU)$(TOOL)
ifneq ($(SOURCES),)
@ for %f in ($(SOURCES)) do \
$(CC) -MM $(CFLAGS) %f >>$@
endif
else
Makefile
@ $(RM) $@
@ $(ECHO) "Creating depend.$(CPU)$(TOOL)"
ifneq ($(SOURCES),)
@ for FILE in $(filter-out $(NODEPENDOBJS), $(SOURCES)); \
do \
$(CC) -MM $(CFLAGS) $$FILE \
| $(TCL) $(BIN_DIR)/depend.tcl $(TGT_DIR) >>$@; \
done
endif
endif
.PHONY = clean
clean:
# $(AR) d $(MESA_LIBNAME) $(GLU_OBJNAME)
# $(AR) d $(VX_LIBNAME) $(GLU_OBJNAME)
$(RM) $(GLU_OBJNAME)
$(RM) $(GLU_OBJECTS)
$(RM) depend.$(CPU)$(TOOL)
include depend.$(CPU)$(TOOL)

View File

@@ -1,62 +0,0 @@
LIBRARY GLU32
DESCRIPTION 'GLU for Windows Mesa'
EXETYPE WINDOWS
CODE MOVEABLE DISCARDABLE
DATA MOVEABLE SINGLE
HEAPSIZE 256000
STACKSIZE 4096
EXPORTS
gluLookAt
gluOrtho2D
gluPerspective
gluPickMatrix
gluProject
gluUnProject
gluErrorString
gluScaleImage
gluBuild1DMipmaps
gluBuild2DMipmaps
gluNewQuadric
gluDeleteQuadric
gluQuadricDrawStyle
gluQuadricOrientation
gluQuadricNormals
gluQuadricTexture
gluQuadricCallback
gluCylinder
gluSphere
gluDisk
gluPartialDisk
gluNewNurbsRenderer
gluDeleteNurbsRenderer
gluLoadSamplingMatrices
gluNurbsProperty
gluGetNurbsProperty
gluBeginCurve
gluEndCurve
gluNurbsCurve
gluBeginSurface
gluEndSurface
gluNurbsSurface
gluBeginTrim
gluEndTrim
gluPwlCurve
gluNurbsCallback
gluNewTess
gluDeleteTess
; gluTessBeginPolygon
; gluTessBeginContour
gluTessVertex
; gluTessEndContour
; gluTessEndPolygon
; gluTessProperty
; gluTessNormal
gluTessCallback
; gluGetTessProperty
gluBeginPolygon
gluNextContour
gluEndPolygon
gluGetString

View File

@@ -1,195 +0,0 @@
Notes on the GLU polygon tesselation facility implemented by Bogdan Sikorski...
The tesselation module is provided under the same terms as the Mesa
package.
This is the first release of polygon tesselation code for Mesa.
It was written during my very little free time, so lets name it:
"its not perfect". If someone hates pointers, don't look at the code.
I preffer dynamic allocation versus static. But _all_ ideas, suggestions,
bug reports and fixes are welcome (if You want, also flames). I am aware
that many things could have been written using better techniques, but time
that I could devote to this library was very limited. It is not well commented,
excuse me. Also I am thinking of continuing working on this code to improve,
fix and polish it. And make it as compliant as possible to the OpenGL, so
software ports from OpenGL to Mesa will work correctly. If You know of any
differences in behaviour, expected input/output between Mesa tesselation library
and OpenGL, please send me a note. I explain later on why I am not
confident with this code.
I tried to be fully compliant with the OpenGL routines. By "tried" I mean that
up to my knowledge it behaves as OpenGL tesselation routines. Just recently
I began to experiment with OpenGL (actually only Mesa), and also have
no access to any machine providing official implementation of OpenGL,
nor access to books (particulary Addison-Wesley publications). Thus my
knowledge on how the original tesselation code works, what kind of data
it expects etc. is based _only_ on the publicly available documentation
provided by SGI. Namely:
* "The OpenGL Graphics System Utility Library" by K.P.Smith
(Silicon Graphics, 1992)
* "The OpenGL Graphics Interface" by M.Segal and K.Akeley
(Silicon Graphics, 19??)
* "OpenGL and X, Part 1: Introduction" by M.J.Kilgard
(Silicon Graphics, 1994)
* "OpenGL and X, Part 2: Using OpenGL with Xlib" by M.J.Kilgard
(Silicon Graphics, 1994)
* "OpenGL Graphics with the X Window System" by P.Karlton
(Silicon Graphics, 1993)
* Online Docs - Appendix C of OpenGL Programming Guide, Polygon Tesselation
(partial text cut and sent by e-mail)
The tesselation routines use slightly different prototypes than the ones
specified in the mentioned above publications. The _only_ differences are
the enumeration types which are not GLenum, but are GLUenum. So the
implemented routines have following prototypes:
GLUtringulatorObj *gluNewTess(void);
void gluTessCallback(GLUtriangulatorObj *,GLUenum,void (*)());
^^^^^^^
void gluBeginPolygon(GLUtriangulatorObj *);
void gluTessVertex(GLUtriangulatorObj *,GLdouble [3],void *);
void gluNextContour(GLUtriangulatorObj *,GLUenum);
^^^^^^^
void gluEndPolygon(GLUtriangulatorObj *);
const GLubyte *gluErrorString(GLUenum);
^^^^^^^
prototypes for callback functions:
void <begin>(GLUenum);
^^^^^^^
void <edgeFlag>(GLboolean);
void <vertex>(void *);
void <end>(void);
void <error>(GLUenum);
^^^^^^^
The begin callback will be called only with GLU_TRIANGLES. No support
for traingle fans or strips yet.
In case of errors an internal error variable is set to the appropiate
error enum values (GLU_TESS_ERROR?). Initially it is set to GLU_NO_ERROR.
The OpenGL library provides 8 error conditions, the tesselation code
of Mesa provides 9. They are:
GLU_TESS_ERROR1: missing gluEndPolygon /* same as OpenGL */
GLU_TESS_ERROR2: missing gluBeginPolygon /* same as OpenGL */
GLU_TESS_ERROR3: misoriented contour /* not used in Mesa
in OpenGL is bad orientation or intersecting edges */
GLU_TESS_ERROR4: vertex/edge intersection /* same as OpenGL */
GLU_TESS_ERROR5: misoriented or self-intersecting loops /* same as OpenGL */
GLU_TESS_ERROR6: coincident vertices /* same as OpenGL */
GLU_TESS_ERROR7: colinear vertices /* OpenGL's illegal data */
GLU_TESS_ERROR8: intersecting edges /* same as OpenGL */
GLU_TESS_ERROR9: not coplanar contours /* new for Mesa */
The Mesa tesselation code ignores all data and calls after detecting an error
codition. This means that a _new_ tesselation object must be used for further
triangulations. Maybe this is too restrictive, and will be lifted in
future versions.
The tesselation code completely ignores the type parameter passed in
gluNextContour. It also doesn't check if the passed parameter is a legal
enum value - ignores silently (maybe at least this should be checked).
The reason I chose this behaviour is based on what I read in the
beforementioned documents. I cite:
"....
void gluNextContour(GLUtriangulatorObj *tessobj, GLenum type);
Marks the beginning of the next contour when multiple contours make up the
boundary of the polygon to be tessellated. type can be GLU_EXTERIOR,
GLU_INTERIOR, GLU_CCW, GLU_CW, or GLU_UNKNOWN. These serve only as
to the tessellation. If you get them right, the tessellation might
go faster. If you get them wrong, they're ignored, and the tesselation still
works.
....."
I hope You agree with me that my decision was correct. Mesa tesselation
_always_ checks by itself the interrelations between contours. Just as if
all contours were specified with the type GLU_UNKNOWN.
One of OpenGL's policy is not to check all error conditions - rely sometimes
that the user "got things right". This is justified, since exhausting
error checking is timeconsuming, and would significantly slow down
a correct application. The Mesa tesselation code assumes only _one_ condition
when triangulating - all vertices in a contour are planar. This is _not_
checked for correctness. Trying to tesselate such objects will lead to
unpredictable output.
And now we arrive to the moment where I would like to list the required
(but checked for) conditions for triangulation, as well as summarize the
library:
* all contours in a single tesselation cycle _must_ be coplanar - if not
an error is raised (and if provided a call to the error callback
is made)
* the contours can be passed in _any_ order, exteriors and holes can be
intermixed within a tesselation cycle and the correct hierarchy
will be determined by the library; thus specifying first holes then
exteriors, then holes within holes form a valid input.
* a hole within a hole is consider to be a yet another exterior contour
* multiple exterior contours (polygons) can be tesselated in one cycle;
_but_ this significantly degrades performance since many tests will be
performed for every contour pair; if You want triangulation to be fast
tesselate a single polygon (with possible holes) one at a time.
* orientation of exterior contours is arbitray, but if it has holes,
all interior holes of this particular exterior contour _must_ have an
opposite orientation.
* the output triangles have the same orientation as the exterior contour
that forms them
* each triangle is "enclosed" within the begin and end callbacks;
this is not efficent, but was made on purpose; so if triangulation
results in 2 triangles the following callbacks will be made in such
order:
<begin>(GLU_TRAINGLES)
<vertex>(...) /* 3 vertices of first triangle */
<vertex>(...)
<vertex>(...)
<end>()
<begin>(GLU_TRAINGLES)
<vertex>(...) /* 3 vertices of second triangle */
<vertex>(...)
<vertex>(...)
<end>()
Of course only when begin, vertex, and end callback were provided,
otherwise no output is done (actually tesselation does not take place).
* You will notice that some output traingles are very "thin"; there
exist possible several ways to traingulate a polygon, but "smart" code
avoiding such cases would require time to write, and will impact on
execution speed.
* like OpenGL, no new vertices are introduced during triangulation
* if the edgeflag callback is provided it will be called whenever
the just-about-to be output vertex begins a different type of edge
than the previous vertices; always before the first output a call
is made with GL_TRUE, to allow synchronization.
* all intermediate computations are done using GLdouble type, and comparisons
are biased with a precision value (EPSILON defined in tess.h)
* the point_in_poly function is my adaptation of code from the
comp.graphics.alg newsgroup FAQ (originally written by Mr. Wm. Randolph
Franklin, modified by Scott Anguish).
* the edge_edge_intersect test is also an adopted code from comp.graphics.alg
newsgroup FAQ
* the general idea for traingulation used in this library is described in
the book "Computational Geometry in C" by Joseph O'Rourke.
Excuse my English, its not my mother tongue. I should be available for some
time uner the following e-mail address. But For how long I am not certain.
Once I am settled in my new place, I'll post on the Mesa mailing list
my new address.
(PS: today is my last day of work here, I'm changing my job).
Bogdan. ( bogdan@dia.unisa.it )
Apr 28, 1995.

View File

@@ -1,43 +0,0 @@
The current NURBS implementation has no trimming facilities yet.
The code is not well commented.
1) Normal calculus fails for special cases of NURBS (independent
of the NURBS modules)
Those cases arise when for u or v, some control points
for a fixed value of that parameter form the same point.
Imagine a Bezier patch degenerated into a "triangle".
v ^ 0,1,2 order=3
| *
|
| 3* 4* 5*
|
| 6* 7* 8*
|
|
+------------------------> u
The calculus of du derivative at triple point (0,1 and 2) will fail.
As a result, the normal vector will be 0.
The eval2.c code has to be changed to handle the above situation.
2) Adjacent NURBS surfaces ("sharing" the same control points along
the "joining" edge) will be sampled with the same factor.
This prevents the formation of "cracks".
When the control polygon of the "shared" edge is not the same,
cracks might appear.
The sampling tolerance is sometimes not respected!
A NURBS object is broken into Bezier curves/surfaces. If one of such
Bezier objects has a local high curvature with other portions of it
relatively flat then the high curvature part will be sampled more dense that
its flatter regions.
The flat regions might be tesselated into quads having sides of length
greater than the current sampling tolernace setting.
I believe such behaviour is acceptable, though not along the concept of
sampling tolerance.
February 20, 1996.
Bogdan.

View File

@@ -1,54 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file includes all .h files needed for the GLU source code for
* the purpose of precompiled headers.
*
* If the preprocessor symbol PCH is defined at compile time then each
* of the .c files will #include "all.h" only, instead of a bunch of
* individual .h files.
*/
#ifndef GLU_ALL_H
#define GLU_ALL_H
#ifndef PC_HEADER
This is an error. all.h should be included only if PCH is defined.
#endif
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GL/gl.h"
#include "GL/glu.h"
#include "gluP.h"
#include "nurbs.h"
#include "tess.h"
#endif /*GLU_ALL_H */

View File

@@ -1,61 +0,0 @@
# Makefile for GLU for VMS
# contributed by Jouk Jansen joukj@hrem.stm.tudelft.nl
.first
define gl [-.include.gl]
.include [-]mms-config.
##### MACROS #####
VPATH = RCS
INCDIR = $disk2:[-.include]
LIBDIR = [-.lib]
CFLAGS = /include=$(INCDIR)/define=(FBIND=1)/name=(as_is,short)/float=ieee/ieee=denorm
SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
polytest.c project.c quadric.c tess.c tesselat.c
OBJECTS =glu.obj,mipmap.obj,nurbs.obj,nurbscrv.obj,nurbssrf.obj,nurbsutl.obj,\
polytest.obj,project.obj,quadric.obj,tess.obj,tesselat.obj
##### RULES #####
VERSION=MesaGlu V3.2
##### TARGETS #####
# Make the library:
$(LIBDIR)$(GLU_LIB) : $(OBJECTS)
.ifdef SHARE
@ WRITE_ SYS$OUTPUT " generating mesagl1.opt"
@ OPEN_/WRITE FILE mesagl1.opt
@ WRITE_ FILE "!"
@ WRITE_ FILE "! mesagl1.opt generated by DESCRIP.$(MMS_EXT)"
@ WRITE_ FILE "!"
@ WRITE_ FILE "IDENTIFICATION=""$(VERSION)"""
@ WRITE_ FILE "GSMATCH=LEQUAL,3,2
@ WRITE_ FILE "$(OBJECTS)"
@ WRITE_ FILE "[-.lib]libmesagl.exe/SHARE"
@ WRITE_ FILE "SYS$SHARE:DECW$XEXTLIBSHR/SHARE"
@ WRITE_ FILE "SYS$SHARE:DECW$XLIBSHR/SHARE"
@ CLOSE_ FILE
@ WRITE_ SYS$OUTPUT " generating mesagl.map ..."
@ LINK_/NODEB/NOSHARE/NOEXE/MAP=mesagl.map/FULL mesagl1.opt/OPT
@ WRITE_ SYS$OUTPUT " analyzing mesagl.map ..."
@ @[-.vms]ANALYZE_MAP.COM mesagl.map mesagl.opt
@ WRITE_ SYS$OUTPUT " linking $(GLU_LIB) ..."
@ LINK_/noinform/NODEB/SHARE=$(GLU_LIB)/MAP=mesagl.map/FULL mesagl1.opt/opt,mesagl.opt/opt
.else
@ $(MAKELIB) $(GLU_LIB) $(OBJECTS)
.endif
@ rename $(GLU_LIB)* $(LIBDIR)
clean :
delete *.obj;*
purge
include mms_depend.

View File

@@ -1,416 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
* Copyright (C) 1995-2001 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gluP.h"
#endif
/*
* Miscellaneous utility functions
*/
#ifndef M_PI
#define M_PI 3.1415926536
#endif
#define EPS 0.00001
#ifndef GLU_INCOMPATIBLE_GL_VERSION
#define GLU_INCOMPATIBLE_GL_VERSION 100903
#endif
void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz)
{
GLdouble m[16];
GLdouble x[3], y[3], z[3];
GLdouble mag;
/* Make rotation matrix */
/* Z vector */
z[0] = eyex - centerx;
z[1] = eyey - centery;
z[2] = eyez - centerz;
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
if (mag) { /* mpichler, 19950515 */
z[0] /= mag;
z[1] /= mag;
z[2] /= mag;
}
/* Y vector */
y[0] = upx;
y[1] = upy;
y[2] = upz;
/* X vector = Y cross Z */
x[0] = y[1] * z[2] - y[2] * z[1];
x[1] = -y[0] * z[2] + y[2] * z[0];
x[2] = y[0] * z[1] - y[1] * z[0];
/* Recompute Y = Z cross X */
y[0] = z[1] * x[2] - z[2] * x[1];
y[1] = -z[0] * x[2] + z[2] * x[0];
y[2] = z[0] * x[1] - z[1] * x[0];
/* mpichler, 19950515 */
/* cross product gives area of parallelogram, which is < 1.0 for
* non-perpendicular unit-length vectors; so normalize x, y here
*/
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
if (mag) {
x[0] /= mag;
x[1] /= mag;
x[2] /= mag;
}
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
if (mag) {
y[0] /= mag;
y[1] /= mag;
y[2] /= mag;
}
#define M(row,col) m[col*4+row]
M(0, 0) = x[0];
M(0, 1) = x[1];
M(0, 2) = x[2];
M(0, 3) = 0.0;
M(1, 0) = y[0];
M(1, 1) = y[1];
M(1, 2) = y[2];
M(1, 3) = 0.0;
M(2, 0) = z[0];
M(2, 1) = z[1];
M(2, 2) = z[2];
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixd(m);
/* Translate Eye to Origin */
glTranslated(-eyex, -eyey, -eyez);
}
void GLAPIENTRY
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
{
glOrtho(left, right, bottom, top, -1.0, 1.0);
}
static void
frustum(GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble nearval, GLdouble farval)
{
GLdouble x, y, a, b, c, d;
GLdouble m[16];
x = (2.0 * nearval) / (right - left);
y = (2.0 * nearval) / (top - bottom);
a = (right + left) / (right - left);
b = (top + bottom) / (top - bottom);
c = -(farval + nearval) / ( farval - nearval);
d = -(2.0 * farval * nearval) / (farval - nearval);
#define M(row,col) m[col*4+row]
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
#undef M
glMultMatrixd(m);
}
void GLAPIENTRY
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
/* don't call glFrustum() because of error semantics (covglu) */
frustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
void GLAPIENTRY
gluPickMatrix(GLdouble x, GLdouble y,
GLdouble width, GLdouble height, GLint viewport[4])
{
GLfloat m[16];
GLfloat sx, sy;
GLfloat tx, ty;
sx = viewport[2] / width;
sy = viewport[3] / height;
tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
#define M(row,col) m[col*4+row]
M(0, 0) = sx;
M(0, 1) = 0.0;
M(0, 2) = 0.0;
M(0, 3) = tx;
M(1, 0) = 0.0;
M(1, 1) = sy;
M(1, 2) = 0.0;
M(1, 3) = ty;
M(2, 0) = 0.0;
M(2, 1) = 0.0;
M(2, 2) = 1.0;
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixf(m);
}
const GLubyte *GLAPIENTRY
gluErrorString(GLenum errorCode)
{
static char *tess_error[] = {
"missing gluBeginPolygon",
"missing gluBeginContour",
"missing gluEndPolygon",
"missing gluEndContour",
"misoriented or self-intersecting loops",
"coincident vertices",
"colinear vertices",
"FIST recovery process fatal error"
};
static char *nurbs_error[] = {
"spline order un-supported",
"too few knots",
"valid knot range is empty",
"decreasing knot sequence knot",
"knot multiplicity greater than order of spline",
"endcurve() must follow bgncurve()",
"bgncurve() must precede endcurve()",
"missing or extra geometric data",
"can't draw pwlcurves",
"missing bgncurve()",
"missing bgnsurface()",
"endtrim() must precede endsurface()",
"bgnsurface() must precede endsurface()",
"curve of improper type passed as trim curve",
"bgnsurface() must precede bgntrim()",
"endtrim() must follow bgntrim()",
"bgntrim() must precede endtrim()",
"invalid or missing trim curve",
"bgntrim() must precede pwlcurve()",
"pwlcurve referenced twice",
"pwlcurve and nurbscurve mixed",
"improper usage of trim data type",
"nurbscurve referenced twice",
"nurbscurve and pwlcurve mixed",
"nurbssurface referenced twice",
"invalid property",
"endsurface() must follow bgnsurface()",
"misoriented trim curves",
"intersecting trim curves",
"UNUSED",
"unconnected trim curves",
"unknown knot error",
"negative vertex count encountered",
"negative byte-stride encountered",
"unknown type descriptor",
"null control array or knot vector",
"duplicate point on pwlcurve"
};
/* GL Errors */
if (errorCode == GL_NO_ERROR) {
return (GLubyte *) "no error";
}
else if (errorCode == GL_INVALID_VALUE) {
return (GLubyte *) "invalid value";
}
else if (errorCode == GL_INVALID_ENUM) {
return (GLubyte *) "invalid enum";
}
else if (errorCode == GL_INVALID_OPERATION) {
return (GLubyte *) "invalid operation";
}
else if (errorCode == GL_STACK_OVERFLOW) {
return (GLubyte *) "stack overflow";
}
else if (errorCode == GL_STACK_UNDERFLOW) {
return (GLubyte *) "stack underflow";
}
else if (errorCode == GL_OUT_OF_MEMORY) {
return (GLubyte *) "out of memory";
}
/* GLU Errors */
else if (errorCode == GLU_NO_ERROR) {
return (GLubyte *) "no error";
}
else if (errorCode == GLU_INVALID_ENUM) {
return (GLubyte *) "invalid enum";
}
else if (errorCode == GLU_INVALID_VALUE) {
return (GLubyte *) "invalid value";
}
else if (errorCode == GLU_OUT_OF_MEMORY) {
return (GLubyte *) "out of memory";
}
else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) {
return (GLubyte *) "incompatible GL version";
}
else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) {
return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1];
}
else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) {
return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1];
}
else {
return NULL;
}
}
/*
* New in GLU 1.1
*/
const GLubyte *GLAPIENTRY
gluGetString(GLenum name)
{
static char *extensions = "GL_EXT_abgr";
static char *version = "1.1 Mesa 3.5";
switch (name) {
case GLU_EXTENSIONS:
return (GLubyte *) extensions;
case GLU_VERSION:
return (GLubyte *) version;
default:
return NULL;
}
}
#if 0 /* gluGetProcAddressEXT not finalized yet! */
#ifdef __cplusplus
/* for BeOS R4.5 */
void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...)
#else
void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) ()
#endif
{
struct proc
{
const char *name;
void *address;
};
static struct proc procTable[] = {
{"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT}, /* me! */
/* new 1.1 functions */
{"gluGetString", (void *) gluGetString},
/* new 1.2 functions */
{"gluTessBeginPolygon", (void *) gluTessBeginPolygon},
{"gluTessBeginContour", (void *) gluTessBeginContour},
{"gluTessEndContour", (void *) gluTessEndContour},
{"gluTessEndPolygon", (void *) gluTessEndPolygon},
{"gluGetTessProperty", (void *) gluGetTessProperty},
/* new 1.3 functions */
{NULL, NULL}
};
GLuint i;
for (i = 0; procTable[i].address; i++) {
if (strcmp((const char *) procName, procTable[i].name) == 0)
return (void (GLAPIENTRY *) ()) procTable[i].address;
}
return NULL;
}
#endif
/*
* New in GLU 1.3
*/
#ifdef GLU_VERSION_1_3
GLboolean GLAPIENTRY
gluCheckExtension(const GLubyte *extName, const GLubyte * extString)
{
assert(extName);
assert(extString);
{
const int len = strlen((const char *) extName);
const char *start = (const char *) extString;
while (1) {
const char *c = strstr(start, (const char *) extName);
if (!c)
return GL_FALSE;
if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0))
return GL_TRUE;
start = c + len;
}
}
}
#endif

View File

@@ -1,97 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.3
* Copyright (C) 1995-2004 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file allows the GLU code to be compiled either with the Mesa
* headers or with the real OpenGL headers.
*/
#ifndef GLUP_H
#define GLUP_H
#include <GL/gl.h>
#include <GL/glu.h>
#include <string.h>
#if defined(_WIN32) && !defined(__WIN32__)
# define __WIN32__
#endif
#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN__))
# pragma warning( disable : 4068 ) /* unknown pragma */
# pragma warning( disable : 4710 ) /* function 'foo' not inlined */
# pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */
# pragma warning( disable : 4127 ) /* conditional expression is constant */
# if defined(MESA_MINWARN)
# pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
# pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
# pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
# pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */
# pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
# endif
# define GLCALLBACK __stdcall
# if defined(__CYGWIN__)
# define GLCALLBACKPCAST *
# else
# define GLCALLBACKPCAST __stdcall *
# endif
#else
/* non-Windows compilation */
# define GLCALLBACK
# define GLCALLBACKPCAST *
#endif /* WIN32 / CYGWIN bracket */
/* compatability guard so we don't need to change client code */
#if defined(_WIN32) && !defined(_WINDEF_) && !defined(_GNU_H_WINDOWS32_BASE) && !defined(OPENSTEP)
# define CALLBACK GLCALLBACK
#endif
#ifndef GLU_TESS_ERROR9
/* If we're using the real OpenGL header files... */
# define GLU_TESS_ERROR9 100159
#endif
#define GLU_NO_ERROR GL_NO_ERROR
/* for Sun: */
#ifdef SUNOS4
#define MEMCPY( DST, SRC, BYTES) \
memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) )
#else
#define MEMCPY( DST, SRC, BYTES) \
memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) )
#endif
#ifndef NULL
# define NULL 0
#endif
#endif

View File

@@ -1,824 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.4
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#endif
/*
* Compute ceiling of integer quotient of A divided by B:
*/
#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
#ifdef EPSILON
#undef EPSILON
#endif
#define EPSILON 0.001
/* To work around optimizer bug in MSVC4.1 */
#if defined(__WIN32__) && !defined(OPENSTEP)
void
dummy(GLuint j, GLuint k)
{
}
#else
#define dummy(J, K)
#endif
GLint GLAPIENTRY
gluScaleImage(GLenum format,
GLsizei widthin, GLsizei heightin,
GLenum typein, const void *datain,
GLsizei widthout, GLsizei heightout,
GLenum typeout, void *dataout)
{
GLint components, i, j, k;
GLfloat *tempin, *tempout;
GLfloat sx, sy;
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
GLint packrowlength, packalignment, packskiprows, packskippixels;
GLint sizein, sizeout;
GLint rowstride, rowlen;
/* Determine number of components per pixel */
switch (format) {
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
components = 1;
break;
case GL_LUMINANCE_ALPHA:
components = 2;
break;
case GL_RGB:
case GL_BGR:
components = 3;
break;
case GL_RGBA:
case GL_BGRA:
#ifdef GL_EXT_abgr
case GL_ABGR_EXT:
#endif
components = 4;
break;
default:
return GLU_INVALID_ENUM;
}
/* Determine bytes per input datum */
switch (typein) {
case GL_UNSIGNED_BYTE:
sizein = sizeof(GLubyte);
break;
case GL_BYTE:
sizein = sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
sizein = sizeof(GLushort);
break;
case GL_SHORT:
sizein = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
sizein = sizeof(GLuint);
break;
case GL_INT:
sizein = sizeof(GLint);
break;
case GL_FLOAT:
sizein = sizeof(GLfloat);
break;
case GL_BITMAP:
/* not implemented yet */
default:
return GL_INVALID_ENUM;
}
/* Determine bytes per output datum */
switch (typeout) {
case GL_UNSIGNED_BYTE:
sizeout = sizeof(GLubyte);
break;
case GL_BYTE:
sizeout = sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
sizeout = sizeof(GLushort);
break;
case GL_SHORT:
sizeout = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
sizeout = sizeof(GLuint);
break;
case GL_INT:
sizeout = sizeof(GLint);
break;
case GL_FLOAT:
sizeout = sizeof(GLfloat);
break;
case GL_BITMAP:
/* not implemented yet */
default:
return GL_INVALID_ENUM;
}
/* Get glPixelStore state */
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);
/* Allocate storage for intermediate images */
tempin = (GLfloat *) malloc(widthin * heightin
* components * sizeof(GLfloat));
if (!tempin) {
return GLU_OUT_OF_MEMORY;
}
tempout = (GLfloat *) malloc(widthout * heightout
* components * sizeof(GLfloat));
if (!tempout) {
free(tempin);
return GLU_OUT_OF_MEMORY;
}
/*
* Unpack the pixel data and convert to floating point
*/
if (unpackrowlength > 0) {
rowlen = unpackrowlength;
}
else {
rowlen = widthin;
}
if (sizein >= unpackalignment) {
rowstride = components * rowlen;
}
else {
rowstride = unpackalignment / sizein
* CEILING(components * rowlen * sizein, unpackalignment);
}
switch (typein) {
case GL_UNSIGNED_BYTE:
k = 0;
for (i = 0; i < heightin; i++) {
GLubyte *ubptr = (GLubyte *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * ubptr++;
}
}
break;
case GL_BYTE:
k = 0;
for (i = 0; i < heightin; i++) {
GLbyte *bptr = (GLbyte *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * bptr++;
}
}
break;
case GL_UNSIGNED_SHORT:
k = 0;
for (i = 0; i < heightin; i++) {
GLushort *usptr = (GLushort *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * usptr++;
}
}
break;
case GL_SHORT:
k = 0;
for (i = 0; i < heightin; i++) {
GLshort *sptr = (GLshort *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * sptr++;
}
}
break;
case GL_UNSIGNED_INT:
k = 0;
for (i = 0; i < heightin; i++) {
GLuint *uiptr = (GLuint *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * uiptr++;
}
}
break;
case GL_INT:
k = 0;
for (i = 0; i < heightin; i++) {
GLint *iptr = (GLint *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * iptr++;
}
}
break;
case GL_FLOAT:
k = 0;
for (i = 0; i < heightin; i++) {
GLfloat *fptr = (GLfloat *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = *fptr++;
}
}
break;
default:
return GLU_INVALID_ENUM;
}
/*
* Scale the image!
*/
if (widthout > 1)
sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1);
else
sx = (GLfloat) (widthin - 1);
if (heightout > 1)
sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1);
else
sy = (GLfloat) (heightin - 1);
/*#define POINT_SAMPLE*/
#ifdef POINT_SAMPLE
for (i = 0; i < heightout; i++) {
GLint ii = i * sy;
for (j = 0; j < widthout; j++) {
GLint jj = j * sx;
GLfloat *src = tempin + (ii * widthin + jj) * components;
GLfloat *dst = tempout + (i * widthout + j) * components;
for (k = 0; k < components; k++) {
*dst++ = *src++;
}
}
}
#else
if (sx < 1.0 && sy < 1.0) {
/* magnify both width and height: use weighted sample of 4 pixels */
GLint i0, i1, j0, j1;
GLfloat alpha, beta;
GLfloat *src00, *src01, *src10, *src11;
GLfloat s1, s2;
GLfloat *dst;
for (i = 0; i < heightout; i++) {
i0 = i * sy;
i1 = i0 + 1;
if (i1 >= heightin)
i1 = heightin - 1;
/* i1 = (i+1) * sy - EPSILON;*/
alpha = i * sy - i0;
for (j = 0; j < widthout; j++) {
j0 = j * sx;
j1 = j0 + 1;
if (j1 >= widthin)
j1 = widthin - 1;
/* j1 = (j+1) * sx - EPSILON; */
beta = j * sx - j0;
/* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
src00 = tempin + (i0 * widthin + j0) * components;
src01 = tempin + (i0 * widthin + j1) * components;
src10 = tempin + (i1 * widthin + j0) * components;
src11 = tempin + (i1 * widthin + j1) * components;
dst = tempout + (i * widthout + j) * components;
for (k = 0; k < components; k++) {
s1 = *src00++ * (1.0 - beta) + *src01++ * beta;
s2 = *src10++ * (1.0 - beta) + *src11++ * beta;
*dst++ = s1 * (1.0 - alpha) + s2 * alpha;
}
}
}
}
else {
/* shrink width and/or height: use an unweighted box filter */
GLint i0, i1;
GLint j0, j1;
GLint ii, jj;
GLfloat sum, *dst;
for (i = 0; i < heightout; i++) {
i0 = i * sy;
i1 = i0 + 1;
if (i1 >= heightin)
i1 = heightin - 1;
/* i1 = (i+1) * sy - EPSILON; */
for (j = 0; j < widthout; j++) {
j0 = j * sx;
j1 = j0 + 1;
if (j1 >= widthin)
j1 = widthin - 1;
/* j1 = (j+1) * sx - EPSILON; */
dst = tempout + (i * widthout + j) * components;
/* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
for (k = 0; k < components; k++) {
sum = 0.0;
for (ii = i0; ii <= i1; ii++) {
for (jj = j0; jj <= j1; jj++) {
sum += *(tempin + (ii * widthin + jj) * components + k);
}
}
sum /= (j1 - j0 + 1) * (i1 - i0 + 1);
*dst++ = sum;
}
}
}
}
#endif
/*
* Return output image
*/
if (packrowlength > 0) {
rowlen = packrowlength;
}
else {
rowlen = widthout;
}
if (sizeout >= packalignment) {
rowstride = components * rowlen;
}
else {
rowstride = packalignment / sizeout
* CEILING(components * rowlen * sizeout, packalignment);
}
switch (typeout) {
case GL_UNSIGNED_BYTE:
k = 0;
for (i = 0; i < heightout; i++) {
GLubyte *ubptr = (GLubyte *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*ubptr++ = (GLubyte) tempout[k++];
}
}
break;
case GL_BYTE:
k = 0;
for (i = 0; i < heightout; i++) {
GLbyte *bptr = (GLbyte *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*bptr++ = (GLbyte) tempout[k++];
}
}
break;
case GL_UNSIGNED_SHORT:
k = 0;
for (i = 0; i < heightout; i++) {
GLushort *usptr = (GLushort *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*usptr++ = (GLushort) tempout[k++];
}
}
break;
case GL_SHORT:
k = 0;
for (i = 0; i < heightout; i++) {
GLshort *sptr = (GLshort *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*sptr++ = (GLshort) tempout[k++];
}
}
break;
case GL_UNSIGNED_INT:
k = 0;
for (i = 0; i < heightout; i++) {
GLuint *uiptr = (GLuint *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*uiptr++ = (GLuint) tempout[k++];
}
}
break;
case GL_INT:
k = 0;
for (i = 0; i < heightout; i++) {
GLint *iptr = (GLint *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*iptr++ = (GLint) tempout[k++];
}
}
break;
case GL_FLOAT:
k = 0;
for (i = 0; i < heightout; i++) {
GLfloat *fptr = (GLfloat *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*fptr++ = tempout[k++];
}
}
break;
default:
return GLU_INVALID_ENUM;
}
/* free temporary image storage */
free(tempin);
free(tempout);
return 0;
}
/*
* Return the largest k such that 2^k <= n.
*/
static GLint
ilog2(GLint n)
{
GLint k;
if (n <= 0)
return 0;
for (k = 0; n >>= 1; k++);
return k;
}
/*
* Find the value nearest to n which is also a power of two.
*/
static GLint
round2(GLint n)
{
GLint m;
for (m = 1; m < n; m *= 2);
/* m>=n */
if (m - n <= n - m / 2) {
return m;
}
else {
return m / 2;
}
}
/*
* Given an pixel format and datatype, return the number of bytes to
* store one pixel.
*/
static GLint
bytes_per_pixel(GLenum format, GLenum type)
{
GLint n, m;
switch (format) {
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
n = 1;
break;
case GL_LUMINANCE_ALPHA:
n = 2;
break;
case GL_RGB:
case GL_BGR:
n = 3;
break;
case GL_RGBA:
case GL_BGRA:
#ifdef GL_EXT_abgr
case GL_ABGR_EXT:
#endif
n = 4;
break;
default:
n = 0;
}
switch (type) {
case GL_UNSIGNED_BYTE:
m = sizeof(GLubyte);
break;
case GL_BYTE:
m = sizeof(GLbyte);
break;
case GL_BITMAP:
m = 1;
break;
case GL_UNSIGNED_SHORT:
m = sizeof(GLushort);
break;
case GL_SHORT:
m = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
m = sizeof(GLuint);
break;
case GL_INT:
m = sizeof(GLint);
break;
case GL_FLOAT:
m = sizeof(GLfloat);
break;
default:
m = 0;
}
return n * m;
}
/*
* WARNING: This function isn't finished and has never been tested!!!!
*/
GLint GLAPIENTRY
gluBuild1DMipmaps(GLenum target, GLint components,
GLsizei width, GLenum format, GLenum type, const void *data)
{
GLubyte *texture;
GLint levels, max_levels;
GLint new_width, max_width;
GLint i, j, k, l;
if (width < 1)
return GLU_INVALID_VALUE;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_width);
max_levels = ilog2(max_width) + 1;
/* Compute how many mipmap images to make */
levels = ilog2(width) + 1;
if (levels > max_levels) {
levels = max_levels;
}
new_width = 1 << (levels - 1);
texture = (GLubyte *) malloc(new_width * components);
if (!texture) {
return GLU_OUT_OF_MEMORY;
}
if (width != new_width) {
/* initial rescaling */
switch (type) {
case GL_UNSIGNED_BYTE:
{
GLubyte *ub_data = (GLubyte *) data;
for (i = 0; i < new_width; i++) {
j = i * width / new_width;
for (k = 0; k < components; k++) {
texture[i * components + k] = ub_data[j * components + k];
}
}
}
break;
default:
/* Not implemented */
return GLU_ERROR;
}
}
/* generate and load mipmap images */
for (l = 0; l < levels; l++) {
glTexImage1D(GL_TEXTURE_1D, l, components, new_width, 0,
format, GL_UNSIGNED_BYTE, texture);
/* Scale image down to 1/2 size */
new_width = new_width / 2;
for (i = 0; i < new_width; i++) {
for (k = 0; k < components; k++) {
GLint sample1, sample2;
sample1 = (GLint) texture[i * 2 * components + k];
sample2 = (GLint) texture[(i * 2 + 1) * components + k];
texture[i * components + k] = (GLubyte) ((sample1 + sample2) / 2);
}
}
}
free(texture);
return 0;
}
GLint GLAPIENTRY
gluBuild2DMipmaps(GLenum target, GLint components,
GLsizei width, GLsizei height, GLenum format,
GLenum type, const void *data)
{
GLint w, h, maxsize;
void *image, *newimage;
GLint neww, newh, level, bpp;
int error;
GLboolean done;
GLint retval = 0;
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
GLint packrowlength, packalignment, packskiprows, packskippixels;
if (width < 1 || height < 1)
return GLU_INVALID_VALUE;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
w = round2(width);
if (w > maxsize) {
w = maxsize;
}
h = round2(height);
if (h > maxsize) {
h = maxsize;
}
bpp = bytes_per_pixel(format, type);
if (bpp == 0) {
/* probably a bad format or type enum */
return GLU_INVALID_ENUM;
}
/* Get current glPixelStore values */
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);
/* set pixel packing */
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
done = GL_FALSE;
if (w != width || h != height) {
/* must rescale image to get "top" mipmap texture image */
image = malloc((w + 4) * h * bpp);
if (!image) {
return GLU_OUT_OF_MEMORY;
}
error = gluScaleImage(format, width, height, type, data,
w, h, type, image);
if (error) {
retval = error;
done = GL_TRUE;
}
}
else {
image = (void *) data;
}
level = 0;
while (!done) {
if (image != data) {
/* set pixel unpacking */
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
}
glTexImage2D(target, level, components, w, h, 0, format, type, image);
if (w == 1 && h == 1)
break;
neww = (w < 2) ? 1 : w / 2;
newh = (h < 2) ? 1 : h / 2;
newimage = malloc((neww + 4) * newh * bpp);
if (!newimage) {
return GLU_OUT_OF_MEMORY;
}
error = gluScaleImage(format, w, h, type, image,
neww, newh, type, newimage);
if (error) {
retval = error;
done = GL_TRUE;
}
if (image != data) {
free(image);
}
image = newimage;
w = neww;
h = newh;
level++;
}
if (image != data) {
free(image);
}
/* Restore original glPixelStore state */
glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);
return retval;
}

View File

@@ -1,15 +0,0 @@
# DO NOT DELETE THIS LINE -- make depend depends on it.
glu.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
mipmap.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
nurbs.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
nurbscrv.obj : nurbs.h gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
nurbssrf.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
nurbsutl.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
project.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
quadric.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
tess.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_fist.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_hash.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_heap.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_clip.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h

View File

@@ -1,628 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#include "nurbs.h"
#endif
void
call_user_error(GLUnurbsObj * nobj, GLenum error)
{
nobj->error = error;
if (nobj->error_callback != NULL) {
(*(nobj->error_callback)) (error);
}
else {
printf("NURBS error %d %s\n", error, (char *) gluErrorString(error));
}
}
GLUnurbsObj *GLAPIENTRY
gluNewNurbsRenderer(void)
{
GLUnurbsObj *n;
GLfloat tmp_viewport[4];
GLint i, j;
n = (GLUnurbsObj *) malloc(sizeof(GLUnurbsObj));
if (n) {
/* init */
n->culling = GL_FALSE;
n->nurbs_type = GLU_NURBS_NONE;
n->error = GLU_NO_ERROR;
n->error_callback = NULL;
n->auto_load_matrix = GL_TRUE;
n->sampling_tolerance = 50.0;
n->parametric_tolerance = 0.5;
n->u_step = n->v_step = 100;
n->sampling_method = GLU_PATH_LENGTH;
n->display_mode = GLU_FILL;
/* in case the user doesn't supply the sampling matrices */
/* set projection and modelview to identity */
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
if (i == j) {
n->sampling_matrices.model[i * 4 + j] = 1.0;
n->sampling_matrices.proj[i * 4 + j] = 1.0;
}
else {
n->sampling_matrices.model[i * 4 + j] = 0.0;
n->sampling_matrices.proj[i * 4 + j] = 0.0;
}
/* and set the viewport sampling matrix to current ciewport */
glGetFloatv(GL_VIEWPORT, tmp_viewport);
for (i = 0; i < 4; i++)
n->sampling_matrices.viewport[i] = tmp_viewport[i];
n->trim = NULL;
}
return n;
}
void GLAPIENTRY
gluDeleteNurbsRenderer(GLUnurbsObj * nobj)
{
if (nobj) {
free(nobj);
}
}
void GLAPIENTRY
gluLoadSamplingMatrices(GLUnurbsObj * nobj,
const GLfloat modelMatrix[16],
const GLfloat projMatrix[16], const GLint viewport[4])
{
GLint i;
for (i = 0; i < 16; i++) {
nobj->sampling_matrices.model[i] = modelMatrix[i];
nobj->sampling_matrices.proj[i] = projMatrix[i];
}
for (i = 0; i < 4; i++)
nobj->sampling_matrices.viewport[i] = viewport[i];
}
void GLAPIENTRY
gluNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat value)
{
GLenum val;
switch (property) {
case GLU_SAMPLING_TOLERANCE:
if (value <= 0.0) {
call_user_error(nobj, GLU_INVALID_VALUE);
return;
}
nobj->sampling_tolerance = value;
break;
case GLU_PARAMETRIC_TOLERANCE:
if (value <= 0.0) {
call_user_error(nobj, GLU_INVALID_VALUE);
return;
}
nobj->parametric_tolerance = value;
break;
case GLU_U_STEP:
if (value <= 0.0) {
call_user_error(nobj, GLU_INVALID_VALUE);
return;
}
nobj->u_step = (GLint) value;
break;
case GLU_V_STEP:
if (value <= 0.0) {
call_user_error(nobj, GLU_INVALID_VALUE);
return;
}
nobj->v_step = (GLint) value;
break;
case GLU_SAMPLING_METHOD:
val = (GLenum) value;
if (val != GLU_PATH_LENGTH && val != GLU_PARAMETRIC_ERROR
&& val != GLU_DOMAIN_DISTANCE) {
call_user_error(nobj, GLU_INVALID_ENUM);
return;
}
nobj->sampling_method = val;
break;
case GLU_DISPLAY_MODE:
val = (GLenum) value;
if (val != GLU_FILL && val != GLU_OUTLINE_POLYGON
&& val != GLU_OUTLINE_PATCH) {
call_user_error(nobj, GLU_INVALID_ENUM);
return;
}
if (nobj->nurbs_type == GLU_NURBS_CURVE) {
call_user_error(nobj, GLU_NURBS_ERROR26);
return;
}
nobj->display_mode = val;
if (val == GLU_OUTLINE_PATCH)
fprintf(stderr,
"NURBS, for the moment, can display only in POLYGON mode\n");
break;
case GLU_CULLING:
val = (GLenum) value;
if (val != GL_TRUE && val != GL_FALSE) {
call_user_error(nobj, GLU_INVALID_ENUM);
return;
}
nobj->culling = (GLboolean) value;
break;
case GLU_AUTO_LOAD_MATRIX:
val = (GLenum) value;
if (val != GL_TRUE && val != GL_FALSE) {
call_user_error(nobj, GLU_INVALID_ENUM);
return;
}
nobj->auto_load_matrix = (GLboolean) value;
break;
default:
call_user_error(nobj, GLU_NURBS_ERROR26);
}
}
void GLAPIENTRY
gluGetNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat * value)
{
switch (property) {
case GLU_SAMPLING_TOLERANCE:
*value = nobj->sampling_tolerance;
break;
case GLU_DISPLAY_MODE:
*value = (GLfloat) (GLint) nobj->display_mode;
break;
case GLU_CULLING:
*value = nobj->culling ? 1.0 : 0.0;
break;
case GLU_AUTO_LOAD_MATRIX:
*value = nobj->auto_load_matrix ? 1.0 : 0.0;
break;
default:
call_user_error(nobj, GLU_INVALID_ENUM);
}
}
void GLAPIENTRY
gluBeginCurve(GLUnurbsObj * nobj)
{
if (nobj->nurbs_type == GLU_NURBS_CURVE) {
call_user_error(nobj, GLU_NURBS_ERROR6);
return;
}
nobj->nurbs_type = GLU_NURBS_CURVE;
nobj->curve.geom.type = GLU_INVALID_ENUM;
nobj->curve.color.type = GLU_INVALID_ENUM;
nobj->curve.texture.type = GLU_INVALID_ENUM;
nobj->curve.normal.type = GLU_INVALID_ENUM;
}
void GLAPIENTRY
gluEndCurve(GLUnurbsObj * nobj)
{
if (nobj->nurbs_type == GLU_NURBS_NONE) {
call_user_error(nobj, GLU_NURBS_ERROR7);
return;
}
if (nobj->curve.geom.type == GLU_INVALID_ENUM) {
call_user_error(nobj, GLU_NURBS_ERROR8);
nobj->nurbs_type = GLU_NURBS_NONE;
return;
}
glPushAttrib((GLbitfield) (GL_EVAL_BIT | GL_ENABLE_BIT));
glDisable(GL_MAP1_VERTEX_3);
glDisable(GL_MAP1_VERTEX_4);
glDisable(GL_MAP1_INDEX);
glDisable(GL_MAP1_COLOR_4);
glDisable(GL_MAP1_NORMAL);
glDisable(GL_MAP1_TEXTURE_COORD_1);
glDisable(GL_MAP1_TEXTURE_COORD_2);
glDisable(GL_MAP1_TEXTURE_COORD_3);
glDisable(GL_MAP1_TEXTURE_COORD_4);
glDisable(GL_MAP2_VERTEX_3);
glDisable(GL_MAP2_VERTEX_4);
glDisable(GL_MAP2_INDEX);
glDisable(GL_MAP2_COLOR_4);
glDisable(GL_MAP2_NORMAL);
glDisable(GL_MAP2_TEXTURE_COORD_1);
glDisable(GL_MAP2_TEXTURE_COORD_2);
glDisable(GL_MAP2_TEXTURE_COORD_3);
glDisable(GL_MAP2_TEXTURE_COORD_4);
do_nurbs_curve(nobj);
glPopAttrib();
nobj->nurbs_type = GLU_NURBS_NONE;
}
void GLAPIENTRY
gluNurbsCurve(GLUnurbsObj * nobj, GLint nknots, GLfloat * knot,
GLint stride, GLfloat * ctlarray, GLint order, GLenum type)
{
if (nobj->nurbs_type == GLU_NURBS_TRIM) {
#if 0
/* TODO: NOT IMPLEMENTED YET */
nurbs_trim *ptr1;
trim_list *ptr2;
if (type != GLU_MAP1_TRIM_2 && type != GLU_MAP1_TRIM_3) {
call_user_error(nobj, GLU_NURBS_ERROR14);
return;
}
for (ptr1 = nobj->trim; ptr1->next; ptr1 = ptr1->next);
if (ptr1->trim_loop) {
for (ptr2 = ptr1->trim_loop; ptr2->next; ptr2 = ptr2->next);
if ((ptr2->next = (trim_list *) malloc(sizeof(trim_list))) == NULL) {
call_user_error(nobj, GLU_OUT_OF_MEMORY);
return;
}
ptr2 = ptr2->next;
}
else {
if ((ptr2 = (trim_list *) malloc(sizeof(trim_list))) == NULL) {
call_user_error(nobj, GLU_OUT_OF_MEMORY);
return;
}
ptr1->trim_loop = ptr2;
}
ptr2->trim_type = GLU_TRIM_NURBS;
ptr2->curve.nurbs_curve.knot_count = nknots;
ptr2->curve.nurbs_curve.knot = knot;
ptr2->curve.nurbs_curve.stride = stride;
ptr2->curve.nurbs_curve.ctrlarray = ctlarray;
ptr2->curve.nurbs_curve.order = order;
ptr2->curve.nurbs_curve.dim = (type == GLU_MAP1_TRIM_2 ? 2 : 3);
ptr2->curve.nurbs_curve.type = type;
ptr2->next = NULL;
#endif
}
else {
if (type == GLU_MAP1_TRIM_2 || type == GLU_MAP1_TRIM_3) {
call_user_error(nobj, GLU_NURBS_ERROR22);
return;
}
if (nobj->nurbs_type != GLU_NURBS_CURVE) {
call_user_error(nobj, GLU_NURBS_ERROR10);
return;
}
switch (type) {
case GL_MAP1_VERTEX_3:
case GL_MAP1_VERTEX_4:
if (nobj->curve.geom.type != GLU_INVALID_ENUM) {
call_user_error(nobj, GLU_NURBS_ERROR8);
return;
}
nobj->curve.geom.type = type;
nobj->curve.geom.knot_count = nknots;
nobj->curve.geom.knot = knot;
nobj->curve.geom.stride = stride;
nobj->curve.geom.ctrlarray = ctlarray;
nobj->curve.geom.order = order;
break;
case GL_MAP1_INDEX:
case GL_MAP1_COLOR_4:
nobj->curve.color.type = type;
nobj->curve.color.knot_count = nknots;
nobj->curve.color.knot = knot;
nobj->curve.color.stride = stride;
nobj->curve.color.ctrlarray = ctlarray;
nobj->curve.color.order = order;
break;
case GL_MAP1_NORMAL:
nobj->curve.normal.type = type;
nobj->curve.normal.knot_count = nknots;
nobj->curve.normal.knot = knot;
nobj->curve.normal.stride = stride;
nobj->curve.normal.ctrlarray = ctlarray;
nobj->curve.normal.order = order;
break;
case GL_MAP1_TEXTURE_COORD_1:
case GL_MAP1_TEXTURE_COORD_2:
case GL_MAP1_TEXTURE_COORD_3:
case GL_MAP1_TEXTURE_COORD_4:
nobj->curve.texture.type = type;
nobj->curve.texture.knot_count = nknots;
nobj->curve.texture.knot = knot;
nobj->curve.texture.stride = stride;
nobj->curve.texture.ctrlarray = ctlarray;
nobj->curve.texture.order = order;
break;
default:
call_user_error(nobj, GLU_INVALID_ENUM);
}
}
}
void GLAPIENTRY
gluBeginSurface(GLUnurbsObj * nobj)
{
switch (nobj->nurbs_type) {
case GLU_NURBS_NONE:
nobj->nurbs_type = GLU_NURBS_SURFACE;
nobj->surface.geom.type = GLU_INVALID_ENUM;
nobj->surface.color.type = GLU_INVALID_ENUM;
nobj->surface.texture.type = GLU_INVALID_ENUM;
nobj->surface.normal.type = GLU_INVALID_ENUM;
break;
case GLU_NURBS_TRIM:
call_user_error(nobj, GLU_NURBS_ERROR16);
break;
case GLU_NURBS_SURFACE:
case GLU_NURBS_NO_TRIM:
case GLU_NURBS_TRIM_DONE:
call_user_error(nobj, GLU_NURBS_ERROR27);
break;
case GLU_NURBS_CURVE:
call_user_error(nobj, GLU_NURBS_ERROR6);
break;
}
}
void GLAPIENTRY
gluEndSurface(GLUnurbsObj * nobj)
{
switch (nobj->nurbs_type) {
case GLU_NURBS_NONE:
call_user_error(nobj, GLU_NURBS_ERROR13);
break;
case GLU_NURBS_TRIM:
call_user_error(nobj, GLU_NURBS_ERROR12);
break;
case GLU_NURBS_TRIM_DONE:
/* if(nobj->trim->trim_loop==NULL)
{
call_user_error(nobj,GLU_NURBS_ERROR18);
return;
}*/
/* no break - fallthrough */
case GLU_NURBS_NO_TRIM:
glPushAttrib((GLbitfield)
(GL_EVAL_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT));
glDisable(GL_MAP2_VERTEX_3);
glDisable(GL_MAP2_VERTEX_4);
glDisable(GL_MAP2_INDEX);
glDisable(GL_MAP2_COLOR_4);
glDisable(GL_MAP2_NORMAL);
glDisable(GL_MAP2_TEXTURE_COORD_1);
glDisable(GL_MAP2_TEXTURE_COORD_2);
glDisable(GL_MAP2_TEXTURE_COORD_3);
glDisable(GL_MAP2_TEXTURE_COORD_4);
/* glDisable(GL_MAP1_VERTEX_3);
glDisable(GL_MAP1_VERTEX_4);
glDisable(GL_MAP1_INDEX);
glDisable(GL_MAP1_COLOR_4);
glDisable(GL_MAP1_NORMAL);
glDisable(GL_MAP1_TEXTURE_COORD_1);
glDisable(GL_MAP1_TEXTURE_COORD_2);
glDisable(GL_MAP1_TEXTURE_COORD_3);
glDisable(GL_MAP1_TEXTURE_COORD_4);*/
do_nurbs_surface(nobj);
glPopAttrib();
break;
default:
call_user_error(nobj, GLU_NURBS_ERROR8);
}
nobj->nurbs_type = GLU_NURBS_NONE;
}
void GLAPIENTRY
gluNurbsSurface(GLUnurbsObj * nobj,
GLint sknot_count, GLfloat * sknot,
GLint tknot_count, GLfloat * tknot,
GLint s_stride, GLint t_stride,
GLfloat * ctrlarray, GLint sorder, GLint torder, GLenum type)
{
if (nobj->nurbs_type == GLU_NURBS_NO_TRIM
|| nobj->nurbs_type == GLU_NURBS_TRIM
|| nobj->nurbs_type == GLU_NURBS_TRIM_DONE) {
if (type == GL_MAP2_VERTEX_3 || type == GL_MAP2_VERTEX_4) {
call_user_error(nobj, GLU_NURBS_ERROR8);
return;
}
}
else if (nobj->nurbs_type != GLU_NURBS_SURFACE) {
call_user_error(nobj, GLU_NURBS_ERROR11);
return;
}
switch (type) {
case GL_MAP2_VERTEX_3:
case GL_MAP2_VERTEX_4:
nobj->surface.geom.sknot_count = sknot_count;
nobj->surface.geom.sknot = sknot;
nobj->surface.geom.tknot_count = tknot_count;
nobj->surface.geom.tknot = tknot;
nobj->surface.geom.s_stride = s_stride;
nobj->surface.geom.t_stride = t_stride;
nobj->surface.geom.ctrlarray = ctrlarray;
nobj->surface.geom.sorder = sorder;
nobj->surface.geom.torder = torder;
nobj->surface.geom.type = type;
nobj->nurbs_type = GLU_NURBS_NO_TRIM;
break;
case GL_MAP2_INDEX:
case GL_MAP2_COLOR_4:
nobj->surface.color.sknot_count = sknot_count;
nobj->surface.color.sknot = sknot;
nobj->surface.color.tknot_count = tknot_count;
nobj->surface.color.tknot = tknot;
nobj->surface.color.s_stride = s_stride;
nobj->surface.color.t_stride = t_stride;
nobj->surface.color.ctrlarray = ctrlarray;
nobj->surface.color.sorder = sorder;
nobj->surface.color.torder = torder;
nobj->surface.color.type = type;
break;
case GL_MAP2_NORMAL:
nobj->surface.normal.sknot_count = sknot_count;
nobj->surface.normal.sknot = sknot;
nobj->surface.normal.tknot_count = tknot_count;
nobj->surface.normal.tknot = tknot;
nobj->surface.normal.s_stride = s_stride;
nobj->surface.normal.t_stride = t_stride;
nobj->surface.normal.ctrlarray = ctrlarray;
nobj->surface.normal.sorder = sorder;
nobj->surface.normal.torder = torder;
nobj->surface.normal.type = type;
break;
case GL_MAP2_TEXTURE_COORD_1:
case GL_MAP2_TEXTURE_COORD_2:
case GL_MAP2_TEXTURE_COORD_3:
case GL_MAP2_TEXTURE_COORD_4:
nobj->surface.texture.sknot_count = sknot_count;
nobj->surface.texture.sknot = sknot;
nobj->surface.texture.tknot_count = tknot_count;
nobj->surface.texture.tknot = tknot;
nobj->surface.texture.s_stride = s_stride;
nobj->surface.texture.t_stride = t_stride;
nobj->surface.texture.ctrlarray = ctrlarray;
nobj->surface.texture.sorder = sorder;
nobj->surface.texture.torder = torder;
nobj->surface.texture.type = type;
break;
default:
call_user_error(nobj, GLU_INVALID_ENUM);
}
}
void GLAPIENTRY
gluNurbsCallback(GLUnurbsObj * nobj, GLenum which, void (GLCALLBACK * fn) ())
{
nobj->error_callback = (void (GLCALLBACKPCAST) (GLenum)) fn;
if (which != GLU_ERROR)
call_user_error(nobj, GLU_INVALID_ENUM);
}
void GLAPIENTRY
gluBeginTrim(GLUnurbsObj * nobj)
{
#if 0
nurbs_trim *ptr;
#endif
if (nobj->nurbs_type != GLU_NURBS_TRIM_DONE)
if (nobj->nurbs_type != GLU_NURBS_NO_TRIM) {
call_user_error(nobj, GLU_NURBS_ERROR15);
return;
}
nobj->nurbs_type = GLU_NURBS_TRIM;
fprintf(stderr, "NURBS - trimming not supported yet\n");
#if 0
if ((ptr = (nurbs_trim *) malloc(sizeof(nurbs_trim))) == NULL) {
call_user_error(nobj, GLU_OUT_OF_MEMORY);
return;
}
if (nobj->trim) {
nurbs_trim *tmp_ptr;
for (tmp_ptr = nobj->trim; tmp_ptr->next; tmp_ptr = tmp_ptr->next);
tmp_ptr->next = ptr;
}
else
nobj->trim = ptr;
ptr->trim_loop = NULL;
ptr->segments = NULL;
ptr->next = NULL;
#endif
}
void GLAPIENTRY
gluPwlCurve(GLUnurbsObj * nobj, GLint count, GLfloat * array, GLint stride,
GLenum type)
{
#if 0
nurbs_trim *ptr1;
trim_list *ptr2;
#endif
if (nobj->nurbs_type == GLU_NURBS_CURVE) {
call_user_error(nobj, GLU_NURBS_ERROR9);
return;
}
if (nobj->nurbs_type == GLU_NURBS_NONE) {
call_user_error(nobj, GLU_NURBS_ERROR19);
return;
}
if (type != GLU_MAP1_TRIM_2 && type != GLU_MAP1_TRIM_3) {
call_user_error(nobj, GLU_NURBS_ERROR14);
return;
}
#if 0
for (ptr1 = nobj->trim; ptr1->next; ptr1 = ptr1->next);
if (ptr1->trim_loop) {
for (ptr2 = ptr1->trim_loop; ptr2->next; ptr2 = ptr2->next);
if ((ptr2->next = (trim_list *) malloc(sizeof(trim_list))) == NULL) {
call_user_error(nobj, GLU_OUT_OF_MEMORY);
return;
}
ptr2 = ptr2->next;
}
else {
if ((ptr2 = (trim_list *) malloc(sizeof(trim_list))) == NULL) {
call_user_error(nobj, GLU_OUT_OF_MEMORY);
return;
}
ptr1->trim_loop = ptr2;
}
ptr2->trim_type = GLU_TRIM_PWL;
ptr2->curve.pwl_curve.pt_count = count;
ptr2->curve.pwl_curve.ctrlarray = array;
ptr2->curve.pwl_curve.stride = stride;
ptr2->curve.pwl_curve.dim = (type == GLU_MAP1_TRIM_2 ? 2 : 3);
ptr2->curve.pwl_curve.type = type;
ptr2->next = NULL;
#endif
}
void GLAPIENTRY
gluEndTrim(GLUnurbsObj * nobj)
{
if (nobj->nurbs_type != GLU_NURBS_TRIM) {
call_user_error(nobj, GLU_NURBS_ERROR17);
return;
}
nobj->nurbs_type = GLU_NURBS_TRIM_DONE;
}

View File

@@ -1,252 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifndef NURBS_H
#define NURBS_H
#define EPSILON 1e-06 /* epsilon for double precision compares */
typedef enum
{
GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM,
GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE
}
GLU_nurbs_enum;
typedef enum
{
GLU_TRIM_NURBS, GLU_TRIM_PWL
}
GLU_trim_enum;
typedef struct
{
GLint sknot_count;
GLfloat *sknot;
GLint tknot_count;
GLfloat *tknot;
GLint s_stride;
GLint t_stride;
GLfloat *ctrlarray;
GLint sorder;
GLint torder;
GLint dim;
GLenum type;
}
surface_attribs;
typedef struct
{
surface_attribs geom;
surface_attribs color;
surface_attribs texture;
surface_attribs normal;
}
nurbs_surface;
typedef struct
{
GLint knot_count;
GLfloat *knot;
GLint stride;
GLfloat *ctrlarray;
GLint order;
GLint dim;
GLenum type;
}
curve_attribs;
typedef struct
{
GLint pt_count;
GLfloat *ctrlarray;
GLint stride;
GLint dim;
GLenum type;
}
pwl_curve_attribs;
typedef struct
{
curve_attribs geom;
curve_attribs color;
curve_attribs texture;
curve_attribs normal;
}
nurbs_curve;
typedef struct trim_list_str
{
GLU_trim_enum trim_type;
union
{
pwl_curve_attribs pwl_curve;
curve_attribs nurbs_curve;
}
curve;
struct trim_list_str *next;
}
trim_list;
typedef struct seg_trim_str
{
GLfloat *points;
GLint pt_cnt, seg_array_len;
struct seg_trim_str *next;
}
trim_segments;
typedef struct nurbs_trim_str
{
trim_list *trim_loop;
trim_segments *segments;
struct nurbs_trim_str *next;
}
nurbs_trim;
typedef struct
{
GLfloat model[16], proj[16], viewport[4];
}
culling_and_sampling_str;
struct GLUnurbs
{
GLboolean culling;
GLenum error;
void (GLCALLBACK * error_callback) (GLenum err);
GLenum display_mode;
GLU_nurbs_enum nurbs_type;
GLboolean auto_load_matrix;
culling_and_sampling_str sampling_matrices;
GLenum sampling_method;
GLfloat sampling_tolerance;
GLfloat parametric_tolerance;
GLint u_step, v_step;
nurbs_surface surface;
nurbs_curve curve;
nurbs_trim *trim;
};
typedef struct
{
GLfloat *knot;
GLint nknots;
GLfloat *unified_knot;
GLint unified_nknots;
GLint order;
GLint t_min, t_max;
GLint delta_nknots;
GLboolean open_at_begin, open_at_end;
GLfloat *new_knot;
GLfloat *alpha;
}
knot_str_type;
typedef struct
{
GLfloat *geom_ctrl;
GLint geom_s_stride, geom_t_stride;
GLfloat **geom_offsets;
GLint geom_s_pt_cnt, geom_t_pt_cnt;
GLfloat *color_ctrl;
GLint color_s_stride, color_t_stride;
GLfloat **color_offsets;
GLint color_s_pt_cnt, color_t_pt_cnt;
GLfloat *normal_ctrl;
GLint normal_s_stride, normal_t_stride;
GLfloat **normal_offsets;
GLint normal_s_pt_cnt, normal_t_pt_cnt;
GLfloat *texture_ctrl;
GLint texture_s_stride, texture_t_stride;
GLfloat **texture_offsets;
GLint texture_s_pt_cnt, texture_t_pt_cnt;
GLint s_bezier_cnt, t_bezier_cnt;
}
new_ctrl_type;
extern void call_user_error(GLUnurbsObj * nobj, GLenum error);
extern GLenum test_knot(GLint nknots, GLfloat * knot, GLint order);
extern GLenum explode_knot(knot_str_type * the_knot);
extern GLenum calc_alphas(knot_str_type * the_knot);
extern GLenum calc_new_ctrl_pts(GLfloat * ctrl, GLint stride,
knot_str_type * the_knot, GLint dim,
GLfloat ** new_ctrl, GLint * ncontrol);
extern GLenum glu_do_sampling_crv(GLUnurbsObj * nobj, GLfloat * new_ctrl,
GLint n_ctrl, GLint order, GLint dim,
GLint ** factors);
extern GLenum glu_do_sampling_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLenum glu_do_sampling_uv(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLenum glu_do_sampling_param_3D(GLUnurbsObj * nobj,
new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLboolean fine_culling_test_2D(GLUnurbsObj * nobj, GLfloat * ctrl,
GLint n_ctrl, GLint stride, GLint dim);
extern GLboolean fine_culling_test_3D(GLUnurbsObj * nobj, GLfloat * ctrl,
GLint s_n_ctrl, GLint t_n_ctrl,
GLint s_stride, GLint t_stride,
GLint dim);
extern void do_nurbs_curve(GLUnurbsObj * nobj);
extern void do_nurbs_surface(GLUnurbsObj * nobj);
extern GLenum patch_trimming(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
GLint * sfactors, GLint * tfactors);
extern void collect_unified_knot(knot_str_type * dest, knot_str_type * src,
GLfloat maximal_min_knot,
GLfloat minimal_max_knot);
extern GLenum select_knot_working_range(GLUnurbsObj * nobj,
knot_str_type * geom_knot,
knot_str_type * color_knot,
knot_str_type * normal_knot,
knot_str_type * texture_knot);
extern void free_unified_knots(knot_str_type * geom_knot,
knot_str_type * color_knot,
knot_str_type * normal_knot,
knot_str_type * texture_knot);
#endif

View File

@@ -1,444 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "gluP.h"
#include "nurbs.h"
#endif
static int
get_curve_dim(GLenum type)
{
switch (type) {
case GL_MAP1_VERTEX_3:
return 3;
case GL_MAP1_VERTEX_4:
return 4;
case GL_MAP1_INDEX:
return 1;
case GL_MAP1_COLOR_4:
return 4;
case GL_MAP1_NORMAL:
return 3;
case GL_MAP1_TEXTURE_COORD_1:
return 1;
case GL_MAP1_TEXTURE_COORD_2:
return 2;
case GL_MAP1_TEXTURE_COORD_3:
return 3;
case GL_MAP1_TEXTURE_COORD_4:
return 4;
default:
abort(); /* TODO: is this OK? */
}
return 0; /*never get here */
}
static GLenum
test_nurbs_curve(GLUnurbsObj * nobj, curve_attribs * attribs)
{
GLenum err;
GLint tmp_int;
if (attribs->order < 0) {
call_user_error(nobj, GLU_INVALID_VALUE);
return GLU_ERROR;
}
glGetIntegerv(GL_MAX_EVAL_ORDER, &tmp_int);
if (attribs->order > tmp_int || attribs->order < 2) {
call_user_error(nobj, GLU_NURBS_ERROR1);
return GLU_ERROR;
}
if (attribs->knot_count < attribs->order + 2) {
call_user_error(nobj, GLU_NURBS_ERROR2);
return GLU_ERROR;
}
if (attribs->stride < 0) {
call_user_error(nobj, GLU_NURBS_ERROR34);
return GLU_ERROR;
}
if (attribs->knot == NULL || attribs->ctrlarray == NULL) {
call_user_error(nobj, GLU_NURBS_ERROR36);
return GLU_ERROR;
}
if ((err = test_knot(attribs->knot_count, attribs->knot, attribs->order))
!= GLU_NO_ERROR) {
call_user_error(nobj, err);
return GLU_ERROR;
}
return GLU_NO_ERROR;
}
static GLenum
test_nurbs_curves(GLUnurbsObj * nobj)
{
/* test the geometric data */
if (test_nurbs_curve(nobj, &(nobj->curve.geom)) != GLU_NO_ERROR)
return GLU_ERROR;
/* now test the attributive data */
/* color */
if (nobj->curve.color.type != GLU_INVALID_ENUM)
if (test_nurbs_curve(nobj, &(nobj->curve.color)) != GLU_NO_ERROR)
return GLU_ERROR;
/* normal */
if (nobj->curve.normal.type != GLU_INVALID_ENUM)
if (test_nurbs_curve(nobj, &(nobj->curve.normal)) != GLU_NO_ERROR)
return GLU_ERROR;
/* texture */
if (nobj->curve.texture.type != GLU_INVALID_ENUM)
if (test_nurbs_curve(nobj, &(nobj->curve.texture)) != GLU_NO_ERROR)
return GLU_ERROR;
return GLU_NO_ERROR;
}
/* prepare the knot information structures */
static GLenum
fill_knot_structures(GLUnurbsObj * nobj, knot_str_type * geom_knot,
knot_str_type * color_knot, knot_str_type * normal_knot,
knot_str_type * texture_knot)
{
GLint order;
GLfloat *knot;
GLint nknots;
GLint t_min, t_max;
geom_knot->unified_knot = NULL;
knot = geom_knot->knot = nobj->curve.geom.knot;
nknots = geom_knot->nknots = nobj->curve.geom.knot_count;
order = geom_knot->order = nobj->curve.geom.order;
geom_knot->delta_nknots = 0;
t_min = geom_knot->t_min = order - 1;
t_max = geom_knot->t_max = nknots - order;
if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
call_user_error(nobj, GLU_NURBS_ERROR3);
return GLU_ERROR;
}
if (fabs(knot[0] - knot[t_min]) < EPSILON) {
/* knot open at beggining */
geom_knot->open_at_begin = GL_TRUE;
}
else
geom_knot->open_at_begin = GL_FALSE;
if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
/* knot open at end */
geom_knot->open_at_end = GL_TRUE;
}
else
geom_knot->open_at_end = GL_FALSE;
if (nobj->curve.color.type != GLU_INVALID_ENUM) {
color_knot->unified_knot = (GLfloat *) 1;
knot = color_knot->knot = nobj->curve.color.knot;
nknots = color_knot->nknots = nobj->curve.color.knot_count;
order = color_knot->order = nobj->curve.color.order;
color_knot->delta_nknots = 0;
t_min = color_knot->t_min = order - 1;
t_max = color_knot->t_max = nknots - order;
if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
call_user_error(nobj, GLU_NURBS_ERROR3);
return GLU_ERROR;
}
if (fabs(knot[0] - knot[t_min]) < EPSILON) {
/* knot open at beggining */
color_knot->open_at_begin = GL_TRUE;
}
else
color_knot->open_at_begin = GL_FALSE;
if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
/* knot open at end */
color_knot->open_at_end = GL_TRUE;
}
else
color_knot->open_at_end = GL_FALSE;
}
else
color_knot->unified_knot = NULL;
if (nobj->curve.normal.type != GLU_INVALID_ENUM) {
normal_knot->unified_knot = (GLfloat *) 1;
knot = normal_knot->knot = nobj->curve.normal.knot;
nknots = normal_knot->nknots = nobj->curve.normal.knot_count;
order = normal_knot->order = nobj->curve.normal.order;
normal_knot->delta_nknots = 0;
t_min = normal_knot->t_min = order - 1;
t_max = normal_knot->t_max = nknots - order;
if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
call_user_error(nobj, GLU_NURBS_ERROR3);
return GLU_ERROR;
}
if (fabs(knot[0] - knot[t_min]) < EPSILON) {
/* knot open at beggining */
normal_knot->open_at_begin = GL_TRUE;
}
else
normal_knot->open_at_begin = GL_FALSE;
if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
/* knot open at end */
normal_knot->open_at_end = GL_TRUE;
}
else
normal_knot->open_at_end = GL_FALSE;
}
else
normal_knot->unified_knot = NULL;
if (nobj->curve.texture.type != GLU_INVALID_ENUM) {
texture_knot->unified_knot = (GLfloat *) 1;
knot = texture_knot->knot = nobj->curve.texture.knot;
nknots = texture_knot->nknots = nobj->curve.texture.knot_count;
order = texture_knot->order = nobj->curve.texture.order;
texture_knot->delta_nknots = 0;
t_min = texture_knot->t_min = order - 1;
t_max = texture_knot->t_max = nknots - order;
if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
call_user_error(nobj, GLU_NURBS_ERROR3);
return GLU_ERROR;
}
if (fabs(knot[0] - knot[t_min]) < EPSILON) {
/* knot open at beggining */
texture_knot->open_at_begin = GL_TRUE;
}
else
texture_knot->open_at_begin = GL_FALSE;
if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
/* knot open at end */
texture_knot->open_at_end = GL_TRUE;
}
else
texture_knot->open_at_end = GL_FALSE;
}
else
texture_knot->unified_knot = NULL;
return GLU_NO_ERROR;
}
/* covert the NURBS curve into a series of adjacent Bezier curves */
static GLenum
convert_curve(knot_str_type * the_knot, curve_attribs * attrib,
GLfloat ** new_ctrl, GLint * ncontrol)
{
GLenum err;
if ((err = explode_knot(the_knot)) != GLU_NO_ERROR) {
if (the_knot->unified_knot) {
free(the_knot->unified_knot);
the_knot->unified_knot = NULL;
}
return err;
}
if (the_knot->unified_knot) {
free(the_knot->unified_knot);
the_knot->unified_knot = NULL;
}
if ((err = calc_alphas(the_knot)) != GLU_NO_ERROR) {
free(the_knot->new_knot);
return err;
}
free(the_knot->new_knot);
if ((err = calc_new_ctrl_pts(attrib->ctrlarray, attrib->stride, the_knot,
attrib->dim, new_ctrl, ncontrol))
!= GLU_NO_ERROR) {
free(the_knot->alpha);
return err;
}
free(the_knot->alpha);
return GLU_NO_ERROR;
}
/* covert curves - geometry and possible attribute ones into equivalent */
/* sequence of adjacent Bezier curves */
static GLenum
convert_curves(GLUnurbsObj * nobj, GLfloat ** new_geom_ctrl,
GLint * ncontrol, GLfloat ** new_color_ctrl,
GLfloat ** new_normal_ctrl, GLfloat ** new_texture_ctrl)
{
knot_str_type geom_knot, color_knot, normal_knot, texture_knot;
GLint junk;
GLenum err;
*new_color_ctrl = *new_normal_ctrl = *new_texture_ctrl = NULL;
if (fill_knot_structures(nobj, &geom_knot, &color_knot, &normal_knot,
&texture_knot) != GLU_NO_ERROR)
return GLU_ERROR;
/* unify knots - all knots should have the same number of working */
/* ranges */
if (
(err =
select_knot_working_range(nobj, &geom_knot, &color_knot, &normal_knot,
&texture_knot)) != GLU_NO_ERROR) {
return err;
}
/* convert the geometry curve */
nobj->curve.geom.dim = get_curve_dim(nobj->curve.geom.type);
if ((err = convert_curve(&geom_knot, &(nobj->curve.geom), new_geom_ctrl,
ncontrol)) != GLU_NO_ERROR) {
free_unified_knots(&geom_knot, &color_knot, &normal_knot,
&texture_knot);
call_user_error(nobj, err);
return err;
}
/* if additional attributive curves are given convert them as well */
if (color_knot.unified_knot) {
nobj->curve.color.dim = get_curve_dim(nobj->curve.color.type);
if ((err = convert_curve(&color_knot, &(nobj->curve.color),
new_color_ctrl, &junk)) != GLU_NO_ERROR) {
free_unified_knots(&geom_knot, &color_knot, &normal_knot,
&texture_knot);
free(*new_geom_ctrl);
call_user_error(nobj, err);
return err;
}
}
if (normal_knot.unified_knot) {
nobj->curve.normal.dim = get_curve_dim(nobj->curve.normal.type);
if ((err = convert_curve(&normal_knot, &(nobj->curve.normal),
new_normal_ctrl, &junk)) != GLU_NO_ERROR) {
free_unified_knots(&geom_knot, &color_knot, &normal_knot,
&texture_knot);
free(*new_geom_ctrl);
if (*new_color_ctrl)
free(*new_color_ctrl);
call_user_error(nobj, err);
return err;
}
}
if (texture_knot.unified_knot) {
nobj->curve.texture.dim = get_curve_dim(nobj->curve.texture.type);
if ((err = convert_curve(&texture_knot, &(nobj->curve.texture),
new_texture_ctrl, &junk)) != GLU_NO_ERROR) {
free_unified_knots(&geom_knot, &color_knot, &normal_knot,
&texture_knot);
free(*new_geom_ctrl);
if (*new_color_ctrl)
free(*new_color_ctrl);
if (*new_normal_ctrl)
free(*new_normal_ctrl);
call_user_error(nobj, err);
return err;
}
}
return GLU_NO_ERROR;
}
/* main NURBS curve procedure */
void
do_nurbs_curve(GLUnurbsObj * nobj)
{
GLint geom_order, color_order = 0, normal_order = 0, texture_order = 0;
GLenum geom_type;
GLint n_ctrl;
GLfloat *new_geom_ctrl, *new_color_ctrl, *new_normal_ctrl,
*new_texture_ctrl;
GLfloat *geom_ctrl = 0, *color_ctrl = 0, *normal_ctrl = 0, *texture_ctrl = 0;
GLint *factors;
GLint i, j;
GLint geom_dim, color_dim = 0, normal_dim = 0, texture_dim = 0;
/* test the user supplied data */
if (test_nurbs_curves(nobj) != GLU_NO_ERROR)
return;
if (convert_curves(nobj, &new_geom_ctrl, &n_ctrl, &new_color_ctrl,
&new_normal_ctrl, &new_texture_ctrl) != GLU_NO_ERROR)
return;
geom_order = nobj->curve.geom.order;
geom_type = nobj->curve.geom.type;
geom_dim = nobj->curve.geom.dim;
if (glu_do_sampling_crv(nobj, new_geom_ctrl, n_ctrl, geom_order, geom_dim,
&factors) != GLU_NO_ERROR) {
free(new_geom_ctrl);
if (new_color_ctrl)
free(new_color_ctrl);
if (new_normal_ctrl)
free(new_normal_ctrl);
if (new_texture_ctrl)
free(new_texture_ctrl);
return;
}
glEnable(geom_type);
if (new_color_ctrl) {
glEnable(nobj->curve.color.type);
color_dim = nobj->curve.color.dim;
color_ctrl = new_color_ctrl;
color_order = nobj->curve.color.order;
}
if (new_normal_ctrl) {
glEnable(nobj->curve.normal.type);
normal_dim = nobj->curve.normal.dim;
normal_ctrl = new_normal_ctrl;
normal_order = nobj->curve.normal.order;
}
if (new_texture_ctrl) {
glEnable(nobj->curve.texture.type);
texture_dim = nobj->curve.texture.dim;
texture_ctrl = new_texture_ctrl;
texture_order = nobj->curve.texture.order;
}
for (i = 0, j = 0, geom_ctrl = new_geom_ctrl;
i < n_ctrl; i += geom_order, j++, geom_ctrl += geom_order * geom_dim) {
if (fine_culling_test_2D
(nobj, geom_ctrl, geom_order, geom_dim, geom_dim)) {
color_ctrl += color_order * color_dim;
normal_ctrl += normal_order * normal_dim;
texture_ctrl += texture_order * texture_dim;
continue;
}
glMap1f(geom_type, 0.0, 1.0, geom_dim, geom_order, geom_ctrl);
if (new_color_ctrl) {
glMap1f(nobj->curve.color.type, 0.0, 1.0, color_dim,
color_order, color_ctrl);
color_ctrl += color_order * color_dim;
}
if (new_normal_ctrl) {
glMap1f(nobj->curve.normal.type, 0.0, 1.0, normal_dim,
normal_order, normal_ctrl);
normal_ctrl += normal_order * normal_dim;
}
if (new_texture_ctrl) {
glMap1f(nobj->curve.texture.type, 0.0, 1.0, texture_dim,
texture_order, texture_ctrl);
texture_ctrl += texture_order * texture_dim;
}
glMapGrid1f(factors[j], 0.0, 1.0);
glEvalMesh1(GL_LINE, 0, factors[j]);
}
free(new_geom_ctrl);
free(factors);
if (new_color_ctrl)
free(new_color_ctrl);
if (new_normal_ctrl)
free(new_normal_ctrl);
if (new_texture_ctrl)
free(new_texture_ctrl);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,937 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "gluP.h"
#include "tess.h"
#endif
static GLenum store_polygon_as_contour(GLUtriangulatorObj *);
static void free_current_polygon(tess_polygon *);
static void prepare_projection_info(GLUtriangulatorObj *);
static GLdouble twice_the_polygon_area(tess_vertex *, tess_vertex *);
static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *);
void tess_find_contour_hierarchies(GLUtriangulatorObj *);
static GLenum test_for_overlapping_contours(GLUtriangulatorObj *);
static GLenum contours_overlap(tess_contour *, tess_polygon *);
static GLenum is_contour_contained_in(tess_contour *, tess_contour *);
static void add_new_exterior(GLUtriangulatorObj *, tess_contour *);
static void add_new_interior(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static void add_interior_with_hierarchy_check(GLUtriangulatorObj *,
tess_contour *, tess_contour *);
static void reverse_hierarchy_and_add_exterior(GLUtriangulatorObj *,
tess_contour *,
tess_contour *);
static GLboolean point_in_polygon(tess_contour *, GLdouble, GLdouble);
static void shift_interior_to_exterior(GLUtriangulatorObj *, tess_contour *);
static void add_exterior_with_check(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static GLenum cut_out_hole(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static GLenum merge_hole_with_contour(GLUtriangulatorObj *,
tess_contour *, tess_contour *,
tess_vertex *, tess_vertex *);
static GLenum
find_normal(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *va, *vb, *vc;
GLdouble A, B, C;
GLdouble A0, A1, A2, B0, B1, B2;
va = polygon->vertices;
vb = va->next;
A0 = vb->location[0] - va->location[0];
A1 = vb->location[1] - va->location[1];
A2 = vb->location[2] - va->location[2];
for (vc = vb->next; vc != va; vc = vc->next) {
B0 = vc->location[0] - va->location[0];
B1 = vc->location[1] - va->location[1];
B2 = vc->location[2] - va->location[2];
A = A1 * B2 - A2 * B1;
B = A2 * B0 - A0 * B2;
C = A0 * B1 - A1 * B0;
if (fabs(A) > EPSILON || fabs(B) > EPSILON || fabs(C) > EPSILON) {
polygon->A = A;
polygon->B = B;
polygon->C = C;
polygon->D =
-A * va->location[0] - B * va->location[1] - C * va->location[2];
return GLU_NO_ERROR;
}
}
tess_call_user_error(tobj, GLU_TESS_ERROR7);
return GLU_ERROR;
}
void
tess_test_polygon(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
/* any vertices defined? */
if (polygon->vertex_cnt < 3) {
free_current_polygon(polygon);
return;
}
/* wrap pointers */
polygon->last_vertex->next = polygon->vertices;
polygon->vertices->previous = polygon->last_vertex;
/* determine the normal */
if (find_normal(tobj) == GLU_ERROR)
return;
/* compare the normals of previously defined contours and this one */
/* first contour define ? */
if (tobj->contours == NULL) {
tobj->A = polygon->A;
tobj->B = polygon->B;
tobj->C = polygon->C;
tobj->D = polygon->D;
/* determine the best projection to use */
if (fabs(polygon->A) > fabs(polygon->B))
if (fabs(polygon->A) > fabs(polygon->C))
tobj->projection = OYZ;
else
tobj->projection = OXY;
else if (fabs(polygon->B) > fabs(polygon->C))
tobj->projection = OXZ;
else
tobj->projection = OXY;
}
else {
GLdouble a[3], b[3];
tess_vertex *vertex = polygon->vertices;
a[0] = tobj->A;
a[1] = tobj->B;
a[2] = tobj->C;
b[0] = polygon->A;
b[1] = polygon->B;
b[2] = polygon->C;
/* compare the normals */
if (fabs(a[1] * b[2] - a[2] * b[1]) > EPSILON ||
fabs(a[2] * b[0] - a[0] * b[2]) > EPSILON ||
fabs(a[0] * b[1] - a[1] * b[0]) > EPSILON) {
/* not coplanar */
tess_call_user_error(tobj, GLU_TESS_ERROR9);
return;
}
/* the normals are parallel - test for plane equation */
if (fabs(a[0] * vertex->location[0] + a[1] * vertex->location[1] +
a[2] * vertex->location[2] + tobj->D) > EPSILON) {
/* not the same plane */
tess_call_user_error(tobj, GLU_TESS_ERROR9);
return;
}
}
prepare_projection_info(tobj);
if (verify_edge_vertex_intersections(tobj) == GLU_ERROR)
return;
if (test_for_overlapping_contours(tobj) == GLU_ERROR)
return;
if (store_polygon_as_contour(tobj) == GLU_ERROR)
return;
}
static GLenum
test_for_overlapping_contours(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
tess_polygon *polygon;
polygon = tobj->current_polygon;
for (contour = tobj->contours; contour != NULL; contour = contour->next)
if (contours_overlap(contour, polygon) != GLU_NO_ERROR) {
tess_call_user_error(tobj, GLU_TESS_ERROR5);
return GLU_ERROR;
}
return GLU_NO_ERROR;
}
static GLenum
store_polygon_as_contour(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_contour *contour = tobj->contours;
/* the first contour defined */
if (contour == NULL) {
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
free_current_polygon(polygon);
return GLU_ERROR;
}
tobj->contours = tobj->last_contour = contour;
contour->next = contour->previous = NULL;
}
else {
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
free_current_polygon(polygon);
return GLU_ERROR;
}
contour->previous = tobj->last_contour;
tobj->last_contour->next = contour;
tobj->last_contour = contour;
contour->next = NULL;
}
/* mark all vertices in new contour as not special */
/* and all are boundary edges */
{
tess_vertex *vertex;
GLuint vertex_cnt, i;
for (vertex = polygon->vertices, i = 0, vertex_cnt =
polygon->vertex_cnt; i < vertex_cnt; vertex = vertex->next, i++) {
vertex->shadow_vertex = NULL;
vertex->edge_flag = GL_TRUE;
}
}
contour->vertex_cnt = polygon->vertex_cnt;
contour->area = polygon->area;
contour->orientation = polygon->orientation;
contour->type = GLU_UNKNOWN;
contour->vertices = polygon->vertices;
contour->last_vertex = polygon->last_vertex;
polygon->vertices = polygon->last_vertex = NULL;
polygon->vertex_cnt = 0;
++(tobj->contour_cnt);
return GLU_NO_ERROR;
}
static void
free_current_polygon(tess_polygon * polygon)
{
tess_vertex *vertex, *vertex_tmp;
GLuint i;
/* free current_polygon structures */
for (vertex = polygon->vertices, i = 0; i < polygon->vertex_cnt; i++) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
polygon->vertices = polygon->last_vertex = NULL;
polygon->vertex_cnt = 0;
}
static void
prepare_projection_info(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *vertex, *last_vertex_ptr;
GLdouble area;
last_vertex_ptr = polygon->last_vertex;
switch (tobj->projection) {
case OXY:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[0];
vertex->y = vertex->location[1];
}
last_vertex_ptr->x = last_vertex_ptr->location[0];
last_vertex_ptr->y = last_vertex_ptr->location[1];
break;
case OXZ:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[0];
vertex->y = vertex->location[2];
}
last_vertex_ptr->x = last_vertex_ptr->location[0];
last_vertex_ptr->y = last_vertex_ptr->location[2];
break;
case OYZ:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[1];
vertex->y = vertex->location[2];
}
last_vertex_ptr->x = last_vertex_ptr->location[1];
last_vertex_ptr->y = last_vertex_ptr->location[2];
break;
}
area = twice_the_polygon_area(polygon->vertices, polygon->last_vertex);
if (area >= 0.0) {
polygon->orientation = GLU_CCW;
polygon->area = area;
}
else {
polygon->orientation = GLU_CW;
polygon->area = -area;
}
}
static GLdouble
twice_the_polygon_area(tess_vertex * vertex, tess_vertex * last_vertex)
{
tess_vertex *next;
GLdouble area, x, y;
area = 0.0;
x = vertex->x;
y = vertex->y;
vertex = vertex->next;
for (; vertex != last_vertex; vertex = vertex->next) {
next = vertex->next;
area +=
(vertex->x - x) * (next->y - y) - (vertex->y - y) * (next->x - x);
}
return area;
}
/* test if edges ab and cd intersect */
/* if not return GLU_NO_ERROR, else if cross return GLU_TESS_ERROR8, */
/* else if adjacent return GLU_TESS_ERROR4 */
static GLenum
edge_edge_intersect(tess_vertex * a,
tess_vertex * b, tess_vertex * c, tess_vertex * d)
{
GLdouble denom, r, s;
GLdouble xba, ydc, yba, xdc, yac, xac;
xba = b->x - a->x;
yba = b->y - a->y;
xdc = d->x - c->x;
ydc = d->y - c->y;
xac = a->x - c->x;
yac = a->y - c->y;
denom = xba * ydc - yba * xdc;
r = yac * xdc - xac * ydc;
/* parallel? */
if (fabs(denom) < EPSILON) {
if (fabs(r) < EPSILON) {
/* colinear */
if (fabs(xba) < EPSILON) {
/* compare the Y coordinate */
if (yba > 0.0) {
if (
(fabs(a->y - c->y) < EPSILON
&& fabs(c->y - b->y) < EPSILON)
|| (fabs(a->y - d->y) < EPSILON
&& fabs(d->y - b->y) <
EPSILON)) return GLU_TESS_ERROR4;
}
else {
if (
(fabs(b->y - c->y) < EPSILON
&& fabs(c->y - a->y) < EPSILON)
|| (fabs(b->y - d->y) < EPSILON
&& fabs(d->y - a->y) <
EPSILON)) return GLU_TESS_ERROR4;
}
}
else {
/* compare the X coordinate */
if (xba > 0.0) {
if (
(fabs(a->x - c->x) < EPSILON
&& fabs(c->x - b->x) < EPSILON)
|| (fabs(a->x - d->x) < EPSILON
&& fabs(d->x - b->x) <
EPSILON)) return GLU_TESS_ERROR4;
}
else {
if (
(fabs(b->x - c->x) < EPSILON
&& fabs(c->x - a->x) < EPSILON)
|| (fabs(b->x - d->x) < EPSILON
&& fabs(d->x - a->x) <
EPSILON)) return GLU_TESS_ERROR4;
}
}
}
return GLU_NO_ERROR;
}
r /= denom;
s = (yac * xba - xac * yba) / denom;
/* test if one vertex lies on other edge */
if (((fabs(r) < EPSILON || (r < 1.0 + EPSILON && r > 1.0 - EPSILON)) &&
s > -EPSILON && s < 1.0 + EPSILON) ||
((fabs(s) < EPSILON || (s < 1.0 + EPSILON && s > 1.0 - EPSILON)) &&
r > -EPSILON && r < 1.0 + EPSILON)) {
return GLU_TESS_ERROR4;
}
/* test for crossing */
if (r > -EPSILON && r < 1.0 + EPSILON && s > -EPSILON && s < 1.0 + EPSILON) {
return GLU_TESS_ERROR8;
}
return GLU_NO_ERROR;
}
static GLenum
verify_edge_vertex_intersections(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *vertex1, *last_vertex, *vertex2;
GLenum test;
last_vertex = polygon->last_vertex;
vertex1 = last_vertex;
for (vertex2 = vertex1->next->next;
vertex2->next != last_vertex; vertex2 = vertex2->next) {
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next);
if (test != GLU_NO_ERROR) {
tess_call_user_error(tobj, test);
return GLU_ERROR;
}
}
for (vertex1 = polygon->vertices;
vertex1->next->next != last_vertex; vertex1 = vertex1->next) {
for (vertex2 = vertex1->next->next;
vertex2 != last_vertex; vertex2 = vertex2->next) {
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next);
if (test != GLU_NO_ERROR) {
tess_call_user_error(tobj, test);
return GLU_ERROR;
}
}
}
return GLU_NO_ERROR;
}
static int
#ifdef WIN32
__cdecl
#endif
area_compare(const void *a, const void *b)
{
GLdouble area1, area2;
area1 = (*((tess_contour **) a))->area;
area2 = (*((tess_contour **) b))->area;
if (area1 < area2)
return 1;
if (area1 > area2)
return -1;
return 0;
}
void
tess_find_contour_hierarchies(GLUtriangulatorObj * tobj)
{
tess_contour **contours; /* dinamic array of pointers */
tess_contour *tmp_contour_ptr = tobj->contours;
GLuint cnt, i;
GLenum result;
GLboolean hierarchy_changed;
/* any contours? */
if (tobj->contour_cnt < 2) {
tobj->contours->type = GLU_EXTERIOR;
return;
}
if ((contours = (tess_contour **)
malloc(sizeof(tess_contour *) * (tobj->contour_cnt))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
for (tmp_contour_ptr = tobj->contours, cnt = 0;
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next)
contours[cnt++] = tmp_contour_ptr;
/* now sort the contours in decreasing area size order */
qsort((void *) contours, (size_t) cnt, (size_t) sizeof(tess_contour *),
area_compare);
/* we leave just the first contour - remove others from list */
tobj->contours = contours[0];
tobj->contours->next = tobj->contours->previous = NULL;
tobj->last_contour = tobj->contours;
tobj->contour_cnt = 1;
/* first contour is the one with greatest area */
/* must be EXTERIOR */
tobj->contours->type = GLU_EXTERIOR;
tmp_contour_ptr = tobj->contours;
/* now we play! */
for (i = 1; i < cnt; i++) {
hierarchy_changed = GL_FALSE;
for (tmp_contour_ptr = tobj->contours;
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next) {
if (tmp_contour_ptr->type == GLU_EXTERIOR) {
/* check if contour completely contained in EXTERIOR */
result = is_contour_contained_in(tmp_contour_ptr, contours[i]);
switch (result) {
case GLU_INTERIOR:
/* now we have to check if contour is inside interiors */
/* or not */
/* any interiors? */
if (tmp_contour_ptr->next != NULL &&
tmp_contour_ptr->next->type == GLU_INTERIOR) {
/* for all interior, check if inside any of them */
/* if not inside any of interiors, its another */
/* interior */
/* or it may contain some interiors, then change */
/* the contained interiors to exterior ones */
add_interior_with_hierarchy_check(tobj,
tmp_contour_ptr,
contours[i]);
}
else {
/* not in interior, add as new interior contour */
add_new_interior(tobj, tmp_contour_ptr, contours[i]);
}
hierarchy_changed = GL_TRUE;
break;
case GLU_EXTERIOR:
/* ooops, the marked as EXTERIOR (contours[i]) is */
/* actually an interior of tmp_contour_ptr */
/* reverse the local hierarchy */
reverse_hierarchy_and_add_exterior(tobj, tmp_contour_ptr,
contours[i]);
hierarchy_changed = GL_TRUE;
break;
case GLU_NO_ERROR:
break;
default:
abort();
}
}
if (hierarchy_changed)
break; /* break from for loop */
}
if (hierarchy_changed == GL_FALSE) {
/* disjoint with all contours, add to contour list */
add_new_exterior(tobj, contours[i]);
}
}
free(contours);
}
/* returns GLU_INTERIOR if inner is completey enclosed within outer */
/* returns GLU_EXTERIOR if outer is completely enclosed within inner */
/* returns GLU_NO_ERROR if contours are disjoint */
static GLenum
is_contour_contained_in(tess_contour * outer, tess_contour * inner)
{
GLenum relation_flag;
/* set relation_flag to relation of containment of first inner vertex */
/* regarding outer contour */
if (point_in_polygon(outer, inner->vertices->x, inner->vertices->y))
relation_flag = GLU_INTERIOR;
else
relation_flag = GLU_EXTERIOR;
if (relation_flag == GLU_INTERIOR)
return GLU_INTERIOR;
if (point_in_polygon(inner, outer->vertices->x, outer->vertices->y))
return GLU_EXTERIOR;
return GLU_NO_ERROR;
}
static GLboolean
point_in_polygon(tess_contour * contour, GLdouble x, GLdouble y)
{
tess_vertex *v1, *v2;
GLuint i, vertex_cnt;
GLdouble xp1, yp1, xp2, yp2;
GLboolean tst;
tst = GL_FALSE;
v1 = contour->vertices;
v2 = contour->vertices->previous;
for (i = 0, vertex_cnt = contour->vertex_cnt; i < vertex_cnt; i++) {
xp1 = v1->x;
yp1 = v1->y;
xp2 = v2->x;
yp2 = v2->y;
if ((((yp1 <= y) && (y < yp2)) || ((yp2 <= y) && (y < yp1))) &&
(x < (xp2 - xp1) * (y - yp1) / (yp2 - yp1) + xp1))
tst = (tst == GL_FALSE ? GL_TRUE : GL_FALSE);
v2 = v1;
v1 = v1->next;
}
return tst;
}
static GLenum
contours_overlap(tess_contour * contour, tess_polygon * polygon)
{
tess_vertex *vertex1, *vertex2;
GLuint vertex1_cnt, vertex2_cnt, i, j;
GLenum test;
vertex1 = contour->vertices;
vertex2 = polygon->vertices;
vertex1_cnt = contour->vertex_cnt;
vertex2_cnt = polygon->vertex_cnt;
for (i = 0; i < vertex1_cnt; vertex1 = vertex1->next, i++) {
for (j = 0; j < vertex2_cnt; vertex2 = vertex2->next, j++)
if ((test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next)) != GLU_NO_ERROR)
return test;
}
return GLU_NO_ERROR;
}
static void
add_new_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
{
contour->type = GLU_EXTERIOR;
contour->next = NULL;
contour->previous = tobj->last_contour;
tobj->last_contour->next = contour;
tobj->last_contour = contour;
}
static void
add_new_interior(GLUtriangulatorObj * tobj,
tess_contour * outer, tess_contour * contour)
{
contour->type = GLU_INTERIOR;
contour->next = outer->next;
contour->previous = outer;
if (outer->next != NULL)
outer->next->previous = contour;
outer->next = contour;
if (tobj->last_contour == outer)
tobj->last_contour = contour;
}
static void
add_interior_with_hierarchy_check(GLUtriangulatorObj * tobj,
tess_contour * outer,
tess_contour * contour)
{
tess_contour *ptr;
/* for all interiors of outer check if they are interior of contour */
/* if so, change that interior to exterior and move it of of the */
/* interior sequence */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
GLenum test;
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
ptr = ptr->next) {
test = is_contour_contained_in(ptr, contour);
switch (test) {
case GLU_INTERIOR:
/* contour is contained in one of the interiors */
/* check if possibly contained in other exteriors */
/* move ptr to first EXTERIOR */
for (; ptr != NULL && ptr->type == GLU_INTERIOR; ptr = ptr->next);
if (ptr == NULL)
/* another exterior */
add_new_exterior(tobj, contour);
else
add_exterior_with_check(tobj, ptr, contour);
return;
case GLU_EXTERIOR:
/* one of the interiors is contained in the contour */
/* change it to EXTERIOR, and shift it away from the */
/* interior sequence */
shift_interior_to_exterior(tobj, ptr);
break;
case GLU_NO_ERROR:
/* disjoint */
break;
default:
abort();
}
}
}
/* add contour to the interior sequence */
add_new_interior(tobj, outer, contour);
}
static void
reverse_hierarchy_and_add_exterior(GLUtriangulatorObj * tobj,
tess_contour * outer,
tess_contour * contour)
{
tess_contour *ptr;
/* reverse INTERIORS to EXTERIORS */
/* any INTERIORS? */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR)
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
ptr = ptr->next) ptr->type = GLU_EXTERIOR;
/* the outer now becomes inner */
outer->type = GLU_INTERIOR;
/* contour is the EXTERIOR */
contour->next = outer;
if (tobj->contours == outer) {
/* first contour beeing reversed */
contour->previous = NULL;
tobj->contours = contour;
}
else {
outer->previous->next = contour;
contour->previous = outer->previous;
}
outer->previous = contour;
}
static void
shift_interior_to_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
{
contour->previous->next = contour->next;
if (contour->next != NULL)
contour->next->previous = contour->previous;
else
tobj->last_contour = contour->previous;
}
static void
add_exterior_with_check(GLUtriangulatorObj * tobj,
tess_contour * outer, tess_contour * contour)
{
GLenum test;
/* this contour might be interior to further exteriors - check */
/* if not, just add as a new exterior */
for (; outer != NULL && outer->type == GLU_EXTERIOR; outer = outer->next) {
test = is_contour_contained_in(outer, contour);
switch (test) {
case GLU_INTERIOR:
/* now we have to check if contour is inside interiors */
/* or not */
/* any interiors? */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
/* for all interior, check if inside any of them */
/* if not inside any of interiors, its another */
/* interior */
/* or it may contain some interiors, then change */
/* the contained interiors to exterior ones */
add_interior_with_hierarchy_check(tobj, outer, contour);
}
else {
/* not in interior, add as new interior contour */
add_new_interior(tobj, outer, contour);
}
return;
case GLU_NO_ERROR:
/* disjoint */
break;
default:
abort();
}
}
/* add contour to the exterior sequence */
add_new_exterior(tobj, contour);
}
void
tess_handle_holes(GLUtriangulatorObj * tobj)
{
tess_contour *contour, *hole;
GLenum exterior_orientation;
/* verify hole orientation */
for (contour = tobj->contours; contour != NULL;) {
exterior_orientation = contour->orientation;
for (contour = contour->next;
contour != NULL && contour->type == GLU_INTERIOR;
contour = contour->next) {
if (contour->orientation == exterior_orientation) {
tess_call_user_error(tobj, GLU_TESS_ERROR5);
return;
}
}
}
/* now cut-out holes */
for (contour = tobj->contours; contour != NULL;) {
hole = contour->next;
while (hole != NULL && hole->type == GLU_INTERIOR) {
if (cut_out_hole(tobj, contour, hole) == GLU_ERROR)
return;
hole = contour->next;
}
contour = contour->next;
}
}
static GLenum
cut_out_hole(GLUtriangulatorObj * tobj,
tess_contour * contour, tess_contour * hole)
{
tess_contour *tmp_hole;
tess_vertex *v1, *v2, *tmp_vertex;
GLuint vertex1_cnt, vertex2_cnt, tmp_vertex_cnt;
GLuint i, j, k;
GLenum test = 0;
/* find an edge connecting contour and hole not intersecting any other */
/* edge belonging to either the contour or any of the other holes */
for (v1 = contour->vertices, vertex1_cnt = contour->vertex_cnt, i = 0;
i < vertex1_cnt; i++, v1 = v1->next) {
for (v2 = hole->vertices, vertex2_cnt = hole->vertex_cnt, j = 0;
j < vertex2_cnt; j++, v2 = v2->next) {
/* does edge (v1,v2) intersect any edge of contour */
for (tmp_vertex = contour->vertices, tmp_vertex_cnt =
contour->vertex_cnt, k = 0; k < tmp_vertex_cnt;
tmp_vertex = tmp_vertex->next, k++) {
/* skip edge tests for edges directly connected */
if (v1 == tmp_vertex || v1 == tmp_vertex->next)
continue;
test = edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test == GLU_NO_ERROR) {
/* does edge (v1,v2) intersect any edge of hole */
for (tmp_vertex = hole->vertices,
tmp_vertex_cnt = hole->vertex_cnt, k = 0;
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
/* skip edge tests for edges directly connected */
if (v2 == tmp_vertex || v2 == tmp_vertex->next)
continue;
test =
edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test == GLU_NO_ERROR) {
/* does edge (v1,v2) intersect any other hole? */
for (tmp_hole = hole->next;
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
tmp_hole = tmp_hole->next) {
/* does edge (v1,v2) intersect any edge of hole */
for (tmp_vertex = tmp_hole->vertices,
tmp_vertex_cnt = tmp_hole->vertex_cnt, k = 0;
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
test = edge_edge_intersect(v1, v2, tmp_vertex,
tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test != GLU_NO_ERROR)
break;
}
}
}
if (test == GLU_NO_ERROR) {
/* edge (v1,v2) is good for eliminating the hole */
if (merge_hole_with_contour(tobj, contour, hole, v1, v2)
== GLU_NO_ERROR)
return GLU_NO_ERROR;
else
return GLU_ERROR;
}
}
}
/* other holes are blocking all possible connections of hole */
/* with contour, we shift this hole as the last hole and retry */
for (tmp_hole = hole;
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
tmp_hole = tmp_hole->next);
contour->next = hole->next;
hole->next->previous = contour;
if (tmp_hole == NULL) {
/* last EXTERIOR contour, shift hole as last contour */
hole->next = NULL;
hole->previous = tobj->last_contour;
tobj->last_contour->next = hole;
tobj->last_contour = hole;
}
else {
tmp_hole->previous->next = hole;
hole->previous = tmp_hole->previous;
tmp_hole->previous = hole;
hole->next = tmp_hole;
}
hole = contour->next;
/* try once again - recurse */
return cut_out_hole(tobj, contour, hole);
}
static GLenum
merge_hole_with_contour(GLUtriangulatorObj * tobj,
tess_contour * contour,
tess_contour * hole,
tess_vertex * v1, tess_vertex * v2)
{
tess_vertex *v1_new, *v2_new;
/* make copies of v1 and v2, place them respectively after their originals */
if ((v1_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return GLU_ERROR;
}
if ((v2_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return GLU_ERROR;
}
v1_new->edge_flag = GL_TRUE;
v1_new->data = v1->data;
v1_new->location[0] = v1->location[0];
v1_new->location[1] = v1->location[1];
v1_new->location[2] = v1->location[2];
v1_new->x = v1->x;
v1_new->y = v1->y;
v1_new->shadow_vertex = v1;
v1->shadow_vertex = v1_new;
v1_new->next = v1->next;
v1_new->previous = v1;
v1->next->previous = v1_new;
v1->next = v1_new;
v2_new->edge_flag = GL_TRUE;
v2_new->data = v2->data;
v2_new->location[0] = v2->location[0];
v2_new->location[1] = v2->location[1];
v2_new->location[2] = v2->location[2];
v2_new->x = v2->x;
v2_new->y = v2->y;
v2_new->shadow_vertex = v2;
v2->shadow_vertex = v2_new;
v2_new->next = v2->next;
v2_new->previous = v2;
v2->next->previous = v2_new;
v2->next = v2_new;
/* link together the two lists */
v1->next = v2_new;
v2_new->previous = v1;
v2->next = v1_new;
v1_new->previous = v2;
/* update the vertex count of the contour */
contour->vertex_cnt += hole->vertex_cnt + 2;
/* remove the INTERIOR contour */
contour->next = hole->next;
if (hole->next != NULL)
hole->next->previous = contour;
free(hole);
/* update tobj structure */
--(tobj->contour_cnt);
if (contour->last_vertex == v1)
contour->last_vertex = v1_new;
/* mark two vertices with edge_flag */
v2->edge_flag = GL_FALSE;
v1->edge_flag = GL_FALSE;
return GLU_NO_ERROR;
}

View File

@@ -1,403 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "gluP.h"
#endif
/*
* This code was contributed by Marc Buffat (buffat@mecaflu.ec-lyon.fr).
* Thanks Marc!!!
*/
/* implementation de gluProject et gluUnproject */
/* M. Buffat 17/2/95 */
/*
* Transform a point (column vector) by a 4x4 matrix. I.e. out = m * in
* Input: m - the 4x4 matrix
* in - the 4x1 vector
* Output: out - the resulting 4x1 vector.
*/
static void
transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
{
#define M(row,col) m[col*4+row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
/*
* Perform a 4x4 matrix multiplication (product = a x b).
* Input: a, b - matrices to multiply
* Output: product - product of a and b
*/
static void
matmul(GLdouble * product, const GLdouble * a, const GLdouble * b)
{
/* This matmul was contributed by Thomas Malik */
GLdouble temp[16];
GLint i;
#define A(row,col) a[(col<<2)+row]
#define B(row,col) b[(col<<2)+row]
#define T(row,col) temp[(col<<2)+row]
/* i-te Zeile */
for (i = 0; i < 4; i++) {
T(i, 0) =
A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i,
3) *
B(3, 0);
T(i, 1) =
A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i,
3) *
B(3, 1);
T(i, 2) =
A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i,
3) *
B(3, 2);
T(i, 3) =
A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i,
3) *
B(3, 3);
}
#undef A
#undef B
#undef T
MEMCPY(product, temp, 16 * sizeof(GLdouble));
}
/*
* Compute inverse of 4x4 transformation matrix.
* Code contributed by Jacques Leroy jle@star.be
* Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
*/
static GLboolean
invert_matrix(const GLdouble * m, GLdouble * out)
{
/* NB. OpenGL Matrices are COLUMN major. */
#define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
#define MAT(m,r,c) (m)[(c)*4+(r)]
GLdouble wtmp[4][8];
GLdouble m0, m1, m2, m3, s;
GLdouble *r0, *r1, *r2, *r3;
r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1),
r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3),
r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1),
r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3),
r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1),
r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3),
r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1),
r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3),
r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
/* choose pivot - or die */
if (fabs(r3[0]) > fabs(r2[0]))
SWAP_ROWS(r3, r2);
if (fabs(r2[0]) > fabs(r1[0]))
SWAP_ROWS(r2, r1);
if (fabs(r1[0]) > fabs(r0[0]))
SWAP_ROWS(r1, r0);
if (0.0 == r0[0])
return GL_FALSE;
/* eliminate first variable */
m1 = r1[0] / r0[0];
m2 = r2[0] / r0[0];
m3 = r3[0] / r0[0];
s = r0[1];
r1[1] -= m1 * s;
r2[1] -= m2 * s;
r3[1] -= m3 * s;
s = r0[2];
r1[2] -= m1 * s;
r2[2] -= m2 * s;
r3[2] -= m3 * s;
s = r0[3];
r1[3] -= m1 * s;
r2[3] -= m2 * s;
r3[3] -= m3 * s;
s = r0[4];
if (s != 0.0) {
r1[4] -= m1 * s;
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r0[5];
if (s != 0.0) {
r1[5] -= m1 * s;
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r0[6];
if (s != 0.0) {
r1[6] -= m1 * s;
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r0[7];
if (s != 0.0) {
r1[7] -= m1 * s;
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* choose pivot - or die */
if (fabs(r3[1]) > fabs(r2[1]))
SWAP_ROWS(r3, r2);
if (fabs(r2[1]) > fabs(r1[1]))
SWAP_ROWS(r2, r1);
if (0.0 == r1[1])
return GL_FALSE;
/* eliminate second variable */
m2 = r2[1] / r1[1];
m3 = r3[1] / r1[1];
r2[2] -= m2 * r1[2];
r3[2] -= m3 * r1[2];
r2[3] -= m2 * r1[3];
r3[3] -= m3 * r1[3];
s = r1[4];
if (0.0 != s) {
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r1[5];
if (0.0 != s) {
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r1[6];
if (0.0 != s) {
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r1[7];
if (0.0 != s) {
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* choose pivot - or die */
if (fabs(r3[2]) > fabs(r2[2]))
SWAP_ROWS(r3, r2);
if (0.0 == r2[2])
return GL_FALSE;
/* eliminate third variable */
m3 = r3[2] / r2[2];
r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7];
/* last check */
if (0.0 == r3[3])
return GL_FALSE;
s = 1.0 / r3[3]; /* now back substitute row 3 */
r3[4] *= s;
r3[5] *= s;
r3[6] *= s;
r3[7] *= s;
m2 = r2[3]; /* now back substitute row 2 */
s = 1.0 / r2[2];
r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
m1 = r1[3];
r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
m0 = r0[3];
r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
m1 = r1[2]; /* now back substitute row 1 */
s = 1.0 / r1[1];
r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
m0 = r0[2];
r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
m0 = r0[1]; /* now back substitute row 0 */
s = 1.0 / r0[0];
r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
MAT(out, 0, 0) = r0[4];
MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6];
MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4];
MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6];
MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4];
MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6];
MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4];
MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6];
MAT(out, 3, 3) = r3[7];
return GL_TRUE;
#undef MAT
#undef SWAP_ROWS
}
/* projection du point (objx,objy,obz) sur l'ecran (winx,winy,winz) */
GLint GLAPIENTRY
gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * winx, GLdouble * winy, GLdouble * winz)
{
/* matrice de transformation */
GLdouble in[4], out[4];
/* initilise la matrice et le vecteur a transformer */
in[0] = objx;
in[1] = objy;
in[2] = objz;
in[3] = 1.0;
transform_point(out, model, in);
transform_point(in, proj, out);
/* d'ou le resultat normalise entre -1 et 1 */
if (in[3] == 0.0)
return GL_FALSE;
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
/* en coordonnees ecran */
*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
/* entre 0 et 1 suivant z */
*winz = (1 + in[2]) / 2;
return GL_TRUE;
}
/* transformation du point ecran (winx,winy,winz) en point objet */
GLint GLAPIENTRY
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * objx, GLdouble * objy, GLdouble * objz)
{
/* matrice de transformation */
GLdouble m[16], A[16];
GLdouble in[4], out[4];
/* transformation coordonnees normalisees entre -1 et 1 */
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
in[2] = 2 * winz - 1.0;
in[3] = 1.0;
/* calcul transformation inverse */
matmul(A, proj, model);
if (!invert_matrix(A, m))
return GL_FALSE;
/* d'ou les coordonnees objets */
transform_point(out, m, in);
if (out[3] == 0.0)
return GL_FALSE;
*objx = out[0] / out[3];
*objy = out[1] / out[3];
*objz = out[2] / out[3];
return GL_TRUE;
}
/*
* New in GLU 1.3
* This is like gluUnProject but also takes near and far DepthRange values.
*/
#ifdef GLU_VERSION_1_3
GLint GLAPIENTRY
gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLclampd nearZ, GLclampd farZ,
GLdouble * objx, GLdouble * objy, GLdouble * objz,
GLdouble * objw)
{
/* matrice de transformation */
GLdouble m[16], A[16];
GLdouble in[4], out[4];
GLdouble z = nearZ + winz * (farZ - nearZ);
/* transformation coordonnees normalisees entre -1 et 1 */
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
in[2] = 2.0 * z - 1.0;
in[3] = clipw;
/* calcul transformation inverse */
matmul(A, projMatrix, modelMatrix);
if (!invert_matrix(A, m))
return GL_FALSE;
/* d'ou les coordonnees objets */
transform_point(out, m, in);
if (out[3] == 0.0)
return GL_FALSE;
*objx = out[0] / out[3];
*objy = out[1] / out[3];
*objz = out[2] / out[3];
*objw = out[3];
return GL_TRUE;
}
#endif

View File

@@ -1,819 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1999-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* TODO:
* texture coordinate support
* flip normals according to orientation
* there's still some inside/outside orientation bugs in possibly all
* but the sphere function
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#endif
#ifndef M_PI
# define M_PI (3.1415926)
#endif
/*
* Convert degrees to radians:
*/
#define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
/*
* Sin and Cos for degree angles:
*/
#define SIND( A ) sin( (A)*(M_PI/180.0) )
#define COSD( A) cos( (A)*(M_PI/180.0) )
/*
* Texture coordinates if texture flag is set
*/
#define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
struct GLUquadric
{
GLenum DrawStyle; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
GLenum Orientation; /* GLU_INSIDE or GLU_OUTSIDE */
GLboolean TextureFlag; /* Generate texture coords? */
GLenum Normals; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
void (GLCALLBACK * ErrorFunc) (GLenum err); /* Error handler callback function */
};
/*
* Process a GLU error.
*/
static void
quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg)
{
/* Call the error call back function if any */
if (qobj->ErrorFunc) {
(*qobj->ErrorFunc) (error);
}
/* Print a message to stdout if MESA_DEBUG variable is defined */
if (getenv("MESA_DEBUG")) {
fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error),
msg);
}
}
GLUquadricObj *GLAPIENTRY
gluNewQuadric(void)
{
GLUquadricObj *q;
q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric));
if (q) {
q->DrawStyle = GLU_FILL;
q->Orientation = GLU_OUTSIDE;
q->TextureFlag = GL_FALSE;
q->Normals = GLU_SMOOTH;
q->ErrorFunc = NULL;
}
return q;
}
void GLAPIENTRY
gluDeleteQuadric(GLUquadricObj * state)
{
if (state) {
free((void *) state);
}
}
/*
* Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
* or GLU_POINT.
*/
void GLAPIENTRY
gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle)
{
if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE
|| drawStyle == GLU_SILHOUETTE
|| drawStyle == GLU_POINT)) {
quadObject->DrawStyle = drawStyle;
}
else {
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle");
}
}
/*
* Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
*/
void GLAPIENTRY
gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation)
{
if (quadObject
&& (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) {
quadObject->Orientation = orientation;
}
else {
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation");
}
}
/*
* Set the error handler callback function.
*/
void GLAPIENTRY
gluQuadricCallback(GLUquadricObj * qobj,
GLenum which, void (GLCALLBACK * fn) ())
{
/*
* UGH, this is a mess! I thought ANSI was a standard.
*/
if (qobj && which == GLU_ERROR) {
#ifdef __CYGWIN32__
qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn;
#elif defined(OPENSTEP)
qobj->ErrorFunc = (void (*)(GLenum)) fn;
#elif defined(_WIN32)
qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn;
#elif defined(__STORM__)
qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn;
#elif defined(__BEOS__)
qobj->ErrorFunc = (void (*)(GLenum)) fn;
#else
qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn;
#endif
}
}
void GLAPIENTRY
gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals)
{
if (quadObject
&& (normals == GLU_NONE || normals == GLU_FLAT
|| normals == GLU_SMOOTH)) {
quadObject->Normals = normals;
}
}
void GLAPIENTRY
gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords)
{
if (quadObject) {
quadObject->TextureFlag = textureCoords;
}
}
/*
* Call glNormal3f after scaling normal to unit length.
*/
static void
normal3f(GLfloat x, GLfloat y, GLfloat z)
{
GLdouble mag;
mag = sqrt(x * x + y * y + z * z);
if (mag > 0.00001F) {
x /= mag;
y /= mag;
z /= mag;
}
glNormal3f(x, y, z);
}
void GLAPIENTRY
gluCylinder(GLUquadricObj * qobj,
GLdouble baseRadius, GLdouble topRadius,
GLdouble height, GLint slices, GLint stacks)
{
GLdouble da, r, dr, dz;
GLfloat x, y, z, nz, nsign;
GLint i, j;
if (qobj->Orientation == GLU_INSIDE) {
nsign = -1.0;
}
else {
nsign = 1.0;
}
da = 2.0 * M_PI / slices;
dr = (topRadius - baseRadius) / stacks;
dz = height / stacks;
nz = (baseRadius - topRadius) / height; /* Z component of normal vectors */
if (qobj->DrawStyle == GLU_POINT) {
glBegin(GL_POINTS);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
z = 0.0;
r = baseRadius;
for (j = 0; j <= stacks; j++) {
glVertex3f(x * r, y * r, z);
z += dz;
r += dr;
}
}
glEnd();
}
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
/* Draw rings */
if (qobj->DrawStyle == GLU_LINE) {
z = 0.0;
r = baseRadius;
for (j = 0; j <= stacks; j++) {
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * r, y * r, z);
}
glEnd();
z += dz;
r += dr;
}
}
else {
/* draw one ring at each end */
if (baseRadius != 0.0) {
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
}
glEnd();
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * topRadius, y * topRadius, height);
}
glEnd();
}
}
/* draw length lines */
glBegin(GL_LINES);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
glVertex3f(x * topRadius, y * topRadius, height);
}
glEnd();
}
else if (qobj->DrawStyle == GLU_FILL) {
GLfloat ds = 1.0 / slices;
GLfloat dt = 1.0 / stacks;
GLfloat t = 0.0;
z = 0.0;
r = baseRadius;
for (j = 0; j < stacks; j++) {
GLfloat s = 0.0;
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
GLfloat x, y;
if (i == slices) {
x = sin(0.0);
y = cos(0.0);
}
else {
x = sin(i * da);
y = cos(i * da);
}
if (nsign == 1.0) {
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t);
glVertex3f(x * r, y * r, z);
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t + dt);
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
}
else {
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t);
glVertex3f(x * r, y * r, z);
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t + dt);
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
}
s += ds;
} /* for slices */
glEnd();
r += dr;
t += dt;
z += dz;
} /* for stacks */
}
}
void GLAPIENTRY
gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks)
{
GLfloat rho, drho, theta, dtheta;
GLfloat x, y, z;
GLfloat s, t, ds, dt;
GLint i, j, imin, imax;
GLboolean normals;
GLfloat nsign;
if (qobj->Normals == GLU_NONE) {
normals = GL_FALSE;
}
else {
normals = GL_TRUE;
}
if (qobj->Orientation == GLU_INSIDE) {
nsign = -1.0;
}
else {
nsign = 1.0;
}
drho = M_PI / (GLfloat) stacks;
dtheta = 2.0 * M_PI / (GLfloat) slices;
/* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
/* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
/* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
if (qobj->DrawStyle == GLU_FILL) {
if (!qobj->TextureFlag) {
/* draw +Z end as a triangle fan */
glBegin(GL_TRIANGLE_FAN);
glNormal3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, nsign * radius);
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(drho);
y = cos(theta) * sin(drho);
z = nsign * cos(drho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
ds = 1.0 / slices;
dt = 1.0 / stacks;
t = 1.0; /* because loop now runs from 0 */
if (qobj->TextureFlag) {
imin = 0;
imax = stacks;
}
else {
imin = 1;
imax = stacks - 1;
}
/* draw intermediate stacks as quad strips */
for (i = imin; i < imax; i++) {
rho = i * drho;
glBegin(GL_QUAD_STRIP);
s = 0.0;
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
TXTR_COORD(s, t);
glVertex3f(x * radius, y * radius, z * radius);
x = -sin(theta) * sin(rho + drho);
y = cos(theta) * sin(rho + drho);
z = nsign * cos(rho + drho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
TXTR_COORD(s, t - dt);
s += ds;
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
t -= dt;
}
if (!qobj->TextureFlag) {
/* draw -Z end as a triangle fan */
glBegin(GL_TRIANGLE_FAN);
glNormal3f(0.0, 0.0, -1.0);
glVertex3f(0.0, 0.0, -radius * nsign);
rho = M_PI - drho;
s = 1.0;
t = dt;
for (j = slices; j >= 0; j--) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
s -= ds;
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
}
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
/* draw stack lines */
for (i = 1; i < stacks; i++) { /* stack line at i==stacks-1 was missing here */
rho = i * drho;
glBegin(GL_LINE_LOOP);
for (j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
/* draw slice lines */
for (j = 0; j < slices; j++) {
theta = j * dtheta;
glBegin(GL_LINE_STRIP);
for (i = 0; i <= stacks; i++) {
rho = i * drho;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
}
else if (qobj->DrawStyle == GLU_POINT) {
/* top and bottom-most points */
glBegin(GL_POINTS);
if (normals)
glNormal3f(0.0, 0.0, nsign);
glVertex3d(0.0, 0.0, radius);
if (normals)
glNormal3f(0.0, 0.0, -nsign);
glVertex3d(0.0, 0.0, -radius);
/* loop over stacks */
for (i = 1; i < stacks - 1; i++) {
rho = i * drho;
for (j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if (normals)
glNormal3f(x * nsign, y * nsign, z * nsign);
glVertex3f(x * radius, y * radius, z * radius);
}
}
glEnd();
}
}
void GLAPIENTRY
gluDisk(GLUquadricObj * qobj,
GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
{
GLfloat da, dr;
#if 0
GLdouble a, da;
GLfloat r, dr;
GLfloat x, y;
GLfloat r1, r2, dtc;
GLint s, l;
#endif
/* Normal vectors */
if (qobj->Normals != GLU_NONE) {
if (qobj->Orientation == GLU_OUTSIDE) {
glNormal3f(0.0, 0.0, +1.0);
}
else {
glNormal3f(0.0, 0.0, -1.0);
}
}
da = 2.0 * M_PI / slices;
dr = (outerRadius - innerRadius) / (GLfloat) loops;
switch (qobj->DrawStyle) {
case GLU_FILL:
{
/* texture of a gluDisk is a cut out of the texture unit square
* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
* (linear mapping)
*/
GLfloat dtc = 2.0f * outerRadius;
GLfloat sa, ca;
GLfloat r1 = innerRadius;
GLint l;
for (l = 0; l < loops; l++) {
GLfloat r2 = r1 + dr;
if (qobj->Orientation == GLU_OUTSIDE) {
GLint s;
glBegin(GL_QUAD_STRIP);
for (s = 0; s <= slices; s++) {
GLfloat a;
if (s == slices)
a = 0.0;
else
a = s * da;
sa = sin(a);
ca = cos(a);
TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc);
glVertex2f(r2 * sa, r2 * ca);
TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc);
glVertex2f(r1 * sa, r1 * ca);
}
glEnd();
}
else {
GLint s;
glBegin(GL_QUAD_STRIP);
for (s = slices; s >= 0; s--) {
GLfloat a;
if (s == slices)
a = 0.0;
else
a = s * da;
sa = sin(a);
ca = cos(a);
TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc);
glVertex2f(r2 * sa, r2 * ca);
TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc);
glVertex2f(r1 * sa, r1 * ca);
}
glEnd();
}
r1 = r2;
}
break;
}
case GLU_LINE:
{
GLint l, s;
/* draw loops */
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius + l * dr;
glBegin(GL_LINE_LOOP);
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
glVertex2f(r * sin(a), r * cos(a));
}
glEnd();
}
/* draw spokes */
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
GLfloat x = sin(a);
GLfloat y = cos(a);
glBegin(GL_LINE_STRIP);
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius + l * dr;
glVertex2f(r * x, r * y);
}
glEnd();
}
break;
}
case GLU_POINT:
{
GLint s;
glBegin(GL_POINTS);
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
GLfloat x = sin(a);
GLfloat y = cos(a);
GLint l;
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius * l * dr;
glVertex2f(r * x, r * y);
}
}
glEnd();
break;
}
case GLU_SILHOUETTE:
{
if (innerRadius != 0.0) {
GLfloat a;
glBegin(GL_LINE_LOOP);
for (a = 0.0; a < 2.0 * M_PI; a += da) {
GLfloat x = innerRadius * sin(a);
GLfloat y = innerRadius * cos(a);
glVertex2f(x, y);
}
glEnd();
}
{
GLfloat a;
glBegin(GL_LINE_LOOP);
for (a = 0; a < 2.0 * M_PI; a += da) {
GLfloat x = outerRadius * sin(a);
GLfloat y = outerRadius * cos(a);
glVertex2f(x, y);
}
glEnd();
}
break;
}
default:
abort();
}
}
void GLAPIENTRY
gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius,
GLdouble outerRadius, GLint slices, GLint loops,
GLdouble startAngle, GLdouble sweepAngle)
{
if (qobj->Normals != GLU_NONE) {
if (qobj->Orientation == GLU_OUTSIDE) {
glNormal3f(0.0, 0.0, +1.0);
}
else {
glNormal3f(0.0, 0.0, -1.0);
}
}
if (qobj->DrawStyle == GLU_POINT) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / (loops - 1);
delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1));
glBegin(GL_POINTS);
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice < slices; slice++) {
glVertex2d(radius * sin(angle), radius * cos(angle));
angle += delta_angle;
}
radius += delta_radius;
}
glEnd();
}
else if (qobj->DrawStyle == GLU_LINE) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / loops;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
/* draw rings */
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
angle = DEG_TO_RAD(startAngle);
glBegin(GL_LINE_STRIP);
for (slice = 0; slice <= slices; slice++) {
glVertex2d(radius * sin(angle), radius * cos(angle));
angle += delta_angle;
}
glEnd();
radius += delta_radius;
}
/* draw spokes */
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
radius = innerRadius;
glBegin(GL_LINE_STRIP);
for (loop = 0; loop < loops; loop++) {
glVertex2d(radius * sin(angle), radius * cos(angle));
radius += delta_radius;
}
glEnd();
angle += delta_angle;
}
}
else if (qobj->DrawStyle == GLU_SILHOUETTE) {
GLint slice;
GLdouble angle, delta_angle;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
/* draw outer ring */
glBegin(GL_LINE_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
glVertex2d(outerRadius * sin(angle), outerRadius * cos(angle));
angle += delta_angle;
}
glEnd();
/* draw inner ring */
if (innerRadius > 0.0) {
glBegin(GL_LINE_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice < slices; slice++) {
glVertex2d(innerRadius * sin(angle), innerRadius * cos(angle));
angle += delta_angle;
}
glEnd();
}
/* draw spokes */
if (sweepAngle < 360.0) {
GLdouble stopAngle = startAngle + sweepAngle;
glBegin(GL_LINES);
glVertex2d(innerRadius * SIND(startAngle),
innerRadius * COSD(startAngle));
glVertex2d(outerRadius * SIND(startAngle),
outerRadius * COSD(startAngle));
glVertex2d(innerRadius * SIND(stopAngle),
innerRadius * COSD(stopAngle));
glVertex2d(outerRadius * SIND(stopAngle),
outerRadius * COSD(stopAngle));
glEnd();
}
}
else if (qobj->DrawStyle == GLU_FILL) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / loops;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
glBegin(GL_QUAD_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
if (qobj->Orientation == GLU_OUTSIDE) {
glVertex2d((radius + delta_radius) * sin(angle),
(radius + delta_radius) * cos(angle));
glVertex2d(radius * sin(angle), radius * cos(angle));
}
else {
glVertex2d(radius * sin(angle), radius * cos(angle));
glVertex2d((radius + delta_radius) * sin(angle),
(radius + delta_radius) * cos(angle));
}
angle += delta_angle;
}
glEnd();
radius += delta_radius;
}
}
}

View File

@@ -1,327 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "tess.h"
#endif
/*
* This is ugly, but seems the easiest way to do things to make the
* code work under YellowBox for Windows
*/
#if defined(OPENSTEP) && defined(CALLBACK)
#undef CALLBACK
#define CALLBACK
#endif
static void delete_contours(GLUtriangulatorObj *);
#ifdef __CYGWIN32__
#define _CALLBACK
#else
#define _CALLBACK GLCALLBACK
#endif
static void
init_callbacks(tess_callbacks * callbacks)
{
callbacks->begin = (void (_CALLBACK *) (GLenum)) 0;
callbacks->edgeFlag = (void (_CALLBACK *) (GLboolean)) 0;
callbacks->vertex = (void (_CALLBACK *) (void *)) 0;
callbacks->end = (void (_CALLBACK *) (void)) 0;
callbacks->error = (void (_CALLBACK *) (GLenum)) 0;
}
void
tess_call_user_error(GLUtriangulatorObj * tobj, GLenum gluerr)
{
if (tobj->error == GLU_NO_ERROR)
tobj->error = gluerr;
if (tobj->callbacks.error != NULL)
(tobj->callbacks.error) (gluerr);
}
GLUtriangulatorObj *GLAPIENTRY
gluNewTess(void)
{
GLUtriangulatorObj *tobj;
if ((tobj = (GLUtriangulatorObj *)
malloc(sizeof(struct GLUtesselator))) == NULL)
return NULL;
tobj->contours = tobj->last_contour = NULL;
init_callbacks(&tobj->callbacks);
tobj->error = GLU_NO_ERROR;
tobj->current_polygon = NULL;
tobj->contour_cnt = 0;
return tobj;
}
void GLAPIENTRY
gluTessCallback(GLUtriangulatorObj * tobj, GLenum which,
void (GLCALLBACK * fn) ())
{
switch (which) {
case GLU_BEGIN:
tobj->callbacks.begin = (void (_CALLBACK *) (GLenum)) fn;
break;
case GLU_EDGE_FLAG:
tobj->callbacks.edgeFlag = (void (_CALLBACK *) (GLboolean)) fn;
break;
case GLU_VERTEX:
tobj->callbacks.vertex = (void (_CALLBACK *) (void *)) fn;
break;
case GLU_END:
tobj->callbacks.end = (void (_CALLBACK *) (void)) fn;
break;
case GLU_ERROR:
tobj->callbacks.error = (void (_CALLBACK *) (GLenum)) fn;
break;
default:
tobj->error = GLU_INVALID_ENUM;
break;
}
}
void GLAPIENTRY
gluDeleteTess(GLUtriangulatorObj * tobj)
{
if (tobj->error == GLU_NO_ERROR && tobj->contour_cnt)
/* was gluEndPolygon called? */
tess_call_user_error(tobj, GLU_TESS_ERROR1);
/* delete all internal structures */
delete_contours(tobj);
free(tobj);
}
void GLAPIENTRY
gluBeginPolygon(GLUtriangulatorObj * tobj)
{
/*
if(tobj->error!=GLU_NO_ERROR)
return;
*/
tobj->error = GLU_NO_ERROR;
if (tobj->current_polygon != NULL) {
/* gluEndPolygon was not called */
tess_call_user_error(tobj, GLU_TESS_ERROR1);
/* delete all internal structures */
delete_contours(tobj);
}
else {
if ((tobj->current_polygon =
(tess_polygon *) malloc(sizeof(tess_polygon))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
tobj->current_polygon->vertex_cnt = 0;
tobj->current_polygon->vertices =
tobj->current_polygon->last_vertex = NULL;
}
}
void GLAPIENTRY
gluEndPolygon(GLUtriangulatorObj * tobj)
{
/*tess_contour *contour_ptr; */
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* check if gluBeginPolygon was called */
if (tobj->current_polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
tess_test_polygon(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* any real contours? */
if (tobj->contour_cnt == 0) {
/* delete all internal structures */
delete_contours(tobj);
return;
}
tess_find_contour_hierarchies(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
tess_handle_holes(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* if no callbacks, nothing to do */
if (tobj->callbacks.begin != NULL && tobj->callbacks.vertex != NULL &&
tobj->callbacks.end != NULL) {
if (tobj->callbacks.edgeFlag == NULL)
tess_tesselate(tobj);
else
tess_tesselate_with_edge_flag(tobj);
}
end:
/* delete all internal structures */
delete_contours(tobj);
}
void GLAPIENTRY
gluNextContour(GLUtriangulatorObj * tobj, GLenum type)
{
if (tobj->error != GLU_NO_ERROR)
return;
if (tobj->current_polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
/* first contour? */
if (tobj->current_polygon->vertex_cnt)
tess_test_polygon(tobj);
}
void GLAPIENTRY
gluTessVertex(GLUtriangulatorObj * tobj, GLdouble v[3], void *data)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *last_vertex_ptr;
if (tobj->error != GLU_NO_ERROR)
return;
if (polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
last_vertex_ptr = polygon->last_vertex;
if (last_vertex_ptr == NULL) {
if ((last_vertex_ptr = (tess_vertex *)
malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
polygon->vertices = last_vertex_ptr;
polygon->last_vertex = last_vertex_ptr;
last_vertex_ptr->data = data;
last_vertex_ptr->location[0] = v[0];
last_vertex_ptr->location[1] = v[1];
last_vertex_ptr->location[2] = v[2];
last_vertex_ptr->next = NULL;
last_vertex_ptr->previous = NULL;
++(polygon->vertex_cnt);
}
else {
tess_vertex *vertex_ptr;
/* same point twice? */
if (fabs(last_vertex_ptr->location[0] - v[0]) < EPSILON &&
fabs(last_vertex_ptr->location[1] - v[1]) < EPSILON &&
fabs(last_vertex_ptr->location[2] - v[2]) < EPSILON) {
tess_call_user_error(tobj, GLU_TESS_ERROR6);
return;
}
if ((vertex_ptr = (tess_vertex *)
malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
vertex_ptr->data = data;
vertex_ptr->location[0] = v[0];
vertex_ptr->location[1] = v[1];
vertex_ptr->location[2] = v[2];
vertex_ptr->next = NULL;
vertex_ptr->previous = last_vertex_ptr;
++(polygon->vertex_cnt);
last_vertex_ptr->next = vertex_ptr;
polygon->last_vertex = vertex_ptr;
}
}
static void
delete_contours(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_contour *contour, *contour_tmp;
tess_vertex *vertex, *vertex_tmp;
/* remove current_polygon list - if exists due to detected error */
if (polygon != NULL) {
if (polygon->vertices) {
for (vertex = polygon->vertices; vertex != polygon->last_vertex;) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
free(vertex);
}
free(polygon);
tobj->current_polygon = NULL;
}
/* remove all contour data */
for (contour = tobj->contours; contour != NULL;) {
for (vertex = contour->vertices; vertex != contour->last_vertex;) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
free(vertex);
contour_tmp = contour->next;
free(contour);
contour = contour_tmp;
}
tobj->contours = tobj->last_contour = NULL;
tobj->contour_cnt = 0;
}
void GLAPIENTRY
gluTessNormal(GLUtesselator *tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ)
{
/* dummy function */
(void) tess;
(void) valueX;
(void) valueY;
(void) valueZ;
}

View File

@@ -1,107 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifndef TESS_H
#define TESS_H
#include "gluP.h"
#define EPSILON 1e-06 /* epsilon for double precision compares */
typedef enum
{
OXY,
OYZ,
OXZ
}
projection_type;
typedef struct callbacks_str
{
void (GLCALLBACK * begin) (GLenum mode);
void (GLCALLBACK * edgeFlag) (GLboolean flag);
void (GLCALLBACK * vertex) (GLvoid * v);
void (GLCALLBACK * end) (void);
void (GLCALLBACK * error) (GLenum err);
}
tess_callbacks;
typedef struct vertex_str
{
void *data;
GLdouble location[3];
GLdouble x, y;
GLboolean edge_flag;
struct vertex_str *shadow_vertex;
struct vertex_str *next, *previous;
}
tess_vertex;
typedef struct contour_str
{
GLenum type;
GLuint vertex_cnt;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices, *last_vertex;
struct contour_str *next, *previous;
}
tess_contour;
typedef struct polygon_str
{
GLuint vertex_cnt;
GLdouble A, B, C, D;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices, *last_vertex;
}
tess_polygon;
struct GLUtesselator
{
tess_contour *contours, *last_contour;
GLuint contour_cnt;
tess_callbacks callbacks;
tess_polygon *current_polygon;
GLenum error;
GLdouble A, B, C, D;
projection_type projection;
};
extern void tess_call_user_error(GLUtriangulatorObj *, GLenum);
extern void tess_test_polygon(GLUtriangulatorObj *);
extern void tess_find_contour_hierarchies(GLUtriangulatorObj *);
extern void tess_handle_holes(GLUtriangulatorObj *);
extern void tess_tesselate(GLUtriangulatorObj *);
extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *);
#endif

View File

@@ -1,406 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdlib.h>
#include <math.h>
#include "tess.h"
#endif
static GLboolean edge_flag;
static void emit_triangle(GLUtriangulatorObj *, tess_vertex *,
tess_vertex *, tess_vertex *);
static void emit_triangle_with_edge_flag(GLUtriangulatorObj *,
tess_vertex *, GLboolean,
tess_vertex *, GLboolean,
tess_vertex *, GLboolean);
static GLdouble
twice_the_triangle_area(tess_vertex * va, tess_vertex * vb, tess_vertex * vc)
{
return (vb->x - va->x) * (vc->y - va->y) - (vb->y - va->y) * (vc->x -
va->x);
}
static GLboolean
left(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y)
{
if (A * x + B * y + C > -EPSILON)
return GL_TRUE;
else
return GL_FALSE;
}
static GLboolean
right(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y)
{
if (A * x + B * y + C < EPSILON)
return GL_TRUE;
else
return GL_FALSE;
}
static GLint
convex_ccw(tess_vertex * va,
tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj)
{
GLdouble d;
d = twice_the_triangle_area(va, vb, vc);
if (d > EPSILON) {
return 1;
}
else if (d < -EPSILON) {
return 0;
}
else {
return -1;
}
}
static GLint
convex_cw(tess_vertex * va,
tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj)
{
GLdouble d;
d = twice_the_triangle_area(va, vb, vc);
if (d < -EPSILON) {
return 1;
}
else if (d > EPSILON) {
return 0;
}
else {
return -1;
}
}
static GLboolean
diagonal_ccw(tess_vertex * va,
tess_vertex * vb,
GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vc = va->next, *vertex, *shadow_vertex;
struct
{
GLdouble A, B, C;
}
ac, cb, ba;
GLdouble x, y;
GLint res = convex_ccw(va, vc, vb, tobj);
if (res == 0)
return GL_FALSE;
if (res == -1)
return GL_TRUE;
ba.A = vb->y - va->y;
ba.B = va->x - vb->x;
ba.C = -ba.A * va->x - ba.B * va->y;
ac.A = va->y - vc->y;
ac.B = vc->x - va->x;
ac.C = -ac.A * vc->x - ac.B * vc->y;
cb.A = vc->y - vb->y;
cb.B = vb->x - vc->x;
cb.C = -cb.A * vb->x - cb.B * vb->y;
for (vertex = vb->next; vertex != va; vertex = vertex->next) {
shadow_vertex = vertex->shadow_vertex;
if (shadow_vertex != NULL &&
(shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc))
continue;
x = vertex->x;
y = vertex->y;
if (left(ba.A, ba.B, ba.C, x, y) &&
left(ac.A, ac.B, ac.C, x, y) && left(cb.A, cb.B, cb.C, x, y))
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean
diagonal_cw(tess_vertex * va,
tess_vertex * vb,
GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vc = va->next, *vertex, *shadow_vertex;
struct
{
GLdouble A, B, C;
}
ac, cb, ba;
GLdouble x, y;
GLint res = convex_cw(va, vc, vb, tobj);
if (res == 0)
return GL_FALSE;
if (res == -1)
return GL_TRUE;
ba.A = vb->y - va->y;
ba.B = va->x - vb->x;
ba.C = -ba.A * va->x - ba.B * va->y;
ac.A = va->y - vc->y;
ac.B = vc->x - va->x;
ac.C = -ac.A * vc->x - ac.B * vc->y;
cb.A = vc->y - vb->y;
cb.B = vb->x - vc->x;
cb.C = -cb.A * vb->x - cb.B * vb->y;
for (vertex = vb->next; vertex != va; vertex = vertex->next) {
shadow_vertex = vertex->shadow_vertex;
if (shadow_vertex != NULL &&
(shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc))
continue;
x = vertex->x;
y = vertex->y;
if (right(ba.A, ba.B, ba.C, x, y) &&
right(ac.A, ac.B, ac.C, x, y) && right(cb.A, cb.B, cb.C, x, y))
return GL_FALSE;
}
return GL_TRUE;
}
static void
clip_ear(GLUtriangulatorObj * tobj, tess_vertex * v, tess_contour * contour)
{
emit_triangle(tobj, v->previous, v, v->next);
/* the first in the list */
if (contour->vertices == v) {
contour->vertices = v->next;
contour->last_vertex->next = v->next;
v->next->previous = contour->last_vertex;
}
else
/* the last ? */
if (contour->last_vertex == v) {
contour->vertices->previous = v->previous;
v->previous->next = v->next;
contour->last_vertex = v->previous;
}
else {
v->next->previous = v->previous;
v->previous->next = v->next;
}
free(v);
--(contour->vertex_cnt);
}
static void
clip_ear_with_edge_flag(GLUtriangulatorObj * tobj,
tess_vertex * v, tess_contour * contour)
{
emit_triangle_with_edge_flag(tobj, v->previous, v->previous->edge_flag,
v, v->edge_flag, v->next, GL_FALSE);
v->previous->edge_flag = GL_FALSE;
/* the first in the list */
if (contour->vertices == v) {
contour->vertices = v->next;
contour->last_vertex->next = v->next;
v->next->previous = contour->last_vertex;
}
else
/* the last ? */
if (contour->last_vertex == v) {
contour->vertices->previous = v->previous;
v->previous->next = v->next;
contour->last_vertex = v->previous;
}
else {
v->next->previous = v->previous;
v->previous->next = v->next;
}
free(v);
--(contour->vertex_cnt);
}
static void
triangulate_ccw(GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear(tobj, vertex->next, contour);
--vertex_cnt;
}
}
static void
triangulate_cw(GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_cw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear(tobj, vertex->next, contour);
--vertex_cnt;
}
}
static void
triangulate_ccw_with_edge_flag(GLUtriangulatorObj * tobj,
tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear_with_edge_flag(tobj, vertex->next, contour);
--vertex_cnt;
}
}
static void
triangulate_cw_with_edge_flag(GLUtriangulatorObj * tobj,
tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_cw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear_with_edge_flag(tobj, vertex->next, contour);
--vertex_cnt;
}
}
void
tess_tesselate(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
for (contour = tobj->contours; contour != NULL; contour = contour->next) {
if (contour->orientation == GLU_CCW) {
triangulate_ccw(tobj, contour);
}
else {
triangulate_cw(tobj, contour);
}
if (tobj->error != GLU_NO_ERROR)
return;
/* emit the last triangle */
emit_triangle(tobj, contour->vertices, contour->vertices->next,
contour->vertices->next->next);
}
}
void
tess_tesselate_with_edge_flag(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
edge_flag = GL_TRUE;
/* first callback with edgeFlag set to GL_TRUE */
(tobj->callbacks.edgeFlag) (GL_TRUE);
for (contour = tobj->contours; contour != NULL; contour = contour->next) {
if (contour->orientation == GLU_CCW)
triangulate_ccw_with_edge_flag(tobj, contour);
else
triangulate_cw_with_edge_flag(tobj, contour);
if (tobj->error != GLU_NO_ERROR)
return;
/* emit the last triangle */
emit_triangle_with_edge_flag(tobj, contour->vertices,
contour->vertices->edge_flag,
contour->vertices->next,
contour->vertices->next->edge_flag,
contour->vertices->next->next,
contour->vertices->next->next->edge_flag);
}
}
static void
emit_triangle(GLUtriangulatorObj * tobj,
tess_vertex * v1, tess_vertex * v2, tess_vertex * v3)
{
(tobj->callbacks.begin) (GL_TRIANGLES);
(tobj->callbacks.vertex) (v1->data);
(tobj->callbacks.vertex) (v2->data);
(tobj->callbacks.vertex) (v3->data);
(tobj->callbacks.end) ();
}
static void
emit_triangle_with_edge_flag(GLUtriangulatorObj * tobj,
tess_vertex * v1,
GLboolean edge_flag1,
tess_vertex * v2,
GLboolean edge_flag2,
tess_vertex * v3, GLboolean edge_flag3)
{
(tobj->callbacks.begin) (GL_TRIANGLES);
if (edge_flag1 != edge_flag) {
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag) (edge_flag);
}
(tobj->callbacks.vertex) (v1->data);
if (edge_flag2 != edge_flag) {
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag) (edge_flag);
}
(tobj->callbacks.vertex) (v2->data);
if (edge_flag3 != edge_flag) {
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag) (edge_flag);
}
(tobj->callbacks.vertex) (v3->data);
(tobj->callbacks.end) ();
}

View File

@@ -1,54 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file includes all .h files needed for the GLU source code for
* the purpose of precompiled headers.
*
* If the preprocessor symbol PCH is defined at compile time then each
* of the .c files will #include "all.h" only, instead of a bunch of
* individual .h files.
*/
#ifndef GLU_ALL_H
#define GLU_ALL_H
#ifndef PC_HEADER
This is an error. all.h should be included only if PCH is defined.
#endif
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GL/gl.h"
#include "GL/glu.h"
#include "gluP.h"
#include "nurbs.h"
#include "tess.h"
#endif /*GLU_ALL_H */

View File

@@ -1,416 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
* Copyright (C) 1995-2001 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gluP.h"
#endif
/*
* Miscellaneous utility functions
*/
#ifndef M_PI
#define M_PI 3.1415926536
#endif
#define EPS 0.00001
#ifndef GLU_INCOMPATIBLE_GL_VERSION
#define GLU_INCOMPATIBLE_GL_VERSION 100903
#endif
void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz)
{
GLfloat m[16];
GLfloat x[3], y[3], z[3];
GLfloat mag;
/* Make rotation matrix */
/* Z vector */
z[0] = eyex - centerx;
z[1] = eyey - centery;
z[2] = eyez - centerz;
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
if (mag) { /* mpichler, 19950515 */
z[0] /= mag;
z[1] /= mag;
z[2] /= mag;
}
/* Y vector */
y[0] = upx;
y[1] = upy;
y[2] = upz;
/* X vector = Y cross Z */
x[0] = y[1] * z[2] - y[2] * z[1];
x[1] = -y[0] * z[2] + y[2] * z[0];
x[2] = y[0] * z[1] - y[1] * z[0];
/* Recompute Y = Z cross X */
y[0] = z[1] * x[2] - z[2] * x[1];
y[1] = -z[0] * x[2] + z[2] * x[0];
y[2] = z[0] * x[1] - z[1] * x[0];
/* mpichler, 19950515 */
/* cross product gives area of parallelogram, which is < 1.0 for
* non-perpendicular unit-length vectors; so normalize x, y here
*/
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
if (mag) {
x[0] /= mag;
x[1] /= mag;
x[2] /= mag;
}
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
if (mag) {
y[0] /= mag;
y[1] /= mag;
y[2] /= mag;
}
#define M(row,col) m[col*4+row]
M(0, 0) = x[0];
M(0, 1) = x[1];
M(0, 2) = x[2];
M(0, 3) = 0.0;
M(1, 0) = y[0];
M(1, 1) = y[1];
M(1, 2) = y[2];
M(1, 3) = 0.0;
M(2, 0) = z[0];
M(2, 1) = z[1];
M(2, 2) = z[2];
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixf(m);
/* Translate Eye to Origin */
glTranslatef(-eyex, -eyey, -eyez);
}
void GLAPIENTRY
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
{
glOrtho(left, right, bottom, top, -1.0, 1.0);
}
static void
frustum(GLfloat left, GLfloat right,
GLfloat bottom, GLfloat top,
GLfloat nearval, GLfloat farval)
{
GLfloat x, y, a, b, c, d;
GLfloat m[16];
x = (2.0 * nearval) / (right - left);
y = (2.0 * nearval) / (top - bottom);
a = (right + left) / (right - left);
b = (top + bottom) / (top - bottom);
c = -(farval + nearval) / ( farval - nearval);
d = -(2.0 * farval * nearval) / (farval - nearval);
#define M(row,col) m[col*4+row]
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
#undef M
glMultMatrixf(m);
}
void GLAPIENTRY
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
GLfloat xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
/* don't call glFrustum() because of error semantics (covglu) */
frustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
void GLAPIENTRY
gluPickMatrix(GLdouble x, GLdouble y,
GLdouble width, GLdouble height, GLint viewport[4])
{
GLfloat m[16];
GLfloat sx, sy;
GLfloat tx, ty;
sx = viewport[2] / width;
sy = viewport[3] / height;
tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
#define M(row,col) m[col*4+row]
M(0, 0) = sx;
M(0, 1) = 0.0;
M(0, 2) = 0.0;
M(0, 3) = tx;
M(1, 0) = 0.0;
M(1, 1) = sy;
M(1, 2) = 0.0;
M(1, 3) = ty;
M(2, 0) = 0.0;
M(2, 1) = 0.0;
M(2, 2) = 1.0;
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixf(m);
}
const GLubyte *GLAPIENTRY
gluErrorString(GLenum errorCode)
{
static char *tess_error[] = {
"missing gluBeginPolygon",
"missing gluBeginContour",
"missing gluEndPolygon",
"missing gluEndContour",
"misoriented or self-intersecting loops",
"coincident vertices",
"colinear vertices",
"FIST recovery process fatal error"
};
static char *nurbs_error[] = {
"spline order un-supported",
"too few knots",
"valid knot range is empty",
"decreasing knot sequence knot",
"knot multiplicity greater than order of spline",
"endcurve() must follow bgncurve()",
"bgncurve() must precede endcurve()",
"missing or extra geometric data",
"can't draw pwlcurves",
"missing bgncurve()",
"missing bgnsurface()",
"endtrim() must precede endsurface()",
"bgnsurface() must precede endsurface()",
"curve of improper type passed as trim curve",
"bgnsurface() must precede bgntrim()",
"endtrim() must follow bgntrim()",
"bgntrim() must precede endtrim()",
"invalid or missing trim curve",
"bgntrim() must precede pwlcurve()",
"pwlcurve referenced twice",
"pwlcurve and nurbscurve mixed",
"improper usage of trim data type",
"nurbscurve referenced twice",
"nurbscurve and pwlcurve mixed",
"nurbssurface referenced twice",
"invalid property",
"endsurface() must follow bgnsurface()",
"misoriented trim curves",
"intersecting trim curves",
"UNUSED",
"unconnected trim curves",
"unknown knot error",
"negative vertex count encountered",
"negative byte-stride encountered",
"unknown type descriptor",
"null control array or knot vector",
"duplicate point on pwlcurve"
};
/* GL Errors */
if (errorCode == GL_NO_ERROR) {
return (GLubyte *) "no error";
}
else if (errorCode == GL_INVALID_VALUE) {
return (GLubyte *) "invalid value";
}
else if (errorCode == GL_INVALID_ENUM) {
return (GLubyte *) "invalid enum";
}
else if (errorCode == GL_INVALID_OPERATION) {
return (GLubyte *) "invalid operation";
}
else if (errorCode == GL_STACK_OVERFLOW) {
return (GLubyte *) "stack overflow";
}
else if (errorCode == GL_STACK_UNDERFLOW) {
return (GLubyte *) "stack underflow";
}
else if (errorCode == GL_OUT_OF_MEMORY) {
return (GLubyte *) "out of memory";
}
/* GLU Errors */
else if (errorCode == GLU_NO_ERROR) {
return (GLubyte *) "no error";
}
else if (errorCode == GLU_INVALID_ENUM) {
return (GLubyte *) "invalid enum";
}
else if (errorCode == GLU_INVALID_VALUE) {
return (GLubyte *) "invalid value";
}
else if (errorCode == GLU_OUT_OF_MEMORY) {
return (GLubyte *) "out of memory";
}
else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) {
return (GLubyte *) "incompatible GL version";
}
else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) {
return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1];
}
else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) {
return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1];
}
else {
return NULL;
}
}
/*
* New in GLU 1.1
*/
const GLubyte *GLAPIENTRY
gluGetString(GLenum name)
{
static char *extensions = "GL_EXT_abgr";
static char *version = "1.1 Mesa 3.5";
switch (name) {
case GLU_EXTENSIONS:
return (GLubyte *) extensions;
case GLU_VERSION:
return (GLubyte *) version;
default:
return NULL;
}
}
#if 0 /* gluGetProcAddressEXT not finalized yet! */
#ifdef __cplusplus
/* for BeOS R4.5 */
void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...)
#else
void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) ()
#endif
{
struct proc
{
const char *name;
void *address;
};
static struct proc procTable[] = {
{"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT}, /* me! */
/* new 1.1 functions */
{"gluGetString", (void *) gluGetString},
/* new 1.2 functions */
{"gluTessBeginPolygon", (void *) gluTessBeginPolygon},
{"gluTessBeginContour", (void *) gluTessBeginContour},
{"gluTessEndContour", (void *) gluTessEndContour},
{"gluTessEndPolygon", (void *) gluTessEndPolygon},
{"gluGetTessProperty", (void *) gluGetTessProperty},
/* new 1.3 functions */
{NULL, NULL}
};
GLuint i;
for (i = 0; procTable[i].address; i++) {
if (strcmp((const char *) procName, procTable[i].name) == 0)
return (void (GLAPIENTRY *) ()) procTable[i].address;
}
return NULL;
}
#endif
/*
* New in GLU 1.3
*/
#ifdef GLU_VERSION_1_3
GLboolean GLAPIENTRY
gluCheckExtension(const GLubyte *extName, const GLubyte * extString)
{
assert(extName);
assert(extString);
{
const int len = strlen((const char *) extName);
const char *start = (const char *) extString;
while (1) {
const char *c = strstr(start, (const char *) extName);
if (!c)
return GL_FALSE;
if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0))
return GL_TRUE;
start = c + len;
}
}
}
#endif

View File

@@ -1,141 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file allows the GLU code to be compiled either with the Mesa
* headers or with the real OpenGL headers.
*/
#ifndef GLUP_H
#define GLUP_H
#include <GL/gl.h>
#include <GL/glu.h>
#include <string.h>
#if defined(_WIN32) && !defined(__WIN32__)
# define __WIN32__
#endif
#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN__))
# pragma warning( disable : 4068 ) /* unknown pragma */
# pragma warning( disable : 4710 ) /* function 'foo' not inlined */
# pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */
# pragma warning( disable : 4127 ) /* conditional expression is constant */
# if defined(MESA_MINWARN)
# pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
# pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
# pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
# pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */
# pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
# endif
# if defined(_MSC_VER) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
# define GLAPI __declspec(dllexport)
# define WGLAPI __declspec(dllexport)
# elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
# define GLAPI __declspec(dllimport)
# define WGLAPI __declspec(dllimport)
# else /* for use with static link lib build of Win32 edition only */
# define GLAPI extern
# define WGLAPI __declspec(dllimport)
# endif /* _STATIC_MESA support */
# define GLAPIENTRY __stdcall
# define GLAPIENTRYP __stdcall *
# define GLCALLBACK __stdcall
# define GLCALLBACKP __stdcall *
# if defined(__CYGWIN__)
# define GLCALLBACKPCAST *
# else
# define GLCALLBACKPCAST __stdcall *
# endif
# define GLWINAPI __stdcall
# define GLWINAPIV __cdecl
#else
/* non-Windows compilation */
# define GLAPI extern
# define GLAPIENTRY
# define GLAPIENTRYP *
# define GLCALLBACK
# define GLCALLBACKP *
# define GLCALLBACKPCAST *
# define GLWINAPI
# define GLWINAPIV
#endif /* WIN32 / CYGWIN bracket */
/* compatibility guard so we don't need to change client code */
#if defined(_WIN32) && !defined(_WINDEF_) && !defined(_GNU_H_WINDOWS32_BASE) && !defined(OPENSTEP)
# define CALLBACK GLCALLBACK
typedef int (GLAPIENTRY *PROC)();
typedef void *HGLRC;
typedef void *HDC;
typedef unsigned long COLORREF;
#endif
#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP)
# define WGL_FONT_LINES 0
# define WGL_FONT_POLYGONS 1
#ifndef _GNU_H_WINDOWS32_FUNCTIONS
# ifdef UNICODE
# define wglUseFontBitmaps wglUseFontBitmapsW
# define wglUseFontOutlines wglUseFontOutlinesW
# else
# define wglUseFontBitmaps wglUseFontBitmapsA
# define wglUseFontOutlines wglUseFontOutlinesA
# endif /* !UNICODE */
#endif /* _GNU_H_WINDOWS32_FUNCTIONS */
typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR;
typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR;
#include <gl/mesa_wgl.h>
#endif
#ifndef GLU_TESS_ERROR9
/* If we're using the real OpenGL header files... */
# define GLU_TESS_ERROR9 100159
#endif
#define GLU_NO_ERROR GL_NO_ERROR
/* for Sun: */
#ifdef SUNOS4
#define MEMCPY( DST, SRC, BYTES) \
memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) )
#else
#define MEMCPY( DST, SRC, BYTES) \
memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) )
#endif
#ifndef NULL
# define NULL 0
#endif
#endif

View File

@@ -1,763 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.4
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#endif
/*
* Compute ceiling of integer quotient of A divided by B:
*/
#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
#ifdef EPSILON
#undef EPSILON
#endif
#define EPSILON 0.001
/* To work around optimizer bug in MSVC4.1 */
#if defined(__WIN32__) && !defined(OPENSTEP)
void
dummy(GLuint j, GLuint k)
{
}
#else
#define dummy(J, K)
#endif
GLint GLAPIENTRY
gluScaleImage(GLenum format,
GLsizei widthin, GLsizei heightin,
GLenum typein, const void *datain,
GLsizei widthout, GLsizei heightout,
GLenum typeout, void *dataout)
{
GLint components, i, j, k;
GLfloat *tempin, *tempout, f;
GLfloat sx, sy;
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
GLint packrowlength, packalignment, packskiprows, packskippixels;
GLint sizein, sizeout;
GLint rowstride, rowlen;
/* Determine number of components per pixel */
switch (format) {
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
components = 1;
break;
case GL_LUMINANCE_ALPHA:
components = 2;
break;
case GL_RGB:
case GL_BGR:
components = 3;
break;
case GL_RGBA:
case GL_BGRA:
#ifdef GL_EXT_abgr
case GL_ABGR_EXT:
#endif
components = 4;
break;
default:
return GLU_INVALID_ENUM;
}
/* Determine bytes per input datum */
switch (typein) {
case GL_UNSIGNED_BYTE:
sizein = sizeof(GLubyte);
break;
case GL_BYTE:
sizein = sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
sizein = sizeof(GLushort);
break;
case GL_SHORT:
sizein = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
sizein = sizeof(GLuint);
break;
case GL_INT:
sizein = sizeof(GLint);
break;
case GL_FLOAT:
sizein = sizeof(GLfloat);
break;
case GL_BITMAP:
/* not implemented yet */
default:
return GL_INVALID_ENUM;
}
/* Determine bytes per output datum */
switch (typeout) {
case GL_UNSIGNED_BYTE:
sizeout = sizeof(GLubyte);
break;
case GL_BYTE:
sizeout = sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
sizeout = sizeof(GLushort);
break;
case GL_SHORT:
sizeout = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
sizeout = sizeof(GLuint);
break;
case GL_INT:
sizeout = sizeof(GLint);
break;
case GL_FLOAT:
sizeout = sizeof(GLfloat);
break;
case GL_BITMAP:
/* not implemented yet */
default:
return GL_INVALID_ENUM;
}
/* Get glPixelStore state */
glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f;
glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f;
glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f;
glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f;
glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f;
glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f;
glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f;
glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f;
/* Allocate storage for intermediate images */
tempin = (GLfloat *) malloc(widthin * heightin
* components * sizeof(GLfloat));
if (!tempin) {
return GLU_OUT_OF_MEMORY;
}
tempout = (GLfloat *) malloc(widthout * heightout
* components * sizeof(GLfloat));
if (!tempout) {
free(tempin);
return GLU_OUT_OF_MEMORY;
}
/*
* Unpack the pixel data and convert to floating point
*/
if (unpackrowlength > 0) {
rowlen = unpackrowlength;
}
else {
rowlen = widthin;
}
if (sizein >= unpackalignment) {
rowstride = components * rowlen;
}
else {
rowstride = unpackalignment / sizein
* CEILING(components * rowlen * sizein, unpackalignment);
}
switch (typein) {
case GL_UNSIGNED_BYTE:
k = 0;
for (i = 0; i < heightin; i++) {
GLubyte *ubptr = (GLubyte *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * ubptr++;
}
}
break;
case GL_BYTE:
k = 0;
for (i = 0; i < heightin; i++) {
GLbyte *bptr = (GLbyte *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * bptr++;
}
}
break;
case GL_UNSIGNED_SHORT:
k = 0;
for (i = 0; i < heightin; i++) {
GLushort *usptr = (GLushort *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * usptr++;
}
}
break;
case GL_SHORT:
k = 0;
for (i = 0; i < heightin; i++) {
GLshort *sptr = (GLshort *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * sptr++;
}
}
break;
case GL_UNSIGNED_INT:
k = 0;
for (i = 0; i < heightin; i++) {
GLuint *uiptr = (GLuint *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * uiptr++;
}
}
break;
case GL_INT:
k = 0;
for (i = 0; i < heightin; i++) {
GLint *iptr = (GLint *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * iptr++;
}
}
break;
case GL_FLOAT:
k = 0;
for (i = 0; i < heightin; i++) {
GLfloat *fptr = (GLfloat *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = *fptr++;
}
}
break;
default:
return GLU_INVALID_ENUM;
}
/*
* Scale the image!
*/
if (widthout > 1)
sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1);
else
sx = (GLfloat) (widthin - 1);
if (heightout > 1)
sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1);
else
sy = (GLfloat) (heightin - 1);
/*#define POINT_SAMPLE*/
#ifdef POINT_SAMPLE
for (i = 0; i < heightout; i++) {
GLint ii = i * sy;
for (j = 0; j < widthout; j++) {
GLint jj = j * sx;
GLfloat *src = tempin + (ii * widthin + jj) * components;
GLfloat *dst = tempout + (i * widthout + j) * components;
for (k = 0; k < components; k++) {
*dst++ = *src++;
}
}
}
#else
if (sx < 1.0 && sy < 1.0) {
/* magnify both width and height: use weighted sample of 4 pixels */
GLint i0, i1, j0, j1;
GLfloat alpha, beta;
GLfloat *src00, *src01, *src10, *src11;
GLfloat s1, s2;
GLfloat *dst;
for (i = 0; i < heightout; i++) {
i0 = i * sy;
i1 = i0 + 1;
if (i1 >= heightin)
i1 = heightin - 1;
/* i1 = (i+1) * sy - EPSILON;*/
alpha = i * sy - i0;
for (j = 0; j < widthout; j++) {
j0 = j * sx;
j1 = j0 + 1;
if (j1 >= widthin)
j1 = widthin - 1;
/* j1 = (j+1) * sx - EPSILON; */
beta = j * sx - j0;
/* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
src00 = tempin + (i0 * widthin + j0) * components;
src01 = tempin + (i0 * widthin + j1) * components;
src10 = tempin + (i1 * widthin + j0) * components;
src11 = tempin + (i1 * widthin + j1) * components;
dst = tempout + (i * widthout + j) * components;
for (k = 0; k < components; k++) {
s1 = *src00++ * (1.0 - beta) + *src01++ * beta;
s2 = *src10++ * (1.0 - beta) + *src11++ * beta;
*dst++ = s1 * (1.0 - alpha) + s2 * alpha;
}
}
}
}
else {
/* shrink width and/or height: use an unweighted box filter */
GLint i0, i1;
GLint j0, j1;
GLint ii, jj;
GLfloat sum, *dst;
for (i = 0; i < heightout; i++) {
i0 = i * sy;
i1 = i0 + 1;
if (i1 >= heightin)
i1 = heightin - 1;
/* i1 = (i+1) * sy - EPSILON; */
for (j = 0; j < widthout; j++) {
j0 = j * sx;
j1 = j0 + 1;
if (j1 >= widthin)
j1 = widthin - 1;
/* j1 = (j+1) * sx - EPSILON; */
dst = tempout + (i * widthout + j) * components;
/* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
for (k = 0; k < components; k++) {
sum = 0.0;
for (ii = i0; ii <= i1; ii++) {
for (jj = j0; jj <= j1; jj++) {
sum += *(tempin + (ii * widthin + jj) * components + k);
}
}
sum /= (j1 - j0 + 1) * (i1 - i0 + 1);
*dst++ = sum;
}
}
}
}
#endif
/*
* Return output image
*/
if (packrowlength > 0) {
rowlen = packrowlength;
}
else {
rowlen = widthout;
}
if (sizeout >= packalignment) {
rowstride = components * rowlen;
}
else {
rowstride = packalignment / sizeout
* CEILING(components * rowlen * sizeout, packalignment);
}
switch (typeout) {
case GL_UNSIGNED_BYTE:
k = 0;
for (i = 0; i < heightout; i++) {
GLubyte *ubptr = (GLubyte *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*ubptr++ = (GLubyte) tempout[k++];
}
}
break;
case GL_BYTE:
k = 0;
for (i = 0; i < heightout; i++) {
GLbyte *bptr = (GLbyte *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*bptr++ = (GLbyte) tempout[k++];
}
}
break;
case GL_UNSIGNED_SHORT:
k = 0;
for (i = 0; i < heightout; i++) {
GLushort *usptr = (GLushort *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*usptr++ = (GLushort) tempout[k++];
}
}
break;
case GL_SHORT:
k = 0;
for (i = 0; i < heightout; i++) {
GLshort *sptr = (GLshort *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*sptr++ = (GLshort) tempout[k++];
}
}
break;
case GL_UNSIGNED_INT:
k = 0;
for (i = 0; i < heightout; i++) {
GLuint *uiptr = (GLuint *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*uiptr++ = (GLuint) tempout[k++];
}
}
break;
case GL_INT:
k = 0;
for (i = 0; i < heightout; i++) {
GLint *iptr = (GLint *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*iptr++ = (GLint) tempout[k++];
}
}
break;
case GL_FLOAT:
k = 0;
for (i = 0; i < heightout; i++) {
GLfloat *fptr = (GLfloat *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*fptr++ = tempout[k++];
}
}
break;
default:
return GLU_INVALID_ENUM;
}
/* free temporary image storage */
free(tempin);
free(tempout);
return 0;
}
/*
* Return the largest k such that 2^k <= n.
*/
static GLint
ilog2(GLint n)
{
GLint k;
if (n <= 0)
return 0;
for (k = 0; n >>= 1; k++);
return k;
}
/*
* Find the value nearest to n which is also a power of two.
*/
static GLint
round2(GLint n)
{
GLint m;
for (m = 1; m < n; m *= 2);
/* m>=n */
if (m - n <= n - m / 2) {
return m;
}
else {
return m / 2;
}
}
/*
* Given an pixel format and data type, return the number of bytes to
* store one pixel.
*/
static GLint
bytes_per_pixel(GLenum format, GLenum type)
{
GLint n, m;
switch (format) {
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
n = 1;
break;
case GL_LUMINANCE_ALPHA:
n = 2;
break;
case GL_RGB:
case GL_BGR:
n = 3;
break;
case GL_RGBA:
case GL_BGRA:
#ifdef GL_EXT_abgr
case GL_ABGR_EXT:
#endif
n = 4;
break;
default:
n = 0;
}
switch (type) {
case GL_UNSIGNED_BYTE:
m = sizeof(GLubyte);
break;
case GL_BYTE:
m = sizeof(GLbyte);
break;
case GL_BITMAP:
m = 1;
break;
case GL_UNSIGNED_SHORT:
m = sizeof(GLushort);
break;
case GL_SHORT:
m = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
m = sizeof(GLuint);
break;
case GL_INT:
m = sizeof(GLint);
break;
case GL_FLOAT:
m = sizeof(GLfloat);
break;
default:
m = 0;
}
return n * m;
}
/*
* WARNING: This function isn't finished and has never been tested!!!!
*/
GLint GLAPIENTRY
gluBuild1DMipmaps(GLenum target, GLint components,
GLsizei width, GLenum format, GLenum type, const void *data)
{
return 0;
}
GLint GLAPIENTRY
gluBuild2DMipmaps(GLenum target, GLint components,
GLsizei width, GLsizei height, GLenum format,
GLenum type, const void *data)
{
GLint w, h;
GLint maxsize;
void *image, *newimage;
GLint neww, newh, level, bpp;
int error;
GLboolean done;
GLint retval = 0;
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
GLint packrowlength, packalignment, packskiprows, packskippixels;
GLfloat f;
if (width < 1 || height < 1)
return GLU_INVALID_VALUE;
glGetFloatv(GL_MAX_TEXTURE_SIZE, &f); maxsize = (int)f;
w = round2(width);
if (w > maxsize) {
w = maxsize;
}
h = round2(height);
if (h > maxsize) {
h = maxsize;
}
bpp = bytes_per_pixel(format, type);
if (bpp == 0) {
/* probably a bad format or type enum */
return GLU_INVALID_ENUM;
}
/* Get current glPixelStore values */
glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f;
glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f;
glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f;
glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f;
glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f;
glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f;
glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f;
glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f;
/* set pixel packing */
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
done = GL_FALSE;
if (w != width || h != height) {
/* must rescale image to get "top" mipmap texture image */
image = malloc((w + 4) * h * bpp);
if (!image) {
return GLU_OUT_OF_MEMORY;
}
error = gluScaleImage(format, width, height, type, data,
w, h, type, image);
if (error) {
retval = error;
done = GL_TRUE;
}
}
else {
image = (void *) data;
}
level = 0;
while (!done) {
if (image != data) {
/* set pixel unpacking */
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
}
glTexImage2D(target, level, components, w, h, 0, format, type, image);
if (w == 1 && h == 1)
break;
neww = (w < 2) ? 1 : w / 2;
newh = (h < 2) ? 1 : h / 2;
newimage = malloc((neww + 4) * newh * bpp);
if (!newimage) {
return GLU_OUT_OF_MEMORY;
}
error = gluScaleImage(format, w, h, type, image,
neww, newh, type, newimage);
if (error) {
retval = error;
done = GL_TRUE;
}
if (image != data) {
free(image);
}
image = newimage;
w = neww;
h = newh;
level++;
}
if (image != data) {
free(image);
}
/* Restore original glPixelStore state */
glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);
return retval;
}

View File

@@ -1,157 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#include "nurbs.h"
#endif
void
call_user_error(GLUnurbsObj * nobj, GLenum error)
{
nobj->error = error;
if (nobj->error_callback != NULL) {
(*(nobj->error_callback)) (error);
}
else {
printf("NURBS error %d %s\n", error, (char *) gluErrorString(error));
}
}
GLUnurbsObj *GLAPIENTRY
gluNewNurbsRenderer(void)
{
GLUnurbsObj *n;
GLfloat tmp_viewport[4];
GLint i, j;
n = (GLUnurbsObj *) malloc(sizeof(GLUnurbsObj));
return n;
}
void GLAPIENTRY
gluDeleteNurbsRenderer(GLUnurbsObj * nobj)
{
if (nobj) {
free(nobj);
}
}
void GLAPIENTRY
gluLoadSamplingMatrices(GLUnurbsObj * nobj,
const GLfloat modelMatrix[16],
const GLfloat projMatrix[16], const GLint viewport[4])
{
}
void GLAPIENTRY
gluNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat value)
{
}
void GLAPIENTRY
gluGetNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat * value)
{
}
void GLAPIENTRY
gluBeginCurve(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluEndCurve(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluNurbsCurve(GLUnurbsObj * nobj, GLint nknots, GLfloat * knot,
GLint stride, GLfloat * ctlarray, GLint order, GLenum type)
{
}
void GLAPIENTRY
gluBeginSurface(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluEndSurface(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluNurbsSurface(GLUnurbsObj * nobj,
GLint sknot_count, GLfloat * sknot,
GLint tknot_count, GLfloat * tknot,
GLint s_stride, GLint t_stride,
GLfloat * ctrlarray, GLint sorder, GLint torder, GLenum type)
{
}
void GLAPIENTRY
gluNurbsCallback(GLUnurbsObj * nobj, GLenum which, void (GLCALLBACK * fn) ())
{
}
void GLAPIENTRY
gluBeginTrim(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluPwlCurve(GLUnurbsObj * nobj, GLint count, GLfloat * array, GLint stride,
GLenum type)
{
}
void GLAPIENTRY
gluEndTrim(GLUnurbsObj * nobj)
{
}

View File

@@ -1,252 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifndef NURBS_H
#define NURBS_H
#define EPSILON 1e-06 /* epsilon for double precision compares */
typedef enum
{
GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM,
GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE
}
GLU_nurbs_enum;
typedef enum
{
GLU_TRIM_NURBS, GLU_TRIM_PWL
}
GLU_trim_enum;
typedef struct
{
GLint sknot_count;
GLfloat *sknot;
GLint tknot_count;
GLfloat *tknot;
GLint s_stride;
GLint t_stride;
GLfloat *ctrlarray;
GLint sorder;
GLint torder;
GLint dim;
GLenum type;
}
surface_attribs;
typedef struct
{
surface_attribs geom;
surface_attribs color;
surface_attribs texture;
surface_attribs normal;
}
nurbs_surface;
typedef struct
{
GLint knot_count;
GLfloat *knot;
GLint stride;
GLfloat *ctrlarray;
GLint order;
GLint dim;
GLenum type;
}
curve_attribs;
typedef struct
{
GLint pt_count;
GLfloat *ctrlarray;
GLint stride;
GLint dim;
GLenum type;
}
pwl_curve_attribs;
typedef struct
{
curve_attribs geom;
curve_attribs color;
curve_attribs texture;
curve_attribs normal;
}
nurbs_curve;
typedef struct trim_list_str
{
GLU_trim_enum trim_type;
union
{
pwl_curve_attribs pwl_curve;
curve_attribs nurbs_curve;
}
curve;
struct trim_list_str *next;
}
trim_list;
typedef struct seg_trim_str
{
GLfloat *points;
GLint pt_cnt, seg_array_len;
struct seg_trim_str *next;
}
trim_segments;
typedef struct nurbs_trim_str
{
trim_list *trim_loop;
trim_segments *segments;
struct nurbs_trim_str *next;
}
nurbs_trim;
typedef struct
{
GLfloat model[16], proj[16], viewport[4];
}
culling_and_sampling_str;
struct GLUnurbs
{
GLboolean culling;
GLenum error;
void (GLCALLBACK * error_callback) (GLenum err);
GLenum display_mode;
GLU_nurbs_enum nurbs_type;
GLboolean auto_load_matrix;
culling_and_sampling_str sampling_matrices;
GLenum sampling_method;
GLfloat sampling_tolerance;
GLfloat parametric_tolerance;
GLint u_step, v_step;
nurbs_surface surface;
nurbs_curve curve;
nurbs_trim *trim;
};
typedef struct
{
GLfloat *knot;
GLint nknots;
GLfloat *unified_knot;
GLint unified_nknots;
GLint order;
GLint t_min, t_max;
GLint delta_nknots;
GLboolean open_at_begin, open_at_end;
GLfloat *new_knot;
GLfloat *alpha;
}
knot_str_type;
typedef struct
{
GLfloat *geom_ctrl;
GLint geom_s_stride, geom_t_stride;
GLfloat **geom_offsets;
GLint geom_s_pt_cnt, geom_t_pt_cnt;
GLfloat *color_ctrl;
GLint color_s_stride, color_t_stride;
GLfloat **color_offsets;
GLint color_s_pt_cnt, color_t_pt_cnt;
GLfloat *normal_ctrl;
GLint normal_s_stride, normal_t_stride;
GLfloat **normal_offsets;
GLint normal_s_pt_cnt, normal_t_pt_cnt;
GLfloat *texture_ctrl;
GLint texture_s_stride, texture_t_stride;
GLfloat **texture_offsets;
GLint texture_s_pt_cnt, texture_t_pt_cnt;
GLint s_bezier_cnt, t_bezier_cnt;
}
new_ctrl_type;
extern void call_user_error(GLUnurbsObj * nobj, GLenum error);
extern GLenum test_knot(GLint nknots, GLfloat * knot, GLint order);
extern GLenum explode_knot(knot_str_type * the_knot);
extern GLenum calc_alphas(knot_str_type * the_knot);
extern GLenum calc_new_ctrl_pts(GLfloat * ctrl, GLint stride,
knot_str_type * the_knot, GLint dim,
GLfloat ** new_ctrl, GLint * ncontrol);
extern GLenum glu_do_sampling_crv(GLUnurbsObj * nobj, GLfloat * new_ctrl,
GLint n_ctrl, GLint order, GLint dim,
GLint ** factors);
extern GLenum glu_do_sampling_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLenum glu_do_sampling_uv(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLenum glu_do_sampling_param_3D(GLUnurbsObj * nobj,
new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLboolean fine_culling_test_2D(GLUnurbsObj * nobj, GLfloat * ctrl,
GLint n_ctrl, GLint stride, GLint dim);
extern GLboolean fine_culling_test_3D(GLUnurbsObj * nobj, GLfloat * ctrl,
GLint s_n_ctrl, GLint t_n_ctrl,
GLint s_stride, GLint t_stride,
GLint dim);
extern void do_nurbs_curve(GLUnurbsObj * nobj);
extern void do_nurbs_surface(GLUnurbsObj * nobj);
extern GLenum patch_trimming(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
GLint * sfactors, GLint * tfactors);
extern void collect_unified_knot(knot_str_type * dest, knot_str_type * src,
GLfloat maximal_min_knot,
GLfloat minimal_max_knot);
extern GLenum select_knot_working_range(GLUnurbsObj * nobj,
knot_str_type * geom_knot,
knot_str_type * color_knot,
knot_str_type * normal_knot,
knot_str_type * texture_knot);
extern void free_unified_knots(knot_str_type * geom_knot,
knot_str_type * color_knot,
knot_str_type * normal_knot,
knot_str_type * texture_knot);
#endif

View File

@@ -1,132 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "gluP.h"
#include "nurbs.h"
#endif
/* main NURBS curve procedure */
void
do_nurbs_curve(GLUnurbsObj * nobj)
{
GLint geom_order, color_order = 0, normal_order = 0, texture_order = 0;
GLenum geom_type;
GLint n_ctrl;
GLfloat *new_geom_ctrl, *new_color_ctrl, *new_normal_ctrl,
*new_texture_ctrl;
GLfloat *geom_ctrl = 0, *color_ctrl = 0, *normal_ctrl = 0, *texture_ctrl = 0;
GLint *factors;
GLint i, j;
GLint geom_dim, color_dim = 0, normal_dim = 0, texture_dim = 0;
/* test the user supplied data */
if (test_nurbs_curves(nobj) != GLU_NO_ERROR)
return;
if (convert_curves(nobj, &new_geom_ctrl, &n_ctrl, &new_color_ctrl,
&new_normal_ctrl, &new_texture_ctrl) != GLU_NO_ERROR)
return;
geom_order = nobj->curve.geom.order;
geom_type = nobj->curve.geom.type;
geom_dim = nobj->curve.geom.dim;
if (glu_do_sampling_crv(nobj, new_geom_ctrl, n_ctrl, geom_order, geom_dim,
&factors) != GLU_NO_ERROR) {
free(new_geom_ctrl);
if (new_color_ctrl)
free(new_color_ctrl);
if (new_normal_ctrl)
free(new_normal_ctrl);
if (new_texture_ctrl)
free(new_texture_ctrl);
return;
}
glEnable(geom_type);
if (new_color_ctrl) {
glEnable(nobj->curve.color.type);
color_dim = nobj->curve.color.dim;
color_ctrl = new_color_ctrl;
color_order = nobj->curve.color.order;
}
if (new_normal_ctrl) {
glEnable(nobj->curve.normal.type);
normal_dim = nobj->curve.normal.dim;
normal_ctrl = new_normal_ctrl;
normal_order = nobj->curve.normal.order;
}
if (new_texture_ctrl) {
glEnable(nobj->curve.texture.type);
texture_dim = nobj->curve.texture.dim;
texture_ctrl = new_texture_ctrl;
texture_order = nobj->curve.texture.order;
}
for (i = 0, j = 0, geom_ctrl = new_geom_ctrl;
i < n_ctrl; i += geom_order, j++, geom_ctrl += geom_order * geom_dim) {
if (fine_culling_test_2D
(nobj, geom_ctrl, geom_order, geom_dim, geom_dim)) {
color_ctrl += color_order * color_dim;
normal_ctrl += normal_order * normal_dim;
texture_ctrl += texture_order * texture_dim;
continue;
}
glMap1f(geom_type, 0.0, 1.0, geom_dim, geom_order, geom_ctrl);
if (new_color_ctrl) {
glMap1f(nobj->curve.color.type, 0.0, 1.0, color_dim,
color_order, color_ctrl);
color_ctrl += color_order * color_dim;
}
if (new_normal_ctrl) {
glMap1f(nobj->curve.normal.type, 0.0, 1.0, normal_dim,
normal_order, normal_ctrl);
normal_ctrl += normal_order * normal_dim;
}
if (new_texture_ctrl) {
glMap1f(nobj->curve.texture.type, 0.0, 1.0, texture_dim,
texture_order, texture_ctrl);
texture_ctrl += texture_order * texture_dim;
}
glMapGrid1f(factors[j], 0.0, 1.0);
glEvalMesh1(GL_LINE, 0, factors[j]);
}
free(new_geom_ctrl);
free(factors);
if (new_color_ctrl)
free(new_color_ctrl);
if (new_normal_ctrl)
free(new_normal_ctrl);
if (new_texture_ctrl)
free(new_texture_ctrl);
}

View File

@@ -1,937 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "gluP.h"
#include "tess.h"
#endif
static GLenum store_polygon_as_contour(GLUtriangulatorObj *);
static void free_current_polygon(tess_polygon *);
static void prepare_projection_info(GLUtriangulatorObj *);
static GLdouble twice_the_polygon_area(tess_vertex *, tess_vertex *);
static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *);
void tess_find_contour_hierarchies(GLUtriangulatorObj *);
static GLenum test_for_overlapping_contours(GLUtriangulatorObj *);
static GLenum contours_overlap(tess_contour *, tess_polygon *);
static GLenum is_contour_contained_in(tess_contour *, tess_contour *);
static void add_new_exterior(GLUtriangulatorObj *, tess_contour *);
static void add_new_interior(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static void add_interior_with_hierarchy_check(GLUtriangulatorObj *,
tess_contour *, tess_contour *);
static void reverse_hierarchy_and_add_exterior(GLUtriangulatorObj *,
tess_contour *,
tess_contour *);
static GLboolean point_in_polygon(tess_contour *, GLdouble, GLdouble);
static void shift_interior_to_exterior(GLUtriangulatorObj *, tess_contour *);
static void add_exterior_with_check(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static GLenum cut_out_hole(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static GLenum merge_hole_with_contour(GLUtriangulatorObj *,
tess_contour *, tess_contour *,
tess_vertex *, tess_vertex *);
static GLenum
find_normal(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *va, *vb, *vc;
GLdouble A, B, C;
GLdouble A0, A1, A2, B0, B1, B2;
va = polygon->vertices;
vb = va->next;
A0 = vb->location[0] - va->location[0];
A1 = vb->location[1] - va->location[1];
A2 = vb->location[2] - va->location[2];
for (vc = vb->next; vc != va; vc = vc->next) {
B0 = vc->location[0] - va->location[0];
B1 = vc->location[1] - va->location[1];
B2 = vc->location[2] - va->location[2];
A = A1 * B2 - A2 * B1;
B = A2 * B0 - A0 * B2;
C = A0 * B1 - A1 * B0;
if (fabs(A) > EPSILON || fabs(B) > EPSILON || fabs(C) > EPSILON) {
polygon->A = A;
polygon->B = B;
polygon->C = C;
polygon->D =
-A * va->location[0] - B * va->location[1] - C * va->location[2];
return GLU_NO_ERROR;
}
}
tess_call_user_error(tobj, GLU_TESS_ERROR7);
return GLU_ERROR;
}
void
tess_test_polygon(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
/* any vertices defined? */
if (polygon->vertex_cnt < 3) {
free_current_polygon(polygon);
return;
}
/* wrap pointers */
polygon->last_vertex->next = polygon->vertices;
polygon->vertices->previous = polygon->last_vertex;
/* determine the normal */
if (find_normal(tobj) == GLU_ERROR)
return;
/* compare the normals of previously defined contours and this one */
/* first contour define ? */
if (tobj->contours == NULL) {
tobj->A = polygon->A;
tobj->B = polygon->B;
tobj->C = polygon->C;
tobj->D = polygon->D;
/* determine the best projection to use */
if (fabs(polygon->A) > fabs(polygon->B))
if (fabs(polygon->A) > fabs(polygon->C))
tobj->projection = OYZ;
else
tobj->projection = OXY;
else if (fabs(polygon->B) > fabs(polygon->C))
tobj->projection = OXZ;
else
tobj->projection = OXY;
}
else {
GLdouble a[3], b[3];
tess_vertex *vertex = polygon->vertices;
a[0] = tobj->A;
a[1] = tobj->B;
a[2] = tobj->C;
b[0] = polygon->A;
b[1] = polygon->B;
b[2] = polygon->C;
/* compare the normals */
if (fabs(a[1] * b[2] - a[2] * b[1]) > EPSILON ||
fabs(a[2] * b[0] - a[0] * b[2]) > EPSILON ||
fabs(a[0] * b[1] - a[1] * b[0]) > EPSILON) {
/* not coplanar */
tess_call_user_error(tobj, GLU_TESS_ERROR9);
return;
}
/* the normals are parallel - test for plane equation */
if (fabs(a[0] * vertex->location[0] + a[1] * vertex->location[1] +
a[2] * vertex->location[2] + tobj->D) > EPSILON) {
/* not the same plane */
tess_call_user_error(tobj, GLU_TESS_ERROR9);
return;
}
}
prepare_projection_info(tobj);
if (verify_edge_vertex_intersections(tobj) == GLU_ERROR)
return;
if (test_for_overlapping_contours(tobj) == GLU_ERROR)
return;
if (store_polygon_as_contour(tobj) == GLU_ERROR)
return;
}
static GLenum
test_for_overlapping_contours(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
tess_polygon *polygon;
polygon = tobj->current_polygon;
for (contour = tobj->contours; contour != NULL; contour = contour->next)
if (contours_overlap(contour, polygon) != GLU_NO_ERROR) {
tess_call_user_error(tobj, GLU_TESS_ERROR5);
return GLU_ERROR;
}
return GLU_NO_ERROR;
}
static GLenum
store_polygon_as_contour(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_contour *contour = tobj->contours;
/* the first contour defined */
if (contour == NULL) {
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
free_current_polygon(polygon);
return GLU_ERROR;
}
tobj->contours = tobj->last_contour = contour;
contour->next = contour->previous = NULL;
}
else {
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
free_current_polygon(polygon);
return GLU_ERROR;
}
contour->previous = tobj->last_contour;
tobj->last_contour->next = contour;
tobj->last_contour = contour;
contour->next = NULL;
}
/* mark all vertices in new contour as not special */
/* and all are boundary edges */
{
tess_vertex *vertex;
GLuint vertex_cnt, i;
for (vertex = polygon->vertices, i = 0, vertex_cnt =
polygon->vertex_cnt; i < vertex_cnt; vertex = vertex->next, i++) {
vertex->shadow_vertex = NULL;
vertex->edge_flag = GL_TRUE;
}
}
contour->vertex_cnt = polygon->vertex_cnt;
contour->area = polygon->area;
contour->orientation = polygon->orientation;
contour->type = GLU_UNKNOWN;
contour->vertices = polygon->vertices;
contour->last_vertex = polygon->last_vertex;
polygon->vertices = polygon->last_vertex = NULL;
polygon->vertex_cnt = 0;
++(tobj->contour_cnt);
return GLU_NO_ERROR;
}
static void
free_current_polygon(tess_polygon * polygon)
{
tess_vertex *vertex, *vertex_tmp;
GLuint i;
/* free current_polygon structures */
for (vertex = polygon->vertices, i = 0; i < polygon->vertex_cnt; i++) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
polygon->vertices = polygon->last_vertex = NULL;
polygon->vertex_cnt = 0;
}
static void
prepare_projection_info(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *vertex, *last_vertex_ptr;
GLdouble area;
last_vertex_ptr = polygon->last_vertex;
switch (tobj->projection) {
case OXY:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[0];
vertex->y = vertex->location[1];
}
last_vertex_ptr->x = last_vertex_ptr->location[0];
last_vertex_ptr->y = last_vertex_ptr->location[1];
break;
case OXZ:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[0];
vertex->y = vertex->location[2];
}
last_vertex_ptr->x = last_vertex_ptr->location[0];
last_vertex_ptr->y = last_vertex_ptr->location[2];
break;
case OYZ:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[1];
vertex->y = vertex->location[2];
}
last_vertex_ptr->x = last_vertex_ptr->location[1];
last_vertex_ptr->y = last_vertex_ptr->location[2];
break;
}
area = twice_the_polygon_area(polygon->vertices, polygon->last_vertex);
if (area >= 0.0) {
polygon->orientation = GLU_CCW;
polygon->area = area;
}
else {
polygon->orientation = GLU_CW;
polygon->area = -area;
}
}
static GLdouble
twice_the_polygon_area(tess_vertex * vertex, tess_vertex * last_vertex)
{
tess_vertex *next;
GLdouble area, x, y;
area = 0.0;
x = vertex->x;
y = vertex->y;
vertex = vertex->next;
for (; vertex != last_vertex; vertex = vertex->next) {
next = vertex->next;
area +=
(vertex->x - x) * (next->y - y) - (vertex->y - y) * (next->x - x);
}
return area;
}
/* test if edges ab and cd intersect */
/* if not return GLU_NO_ERROR, else if cross return GLU_TESS_ERROR8, */
/* else if adjacent return GLU_TESS_ERROR4 */
static GLenum
edge_edge_intersect(tess_vertex * a,
tess_vertex * b, tess_vertex * c, tess_vertex * d)
{
GLdouble denom, r, s;
GLdouble xba, ydc, yba, xdc, yac, xac;
xba = b->x - a->x;
yba = b->y - a->y;
xdc = d->x - c->x;
ydc = d->y - c->y;
xac = a->x - c->x;
yac = a->y - c->y;
denom = xba * ydc - yba * xdc;
r = yac * xdc - xac * ydc;
/* parallel? */
if (fabs(denom) < EPSILON) {
if (fabs(r) < EPSILON) {
/* colinear */
if (fabs(xba) < EPSILON) {
/* compare the Y coordinate */
if (yba > 0.0) {
if (
(fabs(a->y - c->y) < EPSILON
&& fabs(c->y - b->y) < EPSILON)
|| (fabs(a->y - d->y) < EPSILON
&& fabs(d->y - b->y) <
EPSILON)) return GLU_TESS_ERROR4;
}
else {
if (
(fabs(b->y - c->y) < EPSILON
&& fabs(c->y - a->y) < EPSILON)
|| (fabs(b->y - d->y) < EPSILON
&& fabs(d->y - a->y) <
EPSILON)) return GLU_TESS_ERROR4;
}
}
else {
/* compare the X coordinate */
if (xba > 0.0) {
if (
(fabs(a->x - c->x) < EPSILON
&& fabs(c->x - b->x) < EPSILON)
|| (fabs(a->x - d->x) < EPSILON
&& fabs(d->x - b->x) <
EPSILON)) return GLU_TESS_ERROR4;
}
else {
if (
(fabs(b->x - c->x) < EPSILON
&& fabs(c->x - a->x) < EPSILON)
|| (fabs(b->x - d->x) < EPSILON
&& fabs(d->x - a->x) <
EPSILON)) return GLU_TESS_ERROR4;
}
}
}
return GLU_NO_ERROR;
}
r /= denom;
s = (yac * xba - xac * yba) / denom;
/* test if one vertex lies on other edge */
if (((fabs(r) < EPSILON || (r < 1.0 + EPSILON && r > 1.0 - EPSILON)) &&
s > -EPSILON && s < 1.0 + EPSILON) ||
((fabs(s) < EPSILON || (s < 1.0 + EPSILON && s > 1.0 - EPSILON)) &&
r > -EPSILON && r < 1.0 + EPSILON)) {
return GLU_TESS_ERROR4;
}
/* test for crossing */
if (r > -EPSILON && r < 1.0 + EPSILON && s > -EPSILON && s < 1.0 + EPSILON) {
return GLU_TESS_ERROR8;
}
return GLU_NO_ERROR;
}
static GLenum
verify_edge_vertex_intersections(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *vertex1, *last_vertex, *vertex2;
GLenum test;
last_vertex = polygon->last_vertex;
vertex1 = last_vertex;
for (vertex2 = vertex1->next->next;
vertex2->next != last_vertex; vertex2 = vertex2->next) {
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next);
if (test != GLU_NO_ERROR) {
tess_call_user_error(tobj, test);
return GLU_ERROR;
}
}
for (vertex1 = polygon->vertices;
vertex1->next->next != last_vertex; vertex1 = vertex1->next) {
for (vertex2 = vertex1->next->next;
vertex2 != last_vertex; vertex2 = vertex2->next) {
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next);
if (test != GLU_NO_ERROR) {
tess_call_user_error(tobj, test);
return GLU_ERROR;
}
}
}
return GLU_NO_ERROR;
}
static int
#ifdef WIN32
__cdecl
#endif
area_compare(const void *a, const void *b)
{
GLdouble area1, area2;
area1 = (*((tess_contour **) a))->area;
area2 = (*((tess_contour **) b))->area;
if (area1 < area2)
return 1;
if (area1 > area2)
return -1;
return 0;
}
void
tess_find_contour_hierarchies(GLUtriangulatorObj * tobj)
{
tess_contour **contours; /* dinamic array of pointers */
tess_contour *tmp_contour_ptr = tobj->contours;
GLuint cnt, i;
GLenum result;
GLboolean hierarchy_changed;
/* any contours? */
if (tobj->contour_cnt < 2) {
tobj->contours->type = GLU_EXTERIOR;
return;
}
if ((contours = (tess_contour **)
malloc(sizeof(tess_contour *) * (tobj->contour_cnt))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
for (tmp_contour_ptr = tobj->contours, cnt = 0;
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next)
contours[cnt++] = tmp_contour_ptr;
/* now sort the contours in decreasing area size order */
qsort((void *) contours, (size_t) cnt, (size_t) sizeof(tess_contour *),
area_compare);
/* we leave just the first contour - remove others from list */
tobj->contours = contours[0];
tobj->contours->next = tobj->contours->previous = NULL;
tobj->last_contour = tobj->contours;
tobj->contour_cnt = 1;
/* first contour is the one with greatest area */
/* must be EXTERIOR */
tobj->contours->type = GLU_EXTERIOR;
tmp_contour_ptr = tobj->contours;
/* now we play! */
for (i = 1; i < cnt; i++) {
hierarchy_changed = GL_FALSE;
for (tmp_contour_ptr = tobj->contours;
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next) {
if (tmp_contour_ptr->type == GLU_EXTERIOR) {
/* check if contour completely contained in EXTERIOR */
result = is_contour_contained_in(tmp_contour_ptr, contours[i]);
switch (result) {
case GLU_INTERIOR:
/* now we have to check if contour is inside interiors */
/* or not */
/* any interiors? */
if (tmp_contour_ptr->next != NULL &&
tmp_contour_ptr->next->type == GLU_INTERIOR) {
/* for all interior, check if inside any of them */
/* if not inside any of interiors, its another */
/* interior */
/* or it may contain some interiors, then change */
/* the contained interiors to exterior ones */
add_interior_with_hierarchy_check(tobj,
tmp_contour_ptr,
contours[i]);
}
else {
/* not in interior, add as new interior contour */
add_new_interior(tobj, tmp_contour_ptr, contours[i]);
}
hierarchy_changed = GL_TRUE;
break;
case GLU_EXTERIOR:
/* ooops, the marked as EXTERIOR (contours[i]) is */
/* actually an interior of tmp_contour_ptr */
/* reverse the local hierarchy */
reverse_hierarchy_and_add_exterior(tobj, tmp_contour_ptr,
contours[i]);
hierarchy_changed = GL_TRUE;
break;
case GLU_NO_ERROR:
break;
default:
abort();
}
}
if (hierarchy_changed)
break; /* break from for loop */
}
if (hierarchy_changed == GL_FALSE) {
/* disjoint with all contours, add to contour list */
add_new_exterior(tobj, contours[i]);
}
}
free(contours);
}
/* returns GLU_INTERIOR if inner is completey enclosed within outer */
/* returns GLU_EXTERIOR if outer is completely enclosed within inner */
/* returns GLU_NO_ERROR if contours are disjoint */
static GLenum
is_contour_contained_in(tess_contour * outer, tess_contour * inner)
{
GLenum relation_flag;
/* set relation_flag to relation of containment of first inner vertex */
/* regarding outer contour */
if (point_in_polygon(outer, inner->vertices->x, inner->vertices->y))
relation_flag = GLU_INTERIOR;
else
relation_flag = GLU_EXTERIOR;
if (relation_flag == GLU_INTERIOR)
return GLU_INTERIOR;
if (point_in_polygon(inner, outer->vertices->x, outer->vertices->y))
return GLU_EXTERIOR;
return GLU_NO_ERROR;
}
static GLboolean
point_in_polygon(tess_contour * contour, GLdouble x, GLdouble y)
{
tess_vertex *v1, *v2;
GLuint i, vertex_cnt;
GLdouble xp1, yp1, xp2, yp2;
GLboolean tst;
tst = GL_FALSE;
v1 = contour->vertices;
v2 = contour->vertices->previous;
for (i = 0, vertex_cnt = contour->vertex_cnt; i < vertex_cnt; i++) {
xp1 = v1->x;
yp1 = v1->y;
xp2 = v2->x;
yp2 = v2->y;
if ((((yp1 <= y) && (y < yp2)) || ((yp2 <= y) && (y < yp1))) &&
(x < (xp2 - xp1) * (y - yp1) / (yp2 - yp1) + xp1))
tst = (tst == GL_FALSE ? GL_TRUE : GL_FALSE);
v2 = v1;
v1 = v1->next;
}
return tst;
}
static GLenum
contours_overlap(tess_contour * contour, tess_polygon * polygon)
{
tess_vertex *vertex1, *vertex2;
GLuint vertex1_cnt, vertex2_cnt, i, j;
GLenum test;
vertex1 = contour->vertices;
vertex2 = polygon->vertices;
vertex1_cnt = contour->vertex_cnt;
vertex2_cnt = polygon->vertex_cnt;
for (i = 0; i < vertex1_cnt; vertex1 = vertex1->next, i++) {
for (j = 0; j < vertex2_cnt; vertex2 = vertex2->next, j++)
if ((test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next)) != GLU_NO_ERROR)
return test;
}
return GLU_NO_ERROR;
}
static void
add_new_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
{
contour->type = GLU_EXTERIOR;
contour->next = NULL;
contour->previous = tobj->last_contour;
tobj->last_contour->next = contour;
tobj->last_contour = contour;
}
static void
add_new_interior(GLUtriangulatorObj * tobj,
tess_contour * outer, tess_contour * contour)
{
contour->type = GLU_INTERIOR;
contour->next = outer->next;
contour->previous = outer;
if (outer->next != NULL)
outer->next->previous = contour;
outer->next = contour;
if (tobj->last_contour == outer)
tobj->last_contour = contour;
}
static void
add_interior_with_hierarchy_check(GLUtriangulatorObj * tobj,
tess_contour * outer,
tess_contour * contour)
{
tess_contour *ptr;
/* for all interiors of outer check if they are interior of contour */
/* if so, change that interior to exterior and move it of of the */
/* interior sequence */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
GLenum test;
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
ptr = ptr->next) {
test = is_contour_contained_in(ptr, contour);
switch (test) {
case GLU_INTERIOR:
/* contour is contained in one of the interiors */
/* check if possibly contained in other exteriors */
/* move ptr to first EXTERIOR */
for (; ptr != NULL && ptr->type == GLU_INTERIOR; ptr = ptr->next);
if (ptr == NULL)
/* another exterior */
add_new_exterior(tobj, contour);
else
add_exterior_with_check(tobj, ptr, contour);
return;
case GLU_EXTERIOR:
/* one of the interiors is contained in the contour */
/* change it to EXTERIOR, and shift it away from the */
/* interior sequence */
shift_interior_to_exterior(tobj, ptr);
break;
case GLU_NO_ERROR:
/* disjoint */
break;
default:
abort();
}
}
}
/* add contour to the interior sequence */
add_new_interior(tobj, outer, contour);
}
static void
reverse_hierarchy_and_add_exterior(GLUtriangulatorObj * tobj,
tess_contour * outer,
tess_contour * contour)
{
tess_contour *ptr;
/* reverse INTERIORS to EXTERIORS */
/* any INTERIORS? */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR)
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
ptr = ptr->next) ptr->type = GLU_EXTERIOR;
/* the outer now becomes inner */
outer->type = GLU_INTERIOR;
/* contour is the EXTERIOR */
contour->next = outer;
if (tobj->contours == outer) {
/* first contour beeing reversed */
contour->previous = NULL;
tobj->contours = contour;
}
else {
outer->previous->next = contour;
contour->previous = outer->previous;
}
outer->previous = contour;
}
static void
shift_interior_to_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
{
contour->previous->next = contour->next;
if (contour->next != NULL)
contour->next->previous = contour->previous;
else
tobj->last_contour = contour->previous;
}
static void
add_exterior_with_check(GLUtriangulatorObj * tobj,
tess_contour * outer, tess_contour * contour)
{
GLenum test;
/* this contour might be interior to further exteriors - check */
/* if not, just add as a new exterior */
for (; outer != NULL && outer->type == GLU_EXTERIOR; outer = outer->next) {
test = is_contour_contained_in(outer, contour);
switch (test) {
case GLU_INTERIOR:
/* now we have to check if contour is inside interiors */
/* or not */
/* any interiors? */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
/* for all interior, check if inside any of them */
/* if not inside any of interiors, its another */
/* interior */
/* or it may contain some interiors, then change */
/* the contained interiors to exterior ones */
add_interior_with_hierarchy_check(tobj, outer, contour);
}
else {
/* not in interior, add as new interior contour */
add_new_interior(tobj, outer, contour);
}
return;
case GLU_NO_ERROR:
/* disjoint */
break;
default:
abort();
}
}
/* add contour to the exterior sequence */
add_new_exterior(tobj, contour);
}
void
tess_handle_holes(GLUtriangulatorObj * tobj)
{
tess_contour *contour, *hole;
GLenum exterior_orientation;
/* verify hole orientation */
for (contour = tobj->contours; contour != NULL;) {
exterior_orientation = contour->orientation;
for (contour = contour->next;
contour != NULL && contour->type == GLU_INTERIOR;
contour = contour->next) {
if (contour->orientation == exterior_orientation) {
tess_call_user_error(tobj, GLU_TESS_ERROR5);
return;
}
}
}
/* now cut-out holes */
for (contour = tobj->contours; contour != NULL;) {
hole = contour->next;
while (hole != NULL && hole->type == GLU_INTERIOR) {
if (cut_out_hole(tobj, contour, hole) == GLU_ERROR)
return;
hole = contour->next;
}
contour = contour->next;
}
}
static GLenum
cut_out_hole(GLUtriangulatorObj * tobj,
tess_contour * contour, tess_contour * hole)
{
tess_contour *tmp_hole;
tess_vertex *v1, *v2, *tmp_vertex;
GLuint vertex1_cnt, vertex2_cnt, tmp_vertex_cnt;
GLuint i, j, k;
GLenum test = 0;
/* find an edge connecting contour and hole not intersecting any other */
/* edge belonging to either the contour or any of the other holes */
for (v1 = contour->vertices, vertex1_cnt = contour->vertex_cnt, i = 0;
i < vertex1_cnt; i++, v1 = v1->next) {
for (v2 = hole->vertices, vertex2_cnt = hole->vertex_cnt, j = 0;
j < vertex2_cnt; j++, v2 = v2->next) {
/* does edge (v1,v2) intersect any edge of contour */
for (tmp_vertex = contour->vertices, tmp_vertex_cnt =
contour->vertex_cnt, k = 0; k < tmp_vertex_cnt;
tmp_vertex = tmp_vertex->next, k++) {
/* skip edge tests for edges directly connected */
if (v1 == tmp_vertex || v1 == tmp_vertex->next)
continue;
test = edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test == GLU_NO_ERROR) {
/* does edge (v1,v2) intersect any edge of hole */
for (tmp_vertex = hole->vertices,
tmp_vertex_cnt = hole->vertex_cnt, k = 0;
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
/* skip edge tests for edges directly connected */
if (v2 == tmp_vertex || v2 == tmp_vertex->next)
continue;
test =
edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test == GLU_NO_ERROR) {
/* does edge (v1,v2) intersect any other hole? */
for (tmp_hole = hole->next;
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
tmp_hole = tmp_hole->next) {
/* does edge (v1,v2) intersect any edge of hole */
for (tmp_vertex = tmp_hole->vertices,
tmp_vertex_cnt = tmp_hole->vertex_cnt, k = 0;
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
test = edge_edge_intersect(v1, v2, tmp_vertex,
tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test != GLU_NO_ERROR)
break;
}
}
}
if (test == GLU_NO_ERROR) {
/* edge (v1,v2) is good for eliminating the hole */
if (merge_hole_with_contour(tobj, contour, hole, v1, v2)
== GLU_NO_ERROR)
return GLU_NO_ERROR;
else
return GLU_ERROR;
}
}
}
/* other holes are blocking all possible connections of hole */
/* with contour, we shift this hole as the last hole and retry */
for (tmp_hole = hole;
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
tmp_hole = tmp_hole->next);
contour->next = hole->next;
hole->next->previous = contour;
if (tmp_hole == NULL) {
/* last EXTERIOR contour, shift hole as last contour */
hole->next = NULL;
hole->previous = tobj->last_contour;
tobj->last_contour->next = hole;
tobj->last_contour = hole;
}
else {
tmp_hole->previous->next = hole;
hole->previous = tmp_hole->previous;
tmp_hole->previous = hole;
hole->next = tmp_hole;
}
hole = contour->next;
/* try once again - recurse */
return cut_out_hole(tobj, contour, hole);
}
static GLenum
merge_hole_with_contour(GLUtriangulatorObj * tobj,
tess_contour * contour,
tess_contour * hole,
tess_vertex * v1, tess_vertex * v2)
{
tess_vertex *v1_new, *v2_new;
/* make copies of v1 and v2, place them respectively after their originals */
if ((v1_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return GLU_ERROR;
}
if ((v2_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return GLU_ERROR;
}
v1_new->edge_flag = GL_TRUE;
v1_new->data = v1->data;
v1_new->location[0] = v1->location[0];
v1_new->location[1] = v1->location[1];
v1_new->location[2] = v1->location[2];
v1_new->x = v1->x;
v1_new->y = v1->y;
v1_new->shadow_vertex = v1;
v1->shadow_vertex = v1_new;
v1_new->next = v1->next;
v1_new->previous = v1;
v1->next->previous = v1_new;
v1->next = v1_new;
v2_new->edge_flag = GL_TRUE;
v2_new->data = v2->data;
v2_new->location[0] = v2->location[0];
v2_new->location[1] = v2->location[1];
v2_new->location[2] = v2->location[2];
v2_new->x = v2->x;
v2_new->y = v2->y;
v2_new->shadow_vertex = v2;
v2->shadow_vertex = v2_new;
v2_new->next = v2->next;
v2_new->previous = v2;
v2->next->previous = v2_new;
v2->next = v2_new;
/* link together the two lists */
v1->next = v2_new;
v2_new->previous = v1;
v2->next = v1_new;
v1_new->previous = v2;
/* update the vertex count of the contour */
contour->vertex_cnt += hole->vertex_cnt + 2;
/* remove the INTERIOR contour */
contour->next = hole->next;
if (hole->next != NULL)
hole->next->previous = contour;
free(hole);
/* update tobj structure */
--(tobj->contour_cnt);
if (contour->last_vertex == v1)
contour->last_vertex = v1_new;
/* mark two vertices with edge_flag */
v2->edge_flag = GL_FALSE;
v1->edge_flag = GL_FALSE;
return GLU_NO_ERROR;
}

View File

@@ -1,403 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "gluP.h"
#endif
/*
* This code was contributed by Marc Buffat (buffat@mecaflu.ec-lyon.fr).
* Thanks Marc!!!
*/
/* implementation de gluProject et gluUnproject */
/* M. Buffat 17/2/95 */
/*
* Transform a point (column vector) by a 4x4 matrix. I.e. out = m * in
* Input: m - the 4x4 matrix
* in - the 4x1 vector
* Output: out - the resulting 4x1 vector.
*/
static void
transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
{
#define M(row,col) m[col*4+row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
/*
* Perform a 4x4 matrix multiplication (product = a x b).
* Input: a, b - matrices to multiply
* Output: product - product of a and b
*/
static void
matmul(GLdouble * product, const GLdouble * a, const GLdouble * b)
{
/* This matmul was contributed by Thomas Malik */
GLdouble temp[16];
GLint i;
#define A(row,col) a[(col<<2)+row]
#define B(row,col) b[(col<<2)+row]
#define T(row,col) temp[(col<<2)+row]
/* i-te Zeile */
for (i = 0; i < 4; i++) {
T(i, 0) =
A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i,
3) *
B(3, 0);
T(i, 1) =
A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i,
3) *
B(3, 1);
T(i, 2) =
A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i,
3) *
B(3, 2);
T(i, 3) =
A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i,
3) *
B(3, 3);
}
#undef A
#undef B
#undef T
MEMCPY(product, temp, 16 * sizeof(GLdouble));
}
/*
* Compute inverse of 4x4 transformation matrix.
* Code contributed by Jacques Leroy jle@star.be
* Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
*/
static GLboolean
invert_matrix(const GLdouble * m, GLdouble * out)
{
/* NB. OpenGL Matrices are COLUMN major. */
#define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
#define MAT(m,r,c) (m)[(c)*4+(r)]
GLdouble wtmp[4][8];
GLdouble m0, m1, m2, m3, s;
GLdouble *r0, *r1, *r2, *r3;
r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1),
r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3),
r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1),
r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3),
r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1),
r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3),
r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1),
r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3),
r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
/* choose pivot - or die */
if (fabs(r3[0]) > fabs(r2[0]))
SWAP_ROWS(r3, r2);
if (fabs(r2[0]) > fabs(r1[0]))
SWAP_ROWS(r2, r1);
if (fabs(r1[0]) > fabs(r0[0]))
SWAP_ROWS(r1, r0);
if (0.0 == r0[0])
return GL_FALSE;
/* eliminate first variable */
m1 = r1[0] / r0[0];
m2 = r2[0] / r0[0];
m3 = r3[0] / r0[0];
s = r0[1];
r1[1] -= m1 * s;
r2[1] -= m2 * s;
r3[1] -= m3 * s;
s = r0[2];
r1[2] -= m1 * s;
r2[2] -= m2 * s;
r3[2] -= m3 * s;
s = r0[3];
r1[3] -= m1 * s;
r2[3] -= m2 * s;
r3[3] -= m3 * s;
s = r0[4];
if (s != 0.0) {
r1[4] -= m1 * s;
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r0[5];
if (s != 0.0) {
r1[5] -= m1 * s;
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r0[6];
if (s != 0.0) {
r1[6] -= m1 * s;
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r0[7];
if (s != 0.0) {
r1[7] -= m1 * s;
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* choose pivot - or die */
if (fabs(r3[1]) > fabs(r2[1]))
SWAP_ROWS(r3, r2);
if (fabs(r2[1]) > fabs(r1[1]))
SWAP_ROWS(r2, r1);
if (0.0 == r1[1])
return GL_FALSE;
/* eliminate second variable */
m2 = r2[1] / r1[1];
m3 = r3[1] / r1[1];
r2[2] -= m2 * r1[2];
r3[2] -= m3 * r1[2];
r2[3] -= m2 * r1[3];
r3[3] -= m3 * r1[3];
s = r1[4];
if (0.0 != s) {
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r1[5];
if (0.0 != s) {
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r1[6];
if (0.0 != s) {
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r1[7];
if (0.0 != s) {
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* choose pivot - or die */
if (fabs(r3[2]) > fabs(r2[2]))
SWAP_ROWS(r3, r2);
if (0.0 == r2[2])
return GL_FALSE;
/* eliminate third variable */
m3 = r3[2] / r2[2];
r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7];
/* last check */
if (0.0 == r3[3])
return GL_FALSE;
s = 1.0 / r3[3]; /* now back substitute row 3 */
r3[4] *= s;
r3[5] *= s;
r3[6] *= s;
r3[7] *= s;
m2 = r2[3]; /* now back substitute row 2 */
s = 1.0 / r2[2];
r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
m1 = r1[3];
r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
m0 = r0[3];
r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
m1 = r1[2]; /* now back substitute row 1 */
s = 1.0 / r1[1];
r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
m0 = r0[2];
r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
m0 = r0[1]; /* now back substitute row 0 */
s = 1.0 / r0[0];
r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
MAT(out, 0, 0) = r0[4];
MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6];
MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4];
MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6];
MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4];
MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6];
MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4];
MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6];
MAT(out, 3, 3) = r3[7];
return GL_TRUE;
#undef MAT
#undef SWAP_ROWS
}
/* projection du point (objx,objy,obz) sur l'ecran (winx,winy,winz) */
GLint GLAPIENTRY
gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * winx, GLdouble * winy, GLdouble * winz)
{
/* matrice de transformation */
GLdouble in[4], out[4];
/* initilise la matrice et le vecteur a transformer */
in[0] = objx;
in[1] = objy;
in[2] = objz;
in[3] = 1.0;
transform_point(out, model, in);
transform_point(in, proj, out);
/* d'ou le resultat normalise entre -1 et 1 */
if (in[3] == 0.0)
return GL_FALSE;
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
/* en coordonnees ecran */
*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
/* entre 0 et 1 suivant z */
*winz = (1 + in[2]) / 2;
return GL_TRUE;
}
/* transformation du point ecran (winx,winy,winz) en point objet */
GLint GLAPIENTRY
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * objx, GLdouble * objy, GLdouble * objz)
{
/* matrice de transformation */
GLdouble m[16], A[16];
GLdouble in[4], out[4];
/* transformation coordonnees normalisees entre -1 et 1 */
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
in[2] = 2 * winz - 1.0;
in[3] = 1.0;
/* calcul transformation inverse */
matmul(A, proj, model);
if (!invert_matrix(A, m))
return GL_FALSE;
/* d'ou les coordonnees objets */
transform_point(out, m, in);
if (out[3] == 0.0)
return GL_FALSE;
*objx = out[0] / out[3];
*objy = out[1] / out[3];
*objz = out[2] / out[3];
return GL_TRUE;
}
/*
* New in GLU 1.3
* This is like gluUnProject but also takes near and far DepthRange values.
*/
#ifdef GLU_VERSION_1_3
GLint GLAPIENTRY
gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLclampd nearZ, GLclampd farZ,
GLdouble * objx, GLdouble * objy, GLdouble * objz,
GLdouble * objw)
{
/* matrice de transformation */
GLdouble m[16], A[16];
GLdouble in[4], out[4];
GLdouble z = nearZ + winz * (farZ - nearZ);
/* transformation coordonnees normalisees entre -1 et 1 */
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
in[2] = 2.0 * z - 1.0;
in[3] = clipw;
/* calcul transformation inverse */
matmul(A, projMatrix, modelMatrix);
if (!invert_matrix(A, m))
return GL_FALSE;
/* d'ou les coordonnees objets */
transform_point(out, m, in);
if (out[3] == 0.0)
return GL_FALSE;
*objx = out[0] / out[3];
*objy = out[1] / out[3];
*objz = out[2] / out[3];
*objw = out[3];
return GL_TRUE;
}
#endif

View File

@@ -1,773 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1999-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* TODO:
* texture coordinate support
* flip normals according to orientation
* there's still some inside/outside orientation bugs in possibly all
* but the sphere function
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#endif
#ifndef M_PI
# define M_PI (3.1415926)
#endif
/*
* Convert degrees to radians:
*/
#define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
/*
* Sin and Cos for degree angles:
*/
#define SIND( A ) sin( (A)*(M_PI/180.0) )
#define COSD( A) cos( (A)*(M_PI/180.0) )
/*
* Texture coordinates if texture flag is set
*/
#define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
struct GLUquadric
{
GLenum DrawStyle; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
GLenum Orientation; /* GLU_INSIDE or GLU_OUTSIDE */
GLboolean TextureFlag; /* Generate texture coords? */
GLenum Normals; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
void (GLCALLBACK * ErrorFunc) (GLenum err); /* Error handler callback function */
};
/*
* Process a GLU error.
*/
static void
quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg)
{
/* Call the error call back function if any */
if (qobj->ErrorFunc) {
(*qobj->ErrorFunc) (error);
}
/* Print a message to stdout if MESA_DEBUG variable is defined */
if (getenv("MESA_DEBUG")) {
fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error),
msg);
}
}
GLUquadricObj *GLAPIENTRY
gluNewQuadric(void)
{
GLUquadricObj *q;
q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric));
if (q) {
q->DrawStyle = GLU_FILL;
q->Orientation = GLU_OUTSIDE;
q->TextureFlag = GL_FALSE;
q->Normals = GLU_SMOOTH;
q->ErrorFunc = NULL;
}
return q;
}
void GLAPIENTRY
gluDeleteQuadric(GLUquadricObj * state)
{
if (state) {
free((void *) state);
}
}
/*
* Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
* or GLU_POINT.
*/
void GLAPIENTRY
gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle)
{
if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE
|| drawStyle == GLU_SILHOUETTE
|| drawStyle == GLU_POINT)) {
quadObject->DrawStyle = drawStyle;
}
else {
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle");
}
}
/*
* Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
*/
void GLAPIENTRY
gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation)
{
if (quadObject
&& (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) {
quadObject->Orientation = orientation;
}
else {
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation");
}
}
/*
* Set the error handler callback function.
*/
void GLAPIENTRY
gluQuadricCallback(GLUquadricObj * qobj,
GLenum which, void (GLCALLBACK * fn) ())
{
/*
* UGH, this is a mess! I thought ANSI was a standard.
*/
if (qobj && which == GLU_ERROR) {
#ifdef __CYGWIN32__
qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn;
#elif defined(OPENSTEP)
qobj->ErrorFunc = (void (*)(GLenum)) fn;
#elif defined(_WIN32)
qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn;
#elif defined(__STORM__)
qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn;
#elif defined(__BEOS__)
qobj->ErrorFunc = (void (*)(GLenum)) fn;
#else
qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn;
#endif
}
}
void GLAPIENTRY
gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals)
{
if (quadObject
&& (normals == GLU_NONE || normals == GLU_FLAT
|| normals == GLU_SMOOTH)) {
quadObject->Normals = normals;
}
}
void GLAPIENTRY
gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords)
{
if (quadObject) {
quadObject->TextureFlag = textureCoords;
}
}
/*
* Call glNormal3f after scaling normal to unit length.
*/
static void
normal3f(GLfloat x, GLfloat y, GLfloat z)
{
}
void GLAPIENTRY
gluCylinder(GLUquadricObj * qobj,
GLdouble baseRadius, GLdouble topRadius,
GLdouble height, GLint slices, GLint stacks)
{
GLdouble da, r, dr, dz;
GLfloat x, y, z, nz, nsign;
GLint i, j;
if (qobj->Orientation == GLU_INSIDE) {
nsign = -1.0;
}
else {
nsign = 1.0;
}
da = 2.0 * M_PI / slices;
dr = (topRadius - baseRadius) / stacks;
dz = height / stacks;
nz = (baseRadius - topRadius) / height; /* Z component of normal vectors */
if (qobj->DrawStyle == GLU_POINT) {
glBegin(GL_POINTS);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
z = 0.0;
r = baseRadius;
for (j = 0; j <= stacks; j++) {
glVertex3f(x * r, y * r, z);
z += dz;
r += dr;
}
}
glEnd();
}
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
/* Draw rings */
if (qobj->DrawStyle == GLU_LINE) {
z = 0.0;
r = baseRadius;
for (j = 0; j <= stacks; j++) {
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * r, y * r, z);
}
glEnd();
z += dz;
r += dr;
}
}
else {
/* draw one ring at each end */
if (baseRadius != 0.0) {
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
}
glEnd();
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * topRadius, y * topRadius, height);
}
glEnd();
}
}
/* draw length lines */
glBegin(GL_LINES);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
glVertex3f(x * topRadius, y * topRadius, height);
}
glEnd();
}
else if (qobj->DrawStyle == GLU_FILL) {
GLfloat ds = 1.0 / slices;
GLfloat dt = 1.0 / stacks;
GLfloat t = 0.0;
z = 0.0;
r = baseRadius;
for (j = 0; j < stacks; j++) {
GLfloat s = 0.0;
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
GLfloat x, y;
if (i == slices) {
x = sin(0.0);
y = cos(0.0);
}
else {
x = sin(i * da);
y = cos(i * da);
}
if (nsign == 1.0) {
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t);
glVertex3f(x * r, y * r, z);
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t + dt);
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
}
else {
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t);
glVertex3f(x * r, y * r, z);
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t + dt);
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
}
s += ds;
} /* for slices */
glEnd();
r += dr;
t += dt;
z += dz;
} /* for stacks */
}
}
void GLAPIENTRY
gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks)
{
GLfloat rho, drho, theta, dtheta;
GLfloat x, y, z;
GLfloat s, t, ds, dt;
GLint i, j, imin, imax;
GLboolean normals;
GLfloat nsign;
if (qobj->Normals == GLU_NONE) {
normals = GL_FALSE;
}
else {
normals = GL_TRUE;
}
if (qobj->Orientation == GLU_INSIDE) {
nsign = -1.0;
}
else {
nsign = 1.0;
}
drho = M_PI / (GLfloat) stacks;
dtheta = 2.0 * M_PI / (GLfloat) slices;
/* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
/* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
/* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
if (qobj->DrawStyle == GLU_FILL) {
if (!qobj->TextureFlag) {
/* draw +Z end as a triangle fan */
glBegin(GL_TRIANGLE_FAN);
/* glNormal3f(0.0, 0.0, 1.0); */
glVertex3f(0.0, 0.0, nsign * radius);
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(drho);
y = cos(theta) * sin(drho);
z = nsign * cos(drho);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
ds = 1.0 / slices;
dt = 1.0 / stacks;
t = 1.0; /* because loop now runs from 0 */
if (qobj->TextureFlag) {
imin = 0;
imax = stacks;
}
else {
imin = 1;
imax = stacks - 1;
}
/* draw intermediate stacks as quad strips */
for (i = imin; i < imax; i++) {
rho = i * drho;
glBegin(GL_QUAD_STRIP);
s = 0.0;
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
TXTR_COORD(s, t);
glVertex3f(x * radius, y * radius, z * radius);
x = -sin(theta) * sin(rho + drho);
y = cos(theta) * sin(rho + drho);
z = nsign * cos(rho + drho);
TXTR_COORD(s, t - dt);
s += ds;
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
t -= dt;
}
if (!qobj->TextureFlag) {
/* draw -Z end as a triangle fan */
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0, 0.0, -radius * nsign);
rho = M_PI - drho;
s = 1.0;
t = dt;
for (j = slices; j >= 0; j--) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
s -= ds;
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
}
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
/* draw stack lines */
for (i = 1; i < stacks; i++) { /* stack line at i==stacks-1 was missing here */
rho = i * drho;
glBegin(GL_LINE_LOOP);
for (j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
/* draw slice lines */
for (j = 0; j < slices; j++) {
theta = j * dtheta;
glBegin(GL_LINE_STRIP);
for (i = 0; i <= stacks; i++) {
rho = i * drho;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
}
else if (qobj->DrawStyle == GLU_POINT) {
/* top and bottom-most points */
glBegin(GL_POINTS);
glVertex3f(0.0, 0.0, radius);
glVertex3f(0.0, 0.0, -radius);
/* loop over stacks */
for (i = 1; i < stacks - 1; i++) {
rho = i * drho;
for (j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
glVertex3f(x * radius, y * radius, z * radius);
}
}
glEnd();
}
}
void GLAPIENTRY
gluDisk(GLUquadricObj * qobj,
GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
{
GLfloat da, dr;
#if 0
GLdouble a, da;
GLfloat r, dr;
GLfloat x, y;
GLfloat r1, r2, dtc;
GLint s, l;
#endif
da = 2.0 * M_PI / slices;
dr = (outerRadius - innerRadius) / (GLfloat) loops;
switch (qobj->DrawStyle) {
case GLU_FILL:
{
/* texture of a gluDisk is a cut out of the texture unit square
* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
* (linear mapping)
*/
GLfloat dtc = 2.0f * outerRadius;
GLfloat sa, ca;
GLfloat r1 = innerRadius;
GLint l;
for (l = 0; l < loops; l++) {
GLfloat r2 = r1 + dr;
if (qobj->Orientation == GLU_OUTSIDE) {
GLint s;
glBegin(GL_QUAD_STRIP);
for (s = 0; s <= slices; s++) {
GLfloat a;
if (s == slices)
a = 0.0;
else
a = s * da;
sa = sin(a);
ca = cos(a);
TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc);
glVertex2f(r2 * sa, r2 * ca);
TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc);
glVertex2f(r1 * sa, r1 * ca);
}
glEnd();
}
else {
GLint s;
glBegin(GL_QUAD_STRIP);
for (s = slices; s >= 0; s--) {
GLfloat a;
if (s == slices)
a = 0.0;
else
a = s * da;
sa = sin(a);
ca = cos(a);
TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc);
glVertex2f(r2 * sa, r2 * ca);
TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc);
glVertex2f(r1 * sa, r1 * ca);
}
glEnd();
}
r1 = r2;
}
break;
}
case GLU_LINE:
{
GLint l, s;
/* draw loops */
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius + l * dr;
glBegin(GL_LINE_LOOP);
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
glVertex2f(r * sin(a), r * cos(a));
}
glEnd();
}
/* draw spokes */
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
GLfloat x = sin(a);
GLfloat y = cos(a);
glBegin(GL_LINE_STRIP);
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius + l * dr;
glVertex2f(r * x, r * y);
}
glEnd();
}
break;
}
case GLU_POINT:
{
GLint s;
glBegin(GL_POINTS);
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
GLfloat x = sin(a);
GLfloat y = cos(a);
GLint l;
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius * l * dr;
glVertex2f(r * x, r * y);
}
}
glEnd();
break;
}
case GLU_SILHOUETTE:
{
if (innerRadius != 0.0) {
GLfloat a;
glBegin(GL_LINE_LOOP);
for (a = 0.0; a < 2.0 * M_PI; a += da) {
GLfloat x = innerRadius * sin(a);
GLfloat y = innerRadius * cos(a);
glVertex2f(x, y);
}
glEnd();
}
{
GLfloat a;
glBegin(GL_LINE_LOOP);
for (a = 0; a < 2.0 * M_PI; a += da) {
GLfloat x = outerRadius * sin(a);
GLfloat y = outerRadius * cos(a);
glVertex2f(x, y);
}
glEnd();
}
break;
}
default:
abort();
}
}
void GLAPIENTRY
gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius,
GLdouble outerRadius, GLint slices, GLint loops,
GLdouble startAngle, GLdouble sweepAngle)
{
if (qobj->DrawStyle == GLU_POINT) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / (loops - 1);
delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1));
glBegin(GL_POINTS);
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice < slices; slice++) {
glVertex2f(radius * sin(angle), radius * cos(angle));
angle += delta_angle;
}
radius += delta_radius;
}
glEnd();
}
else if (qobj->DrawStyle == GLU_LINE) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / loops;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
/* draw rings */
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
angle = DEG_TO_RAD(startAngle);
glBegin(GL_LINE_STRIP);
for (slice = 0; slice <= slices; slice++) {
glVertex2f(radius * sin(angle), radius * cos(angle));
angle += delta_angle;
}
glEnd();
radius += delta_radius;
}
/* draw spokes */
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
radius = innerRadius;
glBegin(GL_LINE_STRIP);
for (loop = 0; loop < loops; loop++) {
glVertex2f(radius * sin(angle), radius * cos(angle));
radius += delta_radius;
}
glEnd();
angle += delta_angle;
}
}
else if (qobj->DrawStyle == GLU_SILHOUETTE) {
GLint slice;
GLdouble angle, delta_angle;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
/* draw outer ring */
glBegin(GL_LINE_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
glVertex2f(outerRadius * sin(angle), outerRadius * cos(angle));
angle += delta_angle;
}
glEnd();
/* draw inner ring */
if (innerRadius > 0.0) {
glBegin(GL_LINE_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice < slices; slice++) {
glVertex2f(innerRadius * sin(angle), innerRadius * cos(angle));
angle += delta_angle;
}
glEnd();
}
/* draw spokes */
if (sweepAngle < 360.0) {
GLdouble stopAngle = startAngle + sweepAngle;
glBegin(GL_LINES);
glVertex2f(innerRadius * SIND(startAngle),
innerRadius * COSD(startAngle));
glVertex2f(outerRadius * SIND(startAngle),
outerRadius * COSD(startAngle));
glVertex2f(innerRadius * SIND(stopAngle),
innerRadius * COSD(stopAngle));
glVertex2f(outerRadius * SIND(stopAngle),
outerRadius * COSD(stopAngle));
glEnd();
}
}
else if (qobj->DrawStyle == GLU_FILL) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / loops;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
glBegin(GL_QUAD_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
if (qobj->Orientation == GLU_OUTSIDE) {
glVertex2f((radius + delta_radius) * sin(angle),
(radius + delta_radius) * cos(angle));
glVertex2f(radius * sin(angle), radius * cos(angle));
}
else {
glVertex2f(radius * sin(angle), radius * cos(angle));
glVertex2f((radius + delta_radius) * sin(angle),
(radius + delta_radius) * cos(angle));
}
angle += delta_angle;
}
glEnd();
radius += delta_radius;
}
}
}

View File

@@ -1,327 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "tess.h"
#endif
/*
* This is ugly, but seems the easiest way to do things to make the
* code work under YellowBox for Windows
*/
#if defined(OPENSTEP) && defined(CALLBACK)
#undef CALLBACK
#define CALLBACK
#endif
static void delete_contours(GLUtriangulatorObj *);
#ifdef __CYGWIN32__
#define _CALLBACK
#else
#define _CALLBACK GLCALLBACK
#endif
static void
init_callbacks(tess_callbacks * callbacks)
{
callbacks->begin = (void (_CALLBACK *) (GLenum)) 0;
callbacks->edgeFlag = (void (_CALLBACK *) (GLboolean)) 0;
callbacks->vertex = (void (_CALLBACK *) (void *)) 0;
callbacks->end = (void (_CALLBACK *) (void)) 0;
callbacks->error = (void (_CALLBACK *) (GLenum)) 0;
}
void
tess_call_user_error(GLUtriangulatorObj * tobj, GLenum gluerr)
{
if (tobj->error == GLU_NO_ERROR)
tobj->error = gluerr;
if (tobj->callbacks.error != NULL)
(tobj->callbacks.error) (gluerr);
}
GLUtriangulatorObj *GLAPIENTRY
gluNewTess(void)
{
GLUtriangulatorObj *tobj;
if ((tobj = (GLUtriangulatorObj *)
malloc(sizeof(struct GLUtesselator))) == NULL)
return NULL;
tobj->contours = tobj->last_contour = NULL;
init_callbacks(&tobj->callbacks);
tobj->error = GLU_NO_ERROR;
tobj->current_polygon = NULL;
tobj->contour_cnt = 0;
return tobj;
}
void GLAPIENTRY
gluTessCallback(GLUtriangulatorObj * tobj, GLenum which,
void (GLCALLBACK * fn) ())
{
switch (which) {
case GLU_BEGIN:
tobj->callbacks.begin = (void (_CALLBACK *) (GLenum)) fn;
break;
case GLU_EDGE_FLAG:
tobj->callbacks.edgeFlag = (void (_CALLBACK *) (GLboolean)) fn;
break;
case GLU_VERTEX:
tobj->callbacks.vertex = (void (_CALLBACK *) (void *)) fn;
break;
case GLU_END:
tobj->callbacks.end = (void (_CALLBACK *) (void)) fn;
break;
case GLU_ERROR:
tobj->callbacks.error = (void (_CALLBACK *) (GLenum)) fn;
break;
default:
tobj->error = GLU_INVALID_ENUM;
break;
}
}
void GLAPIENTRY
gluDeleteTess(GLUtriangulatorObj * tobj)
{
if (tobj->error == GLU_NO_ERROR && tobj->contour_cnt)
/* was gluEndPolygon called? */
tess_call_user_error(tobj, GLU_TESS_ERROR1);
/* delete all internal structures */
delete_contours(tobj);
free(tobj);
}
void GLAPIENTRY
gluBeginPolygon(GLUtriangulatorObj * tobj)
{
/*
if(tobj->error!=GLU_NO_ERROR)
return;
*/
tobj->error = GLU_NO_ERROR;
if (tobj->current_polygon != NULL) {
/* gluEndPolygon was not called */
tess_call_user_error(tobj, GLU_TESS_ERROR1);
/* delete all internal structures */
delete_contours(tobj);
}
else {
if ((tobj->current_polygon =
(tess_polygon *) malloc(sizeof(tess_polygon))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
tobj->current_polygon->vertex_cnt = 0;
tobj->current_polygon->vertices =
tobj->current_polygon->last_vertex = NULL;
}
}
void GLAPIENTRY
gluEndPolygon(GLUtriangulatorObj * tobj)
{
/*tess_contour *contour_ptr; */
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* check if gluBeginPolygon was called */
if (tobj->current_polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
tess_test_polygon(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* any real contours? */
if (tobj->contour_cnt == 0) {
/* delete all internal structures */
delete_contours(tobj);
return;
}
tess_find_contour_hierarchies(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
tess_handle_holes(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* if no callbacks, nothing to do */
if (tobj->callbacks.begin != NULL && tobj->callbacks.vertex != NULL &&
tobj->callbacks.end != NULL) {
if (tobj->callbacks.edgeFlag == NULL)
tess_tesselate(tobj);
else
tess_tesselate_with_edge_flag(tobj);
}
end:
/* delete all internal structures */
delete_contours(tobj);
}
void GLAPIENTRY
gluNextContour(GLUtriangulatorObj * tobj, GLenum type)
{
if (tobj->error != GLU_NO_ERROR)
return;
if (tobj->current_polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
/* first contour? */
if (tobj->current_polygon->vertex_cnt)
tess_test_polygon(tobj);
}
void GLAPIENTRY
gluTessVertex(GLUtriangulatorObj * tobj, GLdouble v[3], void *data)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *last_vertex_ptr;
if (tobj->error != GLU_NO_ERROR)
return;
if (polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
last_vertex_ptr = polygon->last_vertex;
if (last_vertex_ptr == NULL) {
if ((last_vertex_ptr = (tess_vertex *)
malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
polygon->vertices = last_vertex_ptr;
polygon->last_vertex = last_vertex_ptr;
last_vertex_ptr->data = data;
last_vertex_ptr->location[0] = v[0];
last_vertex_ptr->location[1] = v[1];
last_vertex_ptr->location[2] = v[2];
last_vertex_ptr->next = NULL;
last_vertex_ptr->previous = NULL;
++(polygon->vertex_cnt);
}
else {
tess_vertex *vertex_ptr;
/* same point twice? */
if (fabs(last_vertex_ptr->location[0] - v[0]) < EPSILON &&
fabs(last_vertex_ptr->location[1] - v[1]) < EPSILON &&
fabs(last_vertex_ptr->location[2] - v[2]) < EPSILON) {
tess_call_user_error(tobj, GLU_TESS_ERROR6);
return;
}
if ((vertex_ptr = (tess_vertex *)
malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
vertex_ptr->data = data;
vertex_ptr->location[0] = v[0];
vertex_ptr->location[1] = v[1];
vertex_ptr->location[2] = v[2];
vertex_ptr->next = NULL;
vertex_ptr->previous = last_vertex_ptr;
++(polygon->vertex_cnt);
last_vertex_ptr->next = vertex_ptr;
polygon->last_vertex = vertex_ptr;
}
}
static void
delete_contours(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_contour *contour, *contour_tmp;
tess_vertex *vertex, *vertex_tmp;
/* remove current_polygon list - if exists due to detected error */
if (polygon != NULL) {
if (polygon->vertices) {
for (vertex = polygon->vertices; vertex != polygon->last_vertex;) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
free(vertex);
}
free(polygon);
tobj->current_polygon = NULL;
}
/* remove all contour data */
for (contour = tobj->contours; contour != NULL;) {
for (vertex = contour->vertices; vertex != contour->last_vertex;) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
free(vertex);
contour_tmp = contour->next;
free(contour);
contour = contour_tmp;
}
tobj->contours = tobj->last_contour = NULL;
tobj->contour_cnt = 0;
}
void GLAPIENTRY
gluTessNormal(GLUtesselator *tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ)
{
/* dummy function */
(void) tess;
(void) valueX;
(void) valueY;
(void) valueZ;
}

View File

@@ -1,107 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifndef TESS_H
#define TESS_H
#include "gluP.h"
#define EPSILON 1e-06 /* epsilon for double precision compares */
typedef enum
{
OXY,
OYZ,
OXZ
}
projection_type;
typedef struct callbacks_str
{
void (GLCALLBACK * begin) (GLenum mode);
void (GLCALLBACK * edgeFlag) (GLboolean flag);
void (GLCALLBACK * vertex) (GLvoid * v);
void (GLCALLBACK * end) (void);
void (GLCALLBACK * error) (GLenum err);
}
tess_callbacks;
typedef struct vertex_str
{
void *data;
GLdouble location[3];
GLdouble x, y;
GLboolean edge_flag;
struct vertex_str *shadow_vertex;
struct vertex_str *next, *previous;
}
tess_vertex;
typedef struct contour_str
{
GLenum type;
GLuint vertex_cnt;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices, *last_vertex;
struct contour_str *next, *previous;
}
tess_contour;
typedef struct polygon_str
{
GLuint vertex_cnt;
GLdouble A, B, C, D;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices, *last_vertex;
}
tess_polygon;
struct GLUtesselator
{
tess_contour *contours, *last_contour;
GLuint contour_cnt;
tess_callbacks callbacks;
tess_polygon *current_polygon;
GLenum error;
GLdouble A, B, C, D;
projection_type projection;
};
extern void tess_call_user_error(GLUtriangulatorObj *, GLenum);
extern void tess_test_polygon(GLUtriangulatorObj *);
extern void tess_find_contour_hierarchies(GLUtriangulatorObj *);
extern void tess_handle_holes(GLUtriangulatorObj *);
extern void tess_tesselate(GLUtriangulatorObj *);
extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *);
#endif

Some files were not shown because too many files have changed in this diff Show More